* gcc.dg/compat/struct-layout-1_generate.c (dg_options): New. Moved
[official-gcc.git] / gcc / fortran / trans-io.c
blobaf46ea2d65a0df1d85e39bd331c0c940f790d2ac
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 gfc_st_parameter_field GTY(())
69 const char *name;
70 unsigned int mask;
71 enum ioparam_type param_type;
72 enum iofield_type type;
73 tree field;
74 tree field_len;
76 gfc_st_parameter_field;
78 typedef struct gfc_st_parameter GTY(())
80 const char *name;
81 tree type;
83 gfc_st_parameter;
85 enum iofield
87 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
88 #include "ioparm.def"
89 #undef IOPARM
90 IOPARM_field_num
93 static GTY(()) gfc_st_parameter st_parameter[] =
95 { "common", NULL },
96 { "open", NULL },
97 { "close", NULL },
98 { "filepos", NULL },
99 { "inquire", NULL },
100 { "dt", NULL },
101 { "wait", NULL }
104 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
106 #define IOPARM(param_type, name, mask, type) \
107 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
108 #include "ioparm.def"
109 #undef IOPARM
110 { NULL, 0, 0, 0, NULL, NULL }
113 /* Library I/O subroutines */
115 enum iocall
117 IOCALL_READ,
118 IOCALL_READ_DONE,
119 IOCALL_WRITE,
120 IOCALL_WRITE_DONE,
121 IOCALL_X_INTEGER,
122 IOCALL_X_LOGICAL,
123 IOCALL_X_CHARACTER,
124 IOCALL_X_CHARACTER_WIDE,
125 IOCALL_X_REAL,
126 IOCALL_X_COMPLEX,
127 IOCALL_X_ARRAY,
128 IOCALL_OPEN,
129 IOCALL_CLOSE,
130 IOCALL_INQUIRE,
131 IOCALL_IOLENGTH,
132 IOCALL_IOLENGTH_DONE,
133 IOCALL_REWIND,
134 IOCALL_BACKSPACE,
135 IOCALL_ENDFILE,
136 IOCALL_FLUSH,
137 IOCALL_SET_NML_VAL,
138 IOCALL_SET_NML_VAL_DIM,
139 IOCALL_WAIT,
140 IOCALL_NUM
143 static GTY(()) tree iocall[IOCALL_NUM];
145 /* Variable for keeping track of what the last data transfer statement
146 was. Used for deciding which subroutine to call when the data
147 transfer is complete. */
148 static enum { READ, WRITE, IOLENGTH } last_dt;
150 /* The data transfer parameter block that should be shared by all
151 data transfer calls belonging to the same read/write/iolength. */
152 static GTY(()) tree dt_parm;
153 static stmtblock_t *dt_post_end_block;
155 static void
156 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
158 enum iofield type;
159 gfc_st_parameter_field *p;
160 char name[64];
161 size_t len;
162 tree t = make_node (RECORD_TYPE);
164 len = strlen (st_parameter[ptype].name);
165 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
166 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
167 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
168 len + 1);
169 TYPE_NAME (t) = get_identifier (name);
171 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
172 if (p->param_type == ptype)
173 switch (p->type)
175 case IOPARM_type_int4:
176 case IOPARM_type_intio:
177 case IOPARM_type_pint4:
178 case IOPARM_type_pintio:
179 case IOPARM_type_parray:
180 case IOPARM_type_pchar:
181 case IOPARM_type_pad:
182 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
183 get_identifier (p->name),
184 types[p->type]);
185 break;
186 case IOPARM_type_char1:
187 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
188 get_identifier (p->name),
189 pchar_type_node);
190 /* FALLTHROUGH */
191 case IOPARM_type_char2:
192 len = strlen (p->name);
193 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
194 memcpy (name, p->name, len);
195 memcpy (name + len, "_len", sizeof ("_len"));
196 p->field_len = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
197 get_identifier (name),
198 gfc_charlen_type_node);
199 if (p->type == IOPARM_type_char2)
200 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
201 get_identifier (p->name),
202 pchar_type_node);
203 break;
204 case IOPARM_type_common:
205 p->field
206 = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
207 get_identifier (p->name),
208 st_parameter[IOPARM_ptype_common].type);
209 break;
210 case IOPARM_type_num:
211 gcc_unreachable ();
214 gfc_finish_type (t);
215 st_parameter[ptype].type = t;
219 /* Build code to test an error condition and call generate_error if needed.
220 Note: This builds calls to generate_error in the runtime library function.
221 The function generate_error is dependent on certain parameters in the
222 st_parameter_common flags to be set. (See libgfortran/runtime/error.c)
223 Therefore, the code to set these flags must be generated before
224 this function is used. */
226 void
227 gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
228 const char * msgid, stmtblock_t * pblock)
230 stmtblock_t block;
231 tree body;
232 tree tmp;
233 tree arg1, arg2, arg3;
234 char *message;
236 if (integer_zerop (cond))
237 return;
239 /* The code to generate the error. */
240 gfc_start_block (&block);
242 arg1 = build_fold_addr_expr (var);
244 arg2 = build_int_cst (integer_type_node, error_code),
246 asprintf (&message, "%s", _(msgid));
247 arg3 = gfc_build_addr_expr (pchar_type_node,
248 gfc_build_localized_cstring_const (message));
249 gfc_free(message);
251 tmp = build_call_expr (gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
253 gfc_add_expr_to_block (&block, tmp);
255 body = gfc_finish_block (&block);
257 if (integer_onep (cond))
259 gfc_add_expr_to_block (pblock, body);
261 else
263 /* Tell the compiler that this isn't likely. */
264 cond = fold_convert (long_integer_type_node, cond);
265 tmp = build_int_cst (long_integer_type_node, 0);
266 cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
267 cond = fold_convert (boolean_type_node, cond);
269 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
270 gfc_add_expr_to_block (pblock, tmp);
275 /* Create function decls for IO library functions. */
277 void
278 gfc_build_io_library_fndecls (void)
280 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
281 tree gfc_intio_type_node;
282 tree parm_type, dt_parm_type;
283 HOST_WIDE_INT pad_size;
284 enum ioparam_type ptype;
286 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
287 types[IOPARM_type_intio] = gfc_intio_type_node
288 = gfc_get_int_type (gfc_intio_kind);
289 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
290 types[IOPARM_type_pintio]
291 = build_pointer_type (gfc_intio_type_node);
292 types[IOPARM_type_parray] = pchar_type_node;
293 types[IOPARM_type_pchar] = pchar_type_node;
294 pad_size = 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
295 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
296 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size));
297 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
299 /* pad actually contains pointers and integers so it needs to have an
300 alignment that is at least as large as the needed alignment for those
301 types. See the st_parameter_dt structure in libgfortran/io/io.h for
302 what really goes into this space. */
303 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
304 TYPE_ALIGN (gfc_get_int_type (gfc_max_integer_kind)));
306 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
307 gfc_build_st_parameter (ptype, types);
309 /* Define the transfer functions. */
311 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
313 iocall[IOCALL_X_INTEGER] =
314 gfc_build_library_function_decl (get_identifier
315 (PREFIX("transfer_integer")),
316 void_type_node, 3, dt_parm_type,
317 pvoid_type_node, gfc_int4_type_node);
319 iocall[IOCALL_X_LOGICAL] =
320 gfc_build_library_function_decl (get_identifier
321 (PREFIX("transfer_logical")),
322 void_type_node, 3, dt_parm_type,
323 pvoid_type_node, gfc_int4_type_node);
325 iocall[IOCALL_X_CHARACTER] =
326 gfc_build_library_function_decl (get_identifier
327 (PREFIX("transfer_character")),
328 void_type_node, 3, dt_parm_type,
329 pvoid_type_node, gfc_int4_type_node);
331 iocall[IOCALL_X_CHARACTER_WIDE] =
332 gfc_build_library_function_decl (get_identifier
333 (PREFIX("transfer_character_wide")),
334 void_type_node, 4, dt_parm_type,
335 pvoid_type_node, gfc_charlen_type_node,
336 gfc_int4_type_node);
338 iocall[IOCALL_X_REAL] =
339 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
340 void_type_node, 3, dt_parm_type,
341 pvoid_type_node, gfc_int4_type_node);
343 iocall[IOCALL_X_COMPLEX] =
344 gfc_build_library_function_decl (get_identifier
345 (PREFIX("transfer_complex")),
346 void_type_node, 3, dt_parm_type,
347 pvoid_type_node, gfc_int4_type_node);
349 iocall[IOCALL_X_ARRAY] =
350 gfc_build_library_function_decl (get_identifier
351 (PREFIX("transfer_array")),
352 void_type_node, 4, dt_parm_type,
353 pvoid_type_node, integer_type_node,
354 gfc_charlen_type_node);
356 /* Library entry points */
358 iocall[IOCALL_READ] =
359 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
360 void_type_node, 1, dt_parm_type);
362 iocall[IOCALL_WRITE] =
363 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
364 void_type_node, 1, dt_parm_type);
366 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
367 iocall[IOCALL_OPEN] =
368 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
369 void_type_node, 1, parm_type);
372 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
373 iocall[IOCALL_CLOSE] =
374 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
375 void_type_node, 1, parm_type);
377 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
378 iocall[IOCALL_INQUIRE] =
379 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
380 gfc_int4_type_node, 1, parm_type);
382 iocall[IOCALL_IOLENGTH] =
383 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
384 void_type_node, 1, dt_parm_type);
386 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_wait].type);
387 iocall[IOCALL_WAIT] =
388 gfc_build_library_function_decl (get_identifier (PREFIX("st_wait")),
389 gfc_int4_type_node, 1, parm_type);
391 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
392 iocall[IOCALL_REWIND] =
393 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
394 gfc_int4_type_node, 1, parm_type);
396 iocall[IOCALL_BACKSPACE] =
397 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
398 gfc_int4_type_node, 1, parm_type);
400 iocall[IOCALL_ENDFILE] =
401 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
402 gfc_int4_type_node, 1, parm_type);
404 iocall[IOCALL_FLUSH] =
405 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
406 gfc_int4_type_node, 1, parm_type);
408 /* Library helpers */
410 iocall[IOCALL_READ_DONE] =
411 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
412 gfc_int4_type_node, 1, dt_parm_type);
414 iocall[IOCALL_WRITE_DONE] =
415 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
416 gfc_int4_type_node, 1, dt_parm_type);
418 iocall[IOCALL_IOLENGTH_DONE] =
419 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
420 gfc_int4_type_node, 1, dt_parm_type);
423 iocall[IOCALL_SET_NML_VAL] =
424 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
425 void_type_node, 6, dt_parm_type,
426 pvoid_type_node, pvoid_type_node,
427 gfc_int4_type_node, gfc_charlen_type_node,
428 gfc_int4_type_node);
430 iocall[IOCALL_SET_NML_VAL_DIM] =
431 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
432 void_type_node, 5, dt_parm_type,
433 gfc_int4_type_node, gfc_array_index_type,
434 gfc_array_index_type, gfc_array_index_type);
438 /* Generate code to store an integer constant into the
439 st_parameter_XXX structure. */
441 static unsigned int
442 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
443 unsigned int val)
445 tree tmp;
446 gfc_st_parameter_field *p = &st_parameter_field[type];
448 if (p->param_type == IOPARM_ptype_common)
449 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
450 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
451 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
452 NULL_TREE);
453 gfc_add_modify (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
454 return p->mask;
458 /* Generate code to store a non-string I/O parameter into the
459 st_parameter_XXX structure. This is a pass by value. */
461 static unsigned int
462 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
463 gfc_expr *e)
465 gfc_se se;
466 tree tmp;
467 gfc_st_parameter_field *p = &st_parameter_field[type];
468 tree dest_type = TREE_TYPE (p->field);
470 gfc_init_se (&se, NULL);
471 gfc_conv_expr_val (&se, e);
473 /* If we're storing a UNIT number, we need to check it first. */
474 if (type == IOPARM_common_unit && e->ts.kind != 4)
476 tree cond, max;
477 int i;
479 /* Don't evaluate the UNIT number multiple times. */
480 se.expr = gfc_evaluate_now (se.expr, &se.pre);
482 /* UNIT numbers should be nonnegative. */
483 cond = fold_build2 (LT_EXPR, boolean_type_node, se.expr,
484 build_int_cst (TREE_TYPE (se.expr),0));
485 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
486 "Negative unit number in I/O statement",
487 &se.pre);
489 /* UNIT numbers should be less than the max. */
490 i = gfc_validate_kind (BT_INTEGER, 4, false);
491 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
492 cond = fold_build2 (GT_EXPR, boolean_type_node, se.expr,
493 fold_convert (TREE_TYPE (se.expr), max));
494 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
495 "Unit number in I/O statement too large",
496 &se.pre);
500 se.expr = convert (dest_type, se.expr);
501 gfc_add_block_to_block (block, &se.pre);
503 if (p->param_type == IOPARM_ptype_common)
504 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
505 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
507 tmp = fold_build3 (COMPONENT_REF, dest_type, var, p->field, NULL_TREE);
508 gfc_add_modify (block, tmp, se.expr);
509 return p->mask;
513 /* Generate code to store a non-string I/O parameter into the
514 st_parameter_XXX structure. This is pass by reference. */
516 static unsigned int
517 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
518 tree var, enum iofield type, gfc_expr *e)
520 gfc_se se;
521 tree tmp, addr;
522 gfc_st_parameter_field *p = &st_parameter_field[type];
524 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
525 gfc_init_se (&se, NULL);
526 gfc_conv_expr_lhs (&se, e);
528 gfc_add_block_to_block (block, &se.pre);
530 if (TYPE_MODE (TREE_TYPE (se.expr))
531 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
533 addr = convert (TREE_TYPE (p->field), build_fold_addr_expr (se.expr));
535 /* If this is for the iostat variable initialize the
536 user variable to LIBERROR_OK which is zero. */
537 if (type == IOPARM_common_iostat)
538 gfc_add_modify (block, se.expr,
539 build_int_cst (TREE_TYPE (se.expr), LIBERROR_OK));
541 else
543 /* The type used by the library has different size
544 from the type of the variable supplied by the user.
545 Need to use a temporary. */
546 tree tmpvar = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
547 st_parameter_field[type].name);
549 /* If this is for the iostat variable, initialize the
550 user variable to LIBERROR_OK which is zero. */
551 if (type == IOPARM_common_iostat)
552 gfc_add_modify (block, tmpvar,
553 build_int_cst (TREE_TYPE (tmpvar), LIBERROR_OK));
555 addr = build_fold_addr_expr (tmpvar);
556 /* After the I/O operation, we set the variable from the temporary. */
557 tmp = convert (TREE_TYPE (se.expr), tmpvar);
558 gfc_add_modify (postblock, se.expr, tmp);
561 if (p->param_type == IOPARM_ptype_common)
562 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
563 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
564 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
565 var, p->field, NULL_TREE);
566 gfc_add_modify (block, tmp, addr);
567 return p->mask;
570 /* Given an array expr, find its address and length to get a string. If the
571 array is full, the string's address is the address of array's first element
572 and the length is the size of the whole array. If it is an element, the
573 string's address is the element's address and the length is the rest size of
574 the array.
577 static void
578 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
580 tree tmp;
581 tree array;
582 tree type;
583 tree size;
584 int rank;
585 gfc_symbol *sym;
587 sym = e->symtree->n.sym;
588 rank = sym->as->rank - 1;
590 if (e->ref->u.ar.type == AR_FULL)
592 se->expr = gfc_get_symbol_decl (sym);
593 se->expr = gfc_conv_array_data (se->expr);
595 else
597 gfc_conv_expr (se, e);
600 array = sym->backend_decl;
601 type = TREE_TYPE (array);
603 if (GFC_ARRAY_TYPE_P (type))
604 size = GFC_TYPE_ARRAY_SIZE (type);
605 else
607 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
608 size = gfc_conv_array_stride (array, rank);
609 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
610 gfc_conv_array_ubound (array, rank),
611 gfc_conv_array_lbound (array, rank));
612 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
613 gfc_index_one_node);
614 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
617 gcc_assert (size);
619 /* If it is an element, we need the its address and size of the rest. */
620 if (e->ref->u.ar.type == AR_ELEMENT)
622 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
623 TREE_OPERAND (se->expr, 1));
624 se->expr = build_fold_addr_expr (se->expr);
627 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
628 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
629 fold_convert (gfc_array_index_type, tmp));
631 se->string_length = fold_convert (gfc_charlen_type_node, size);
635 /* Generate code to store a string and its length into the
636 st_parameter_XXX structure. */
638 static unsigned int
639 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
640 enum iofield type, gfc_expr * e)
642 gfc_se se;
643 tree tmp;
644 tree io;
645 tree len;
646 gfc_st_parameter_field *p = &st_parameter_field[type];
648 gfc_init_se (&se, NULL);
650 if (p->param_type == IOPARM_ptype_common)
651 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
652 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
653 io = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
654 var, p->field, NULL_TREE);
655 len = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field_len),
656 var, p->field_len, NULL_TREE);
658 /* Integer variable assigned a format label. */
659 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
661 char * msg;
662 tree cond;
664 gfc_conv_label_variable (&se, e);
665 tmp = GFC_DECL_STRING_LEN (se.expr);
666 cond = fold_build2 (LT_EXPR, boolean_type_node,
667 tmp, build_int_cst (TREE_TYPE (tmp), 0));
669 asprintf(&msg, "Label assigned to variable '%s' (%%ld) is not a format "
670 "label", e->symtree->name);
671 gfc_trans_runtime_check (true, false, cond, &se.pre, &e->where, msg,
672 fold_convert (long_integer_type_node, tmp));
673 gfc_free (msg);
675 gfc_add_modify (&se.pre, io,
676 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
677 gfc_add_modify (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
679 else
681 /* General character. */
682 if (e->ts.type == BT_CHARACTER && e->rank == 0)
683 gfc_conv_expr (&se, e);
684 /* Array assigned Hollerith constant or character array. */
685 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
686 gfc_convert_array_to_string (&se, e);
687 else
688 gcc_unreachable ();
690 gfc_conv_string_parameter (&se);
691 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
692 gfc_add_modify (&se.pre, len, se.string_length);
695 gfc_add_block_to_block (block, &se.pre);
696 gfc_add_block_to_block (postblock, &se.post);
697 return p->mask;
701 /* Generate code to store the character (array) and the character length
702 for an internal unit. */
704 static unsigned int
705 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
706 tree var, gfc_expr * e)
708 gfc_se se;
709 tree io;
710 tree len;
711 tree desc;
712 tree tmp;
713 gfc_st_parameter_field *p;
714 unsigned int mask;
716 gfc_init_se (&se, NULL);
718 p = &st_parameter_field[IOPARM_dt_internal_unit];
719 mask = p->mask;
720 io = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
721 var, p->field, NULL_TREE);
722 len = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field_len),
723 var, p->field_len, NULL_TREE);
724 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
725 desc = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
726 var, p->field, NULL_TREE);
728 gcc_assert (e->ts.type == BT_CHARACTER);
730 /* Character scalars. */
731 if (e->rank == 0)
733 gfc_conv_expr (&se, e);
734 gfc_conv_string_parameter (&se);
735 tmp = se.expr;
736 se.expr = build_int_cst (pchar_type_node, 0);
739 /* Character array. */
740 else if (e->rank > 0)
742 se.ss = gfc_walk_expr (e);
744 if (is_subref_array (e))
746 /* Use a temporary for components of arrays of derived types
747 or substring array references. */
748 gfc_conv_subref_array_arg (&se, e, 0,
749 last_dt == READ ? INTENT_IN : INTENT_OUT);
750 tmp = build_fold_indirect_ref (se.expr);
751 se.expr = gfc_build_addr_expr (pchar_type_node, tmp);
752 tmp = gfc_conv_descriptor_data_get (tmp);
754 else
756 /* Return the data pointer and rank from the descriptor. */
757 gfc_conv_expr_descriptor (&se, e, se.ss);
758 tmp = gfc_conv_descriptor_data_get (se.expr);
759 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
762 else
763 gcc_unreachable ();
765 /* The cast is needed for character substrings and the descriptor
766 data. */
767 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
768 gfc_add_modify (&se.pre, len,
769 fold_convert (TREE_TYPE (len), se.string_length));
770 gfc_add_modify (&se.pre, desc, se.expr);
772 gfc_add_block_to_block (block, &se.pre);
773 gfc_add_block_to_block (post_block, &se.post);
774 return mask;
777 /* Add a case to a IO-result switch. */
779 static void
780 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
782 tree tmp, value;
784 if (label == NULL)
785 return; /* No label, no case */
787 value = build_int_cst (NULL_TREE, label_value);
789 /* Make a backend label for this case. */
790 tmp = gfc_build_label_decl (NULL_TREE);
792 /* And the case itself. */
793 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
794 gfc_add_expr_to_block (body, tmp);
796 /* Jump to the label. */
797 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
798 gfc_add_expr_to_block (body, tmp);
802 /* Generate a switch statement that branches to the correct I/O
803 result label. The last statement of an I/O call stores the
804 result into a variable because there is often cleanup that
805 must be done before the switch, so a temporary would have to
806 be created anyway. */
808 static void
809 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
810 gfc_st_label * end_label, gfc_st_label * eor_label)
812 stmtblock_t body;
813 tree tmp, rc;
814 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
816 /* If no labels are specified, ignore the result instead
817 of building an empty switch. */
818 if (err_label == NULL
819 && end_label == NULL
820 && eor_label == NULL)
821 return;
823 /* Build a switch statement. */
824 gfc_start_block (&body);
826 /* The label values here must be the same as the values
827 in the library_return enum in the runtime library */
828 add_case (1, err_label, &body);
829 add_case (2, end_label, &body);
830 add_case (3, eor_label, &body);
832 tmp = gfc_finish_block (&body);
834 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
835 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
836 rc = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
837 var, p->field, NULL_TREE);
838 rc = fold_build2 (BIT_AND_EXPR, TREE_TYPE (rc),
839 rc, build_int_cst (TREE_TYPE (rc),
840 IOPARM_common_libreturn_mask));
842 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
844 gfc_add_expr_to_block (block, tmp);
848 /* Store the current file and line number to variables so that if a
849 library call goes awry, we can tell the user where the problem is. */
851 static void
852 set_error_locus (stmtblock_t * block, tree var, locus * where)
854 gfc_file *f;
855 tree str, locus_file;
856 int line;
857 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
859 locus_file = fold_build3 (COMPONENT_REF,
860 st_parameter[IOPARM_ptype_common].type,
861 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
862 locus_file = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
863 locus_file, p->field, NULL_TREE);
864 f = where->lb->file;
865 str = gfc_build_cstring_const (f->filename);
867 str = gfc_build_addr_expr (pchar_type_node, str);
868 gfc_add_modify (block, locus_file, str);
870 line = LOCATION_LINE (where->lb->location);
871 set_parameter_const (block, var, IOPARM_common_line, line);
875 /* Translate an OPEN statement. */
877 tree
878 gfc_trans_open (gfc_code * code)
880 stmtblock_t block, post_block;
881 gfc_open *p;
882 tree tmp, var;
883 unsigned int mask = 0;
885 gfc_start_block (&block);
886 gfc_init_block (&post_block);
888 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
890 set_error_locus (&block, var, &code->loc);
891 p = code->ext.open;
893 if (p->iomsg)
894 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
895 p->iomsg);
897 if (p->iostat)
898 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
899 p->iostat);
901 if (p->err)
902 mask |= IOPARM_common_err;
904 if (p->file)
905 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
907 if (p->status)
908 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
909 p->status);
911 if (p->access)
912 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
913 p->access);
915 if (p->form)
916 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
918 if (p->recl)
919 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
921 if (p->blank)
922 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
923 p->blank);
925 if (p->position)
926 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
927 p->position);
929 if (p->action)
930 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
931 p->action);
933 if (p->delim)
934 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
935 p->delim);
937 if (p->pad)
938 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
940 if (p->decimal)
941 mask |= set_string (&block, &post_block, var, IOPARM_open_decimal,
942 p->decimal);
944 if (p->encoding)
945 mask |= set_string (&block, &post_block, var, IOPARM_open_encoding,
946 p->encoding);
948 if (p->round)
949 mask |= set_string (&block, &post_block, var, IOPARM_open_round, p->round);
951 if (p->sign)
952 mask |= set_string (&block, &post_block, var, IOPARM_open_sign, p->sign);
954 if (p->asynchronous)
955 mask |= set_string (&block, &post_block, var, IOPARM_open_asynchronous,
956 p->asynchronous);
958 if (p->convert)
959 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
960 p->convert);
962 set_parameter_const (&block, var, IOPARM_common_flags, mask);
964 if (p->unit)
965 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
966 else
967 set_parameter_const (&block, var, IOPARM_common_unit, 0);
969 tmp = build_fold_addr_expr (var);
970 tmp = build_call_expr (iocall[IOCALL_OPEN], 1, tmp);
971 gfc_add_expr_to_block (&block, tmp);
973 gfc_add_block_to_block (&block, &post_block);
975 io_result (&block, var, p->err, NULL, NULL);
977 return gfc_finish_block (&block);
981 /* Translate a CLOSE statement. */
983 tree
984 gfc_trans_close (gfc_code * code)
986 stmtblock_t block, post_block;
987 gfc_close *p;
988 tree tmp, var;
989 unsigned int mask = 0;
991 gfc_start_block (&block);
992 gfc_init_block (&post_block);
994 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
996 set_error_locus (&block, var, &code->loc);
997 p = code->ext.close;
999 if (p->iomsg)
1000 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1001 p->iomsg);
1003 if (p->iostat)
1004 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1005 p->iostat);
1007 if (p->err)
1008 mask |= IOPARM_common_err;
1010 if (p->status)
1011 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
1012 p->status);
1014 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1016 if (p->unit)
1017 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1018 else
1019 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1021 tmp = build_fold_addr_expr (var);
1022 tmp = build_call_expr (iocall[IOCALL_CLOSE], 1, tmp);
1023 gfc_add_expr_to_block (&block, tmp);
1025 gfc_add_block_to_block (&block, &post_block);
1027 io_result (&block, var, p->err, NULL, NULL);
1029 return gfc_finish_block (&block);
1033 /* Common subroutine for building a file positioning statement. */
1035 static tree
1036 build_filepos (tree function, gfc_code * code)
1038 stmtblock_t block, post_block;
1039 gfc_filepos *p;
1040 tree tmp, var;
1041 unsigned int mask = 0;
1043 p = code->ext.filepos;
1045 gfc_start_block (&block);
1046 gfc_init_block (&post_block);
1048 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
1049 "filepos_parm");
1051 set_error_locus (&block, var, &code->loc);
1053 if (p->iomsg)
1054 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1055 p->iomsg);
1057 if (p->iostat)
1058 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1059 p->iostat);
1061 if (p->err)
1062 mask |= IOPARM_common_err;
1064 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1066 if (p->unit)
1067 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1068 else
1069 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1071 tmp = build_fold_addr_expr (var);
1072 tmp = build_call_expr (function, 1, tmp);
1073 gfc_add_expr_to_block (&block, tmp);
1075 gfc_add_block_to_block (&block, &post_block);
1077 io_result (&block, var, p->err, NULL, NULL);
1079 return gfc_finish_block (&block);
1083 /* Translate a BACKSPACE statement. */
1085 tree
1086 gfc_trans_backspace (gfc_code * code)
1088 return build_filepos (iocall[IOCALL_BACKSPACE], code);
1092 /* Translate an ENDFILE statement. */
1094 tree
1095 gfc_trans_endfile (gfc_code * code)
1097 return build_filepos (iocall[IOCALL_ENDFILE], code);
1101 /* Translate a REWIND statement. */
1103 tree
1104 gfc_trans_rewind (gfc_code * code)
1106 return build_filepos (iocall[IOCALL_REWIND], code);
1110 /* Translate a FLUSH statement. */
1112 tree
1113 gfc_trans_flush (gfc_code * code)
1115 return build_filepos (iocall[IOCALL_FLUSH], code);
1119 /* Create a dummy iostat variable to catch any error due to bad unit. */
1121 static gfc_expr *
1122 create_dummy_iostat (void)
1124 gfc_symtree *st;
1125 gfc_expr *e;
1127 gfc_get_ha_sym_tree ("@iostat", &st);
1128 st->n.sym->ts.type = BT_INTEGER;
1129 st->n.sym->ts.kind = gfc_default_integer_kind;
1130 gfc_set_sym_referenced (st->n.sym);
1131 gfc_commit_symbol (st->n.sym);
1132 st->n.sym->backend_decl
1133 = gfc_create_var (gfc_get_int_type (st->n.sym->ts.kind),
1134 st->n.sym->name);
1136 e = gfc_get_expr ();
1137 e->expr_type = EXPR_VARIABLE;
1138 e->symtree = st;
1139 e->ts.type = BT_INTEGER;
1140 e->ts.kind = st->n.sym->ts.kind;
1142 return e;
1146 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
1148 tree
1149 gfc_trans_inquire (gfc_code * code)
1151 stmtblock_t block, post_block;
1152 gfc_inquire *p;
1153 tree tmp, var;
1154 unsigned int mask = 0, mask2 = 0;
1156 gfc_start_block (&block);
1157 gfc_init_block (&post_block);
1159 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1160 "inquire_parm");
1162 set_error_locus (&block, var, &code->loc);
1163 p = code->ext.inquire;
1165 if (p->iomsg)
1166 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1167 p->iomsg);
1169 if (p->iostat)
1170 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1171 p->iostat);
1173 if (p->err)
1174 mask |= IOPARM_common_err;
1176 /* Sanity check. */
1177 if (p->unit && p->file)
1178 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1180 if (p->file)
1181 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1182 p->file);
1184 if (p->exist)
1186 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1187 p->exist);
1189 if (p->unit && !p->iostat)
1191 p->iostat = create_dummy_iostat ();
1192 mask |= set_parameter_ref (&block, &post_block, var,
1193 IOPARM_common_iostat, p->iostat);
1197 if (p->opened)
1198 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1199 p->opened);
1201 if (p->number)
1202 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1203 p->number);
1205 if (p->named)
1206 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1207 p->named);
1209 if (p->name)
1210 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1211 p->name);
1213 if (p->access)
1214 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1215 p->access);
1217 if (p->sequential)
1218 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1219 p->sequential);
1221 if (p->direct)
1222 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1223 p->direct);
1225 if (p->form)
1226 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1227 p->form);
1229 if (p->formatted)
1230 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1231 p->formatted);
1233 if (p->unformatted)
1234 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1235 p->unformatted);
1237 if (p->recl)
1238 mask |= set_parameter_ref (&block, &post_block, var,
1239 IOPARM_inquire_recl_out, p->recl);
1241 if (p->nextrec)
1242 mask |= set_parameter_ref (&block, &post_block, var,
1243 IOPARM_inquire_nextrec, p->nextrec);
1245 if (p->blank)
1246 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1247 p->blank);
1249 if (p->delim)
1250 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1251 p->delim);
1253 if (p->position)
1254 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1255 p->position);
1257 if (p->action)
1258 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1259 p->action);
1261 if (p->read)
1262 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1263 p->read);
1265 if (p->write)
1266 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1267 p->write);
1269 if (p->readwrite)
1270 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1271 p->readwrite);
1273 if (p->pad)
1274 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1275 p->pad);
1277 if (p->convert)
1278 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1279 p->convert);
1281 if (p->strm_pos)
1282 mask |= set_parameter_ref (&block, &post_block, var,
1283 IOPARM_inquire_strm_pos_out, p->strm_pos);
1285 /* The second series of flags. */
1286 if (p->asynchronous)
1287 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_asynchronous,
1288 p->asynchronous);
1290 if (p->decimal)
1291 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_decimal,
1292 p->decimal);
1294 if (p->encoding)
1295 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_encoding,
1296 p->encoding);
1298 if (p->round)
1299 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_round,
1300 p->round);
1302 if (p->sign)
1303 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_sign,
1304 p->sign);
1306 if (p->pending)
1307 mask2 |= set_parameter_ref (&block, &post_block, var,
1308 IOPARM_inquire_pending, p->pending);
1310 if (p->size)
1311 mask2 |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_size,
1312 p->size);
1314 if (p->id)
1315 mask2 |= set_parameter_ref (&block, &post_block,var, IOPARM_inquire_id,
1316 p->id);
1318 set_parameter_const (&block, var, IOPARM_inquire_flags2, mask2);
1320 if (mask2)
1321 mask |= IOPARM_inquire_flags2;
1323 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1325 if (p->unit)
1326 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1327 else
1328 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1330 tmp = build_fold_addr_expr (var);
1331 tmp = build_call_expr (iocall[IOCALL_INQUIRE], 1, tmp);
1332 gfc_add_expr_to_block (&block, tmp);
1334 gfc_add_block_to_block (&block, &post_block);
1336 io_result (&block, var, p->err, NULL, NULL);
1338 return gfc_finish_block (&block);
1342 tree
1343 gfc_trans_wait (gfc_code * code)
1345 stmtblock_t block, post_block;
1346 gfc_wait *p;
1347 tree tmp, var;
1348 unsigned int mask = 0;
1350 gfc_start_block (&block);
1351 gfc_init_block (&post_block);
1353 var = gfc_create_var (st_parameter[IOPARM_ptype_wait].type,
1354 "wait_parm");
1356 set_error_locus (&block, var, &code->loc);
1357 p = code->ext.wait;
1359 /* Set parameters here. */
1360 if (p->iomsg)
1361 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1362 p->iomsg);
1364 if (p->iostat)
1365 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1366 p->iostat);
1368 if (p->err)
1369 mask |= IOPARM_common_err;
1371 if (p->id)
1372 mask |= set_parameter_value (&block, var, IOPARM_wait_id, p->id);
1374 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1376 if (p->unit)
1377 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1379 tmp = build_fold_addr_expr (var);
1380 tmp = build_call_expr (iocall[IOCALL_WAIT], 1, tmp);
1381 gfc_add_expr_to_block (&block, tmp);
1383 gfc_add_block_to_block (&block, &post_block);
1385 io_result (&block, var, p->err, NULL, NULL);
1387 return gfc_finish_block (&block);
1391 static gfc_expr *
1392 gfc_new_nml_name_expr (const char * name)
1394 gfc_expr * nml_name;
1396 nml_name = gfc_get_expr();
1397 nml_name->ref = NULL;
1398 nml_name->expr_type = EXPR_CONSTANT;
1399 nml_name->ts.kind = gfc_default_character_kind;
1400 nml_name->ts.type = BT_CHARACTER;
1401 nml_name->value.character.length = strlen(name);
1402 nml_name->value.character.string = gfc_char_to_widechar (name);
1404 return nml_name;
1407 /* nml_full_name builds up the fully qualified name of a
1408 derived type component. */
1410 static char*
1411 nml_full_name (const char* var_name, const char* cmp_name)
1413 int full_name_length;
1414 char * full_name;
1416 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1417 full_name = (char*)gfc_getmem (full_name_length + 1);
1418 strcpy (full_name, var_name);
1419 full_name = strcat (full_name, "%");
1420 full_name = strcat (full_name, cmp_name);
1421 return full_name;
1424 /* nml_get_addr_expr builds an address expression from the
1425 gfc_symbol or gfc_component backend_decl's. An offset is
1426 provided so that the address of an element of an array of
1427 derived types is returned. This is used in the runtime to
1428 determine that span of the derived type. */
1430 static tree
1431 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1432 tree base_addr)
1434 tree decl = NULL_TREE;
1435 tree tmp;
1436 tree itmp;
1437 int array_flagged;
1438 int dummy_arg_flagged;
1440 if (sym)
1442 sym->attr.referenced = 1;
1443 decl = gfc_get_symbol_decl (sym);
1445 /* If this is the enclosing function declaration, use
1446 the fake result instead. */
1447 if (decl == current_function_decl)
1448 decl = gfc_get_fake_result_decl (sym, 0);
1449 else if (decl == DECL_CONTEXT (current_function_decl))
1450 decl = gfc_get_fake_result_decl (sym, 1);
1452 else
1453 decl = c->backend_decl;
1455 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1456 || TREE_CODE (decl) == VAR_DECL
1457 || TREE_CODE (decl) == PARM_DECL)
1458 || TREE_CODE (decl) == COMPONENT_REF));
1460 tmp = decl;
1462 /* Build indirect reference, if dummy argument. */
1464 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1466 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1468 /* If an array, set flag and use indirect ref. if built. */
1470 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1471 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1473 if (array_flagged)
1474 tmp = itmp;
1476 /* Treat the component of a derived type, using base_addr for
1477 the derived type. */
1479 if (TREE_CODE (decl) == FIELD_DECL)
1480 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
1481 base_addr, tmp, NULL_TREE);
1483 /* If we have a derived type component, a reference to the first
1484 element of the array is built. This is done so that base_addr,
1485 used in the build of the component reference, always points to
1486 a RECORD_TYPE. */
1488 if (array_flagged)
1489 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL);
1491 /* Now build the address expression. */
1493 tmp = build_fold_addr_expr (tmp);
1495 /* If scalar dummy, resolve indirect reference now. */
1497 if (dummy_arg_flagged && !array_flagged)
1498 tmp = build_fold_indirect_ref (tmp);
1500 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1502 return tmp;
1505 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1506 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1507 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1509 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1511 static void
1512 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1513 gfc_symbol * sym, gfc_component * c,
1514 tree base_addr)
1516 gfc_typespec * ts = NULL;
1517 gfc_array_spec * as = NULL;
1518 tree addr_expr = NULL;
1519 tree dt = NULL;
1520 tree string;
1521 tree tmp;
1522 tree dtype;
1523 tree dt_parm_addr;
1524 int n_dim;
1525 int itype;
1526 int rank = 0;
1528 gcc_assert (sym || c);
1530 /* Build the namelist object name. */
1532 string = gfc_build_cstring_const (var_name);
1533 string = gfc_build_addr_expr (pchar_type_node, string);
1535 /* Build ts, as and data address using symbol or component. */
1537 ts = (sym) ? &sym->ts : &c->ts;
1538 as = (sym) ? sym->as : c->as;
1540 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1542 if (as)
1543 rank = as->rank;
1545 if (rank)
1547 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1548 dtype = gfc_get_dtype (dt);
1550 else
1552 itype = GFC_DTYPE_UNKNOWN;
1554 switch (ts->type)
1557 case BT_INTEGER:
1558 itype = GFC_DTYPE_INTEGER;
1559 break;
1560 case BT_LOGICAL:
1561 itype = GFC_DTYPE_LOGICAL;
1562 break;
1563 case BT_REAL:
1564 itype = GFC_DTYPE_REAL;
1565 break;
1566 case BT_COMPLEX:
1567 itype = GFC_DTYPE_COMPLEX;
1568 break;
1569 case BT_DERIVED:
1570 itype = GFC_DTYPE_DERIVED;
1571 break;
1572 case BT_CHARACTER:
1573 itype = GFC_DTYPE_CHARACTER;
1574 break;
1575 default:
1576 gcc_unreachable ();
1579 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1582 /* Build up the arguments for the transfer call.
1583 The call for the scalar part transfers:
1584 (address, name, type, kind or string_length, dtype) */
1586 dt_parm_addr = build_fold_addr_expr (dt_parm);
1588 if (ts->type == BT_CHARACTER)
1589 tmp = ts->cl->backend_decl;
1590 else
1591 tmp = build_int_cst (gfc_charlen_type_node, 0);
1592 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL], 6,
1593 dt_parm_addr, addr_expr, string,
1594 IARG (ts->kind), tmp, dtype);
1595 gfc_add_expr_to_block (block, tmp);
1597 /* If the object is an array, transfer rank times:
1598 (null pointer, name, stride, lbound, ubound) */
1600 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1602 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], 5,
1603 dt_parm_addr,
1604 IARG (n_dim),
1605 GFC_TYPE_ARRAY_STRIDE (dt, n_dim),
1606 GFC_TYPE_ARRAY_LBOUND (dt, n_dim),
1607 GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1608 gfc_add_expr_to_block (block, tmp);
1611 if (ts->type == BT_DERIVED)
1613 gfc_component *cmp;
1615 /* Provide the RECORD_TYPE to build component references. */
1617 tree expr = build_fold_indirect_ref (addr_expr);
1619 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1621 char *full_name = nml_full_name (var_name, cmp->name);
1622 transfer_namelist_element (block,
1623 full_name,
1624 NULL, cmp, expr);
1625 gfc_free (full_name);
1630 #undef IARG
1632 /* Create a data transfer statement. Not all of the fields are valid
1633 for both reading and writing, but improper use has been filtered
1634 out by now. */
1636 static tree
1637 build_dt (tree function, gfc_code * code)
1639 stmtblock_t block, post_block, post_end_block, post_iu_block;
1640 gfc_dt *dt;
1641 tree tmp, var;
1642 gfc_expr *nmlname;
1643 gfc_namelist *nml;
1644 unsigned int mask = 0;
1646 gfc_start_block (&block);
1647 gfc_init_block (&post_block);
1648 gfc_init_block (&post_end_block);
1649 gfc_init_block (&post_iu_block);
1651 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1653 set_error_locus (&block, var, &code->loc);
1655 if (last_dt == IOLENGTH)
1657 gfc_inquire *inq;
1659 inq = code->ext.inquire;
1661 /* First check that preconditions are met. */
1662 gcc_assert (inq != NULL);
1663 gcc_assert (inq->iolength != NULL);
1665 /* Connect to the iolength variable. */
1666 mask |= set_parameter_ref (&block, &post_end_block, var,
1667 IOPARM_dt_iolength, inq->iolength);
1668 dt = NULL;
1670 else
1672 dt = code->ext.dt;
1673 gcc_assert (dt != NULL);
1676 if (dt && dt->io_unit)
1678 if (dt->io_unit->ts.type == BT_CHARACTER)
1680 mask |= set_internal_unit (&block, &post_iu_block,
1681 var, dt->io_unit);
1682 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1685 else
1686 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1688 if (dt)
1690 if (dt->iomsg)
1691 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1692 dt->iomsg);
1694 if (dt->iostat)
1695 mask |= set_parameter_ref (&block, &post_end_block, var,
1696 IOPARM_common_iostat, dt->iostat);
1698 if (dt->err)
1699 mask |= IOPARM_common_err;
1701 if (dt->eor)
1702 mask |= IOPARM_common_eor;
1704 if (dt->end)
1705 mask |= IOPARM_common_end;
1707 if (dt->id)
1708 mask |= set_parameter_ref (&block, &post_end_block, var,
1709 IOPARM_dt_id, dt->id);
1711 if (dt->pos)
1712 mask |= set_parameter_value (&block, var, IOPARM_dt_pos, dt->pos);
1714 if (dt->asynchronous)
1715 mask |= set_string (&block, &post_block, var, IOPARM_dt_asynchronous,
1716 dt->asynchronous);
1718 if (dt->blank)
1719 mask |= set_string (&block, &post_block, var, IOPARM_dt_blank,
1720 dt->blank);
1722 if (dt->decimal)
1723 mask |= set_string (&block, &post_block, var, IOPARM_dt_decimal,
1724 dt->decimal);
1726 if (dt->delim)
1727 mask |= set_string (&block, &post_block, var, IOPARM_dt_delim,
1728 dt->delim);
1730 if (dt->pad)
1731 mask |= set_string (&block, &post_block, var, IOPARM_dt_pad,
1732 dt->pad);
1734 if (dt->round)
1735 mask |= set_string (&block, &post_block, var, IOPARM_dt_round,
1736 dt->round);
1738 if (dt->sign)
1739 mask |= set_string (&block, &post_block, var, IOPARM_dt_sign,
1740 dt->sign);
1742 if (dt->rec)
1743 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1745 if (dt->advance)
1746 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1747 dt->advance);
1749 if (dt->format_expr)
1750 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1751 dt->format_expr);
1753 if (dt->format_label)
1755 if (dt->format_label == &format_asterisk)
1756 mask |= IOPARM_dt_list_format;
1757 else
1758 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1759 dt->format_label->format);
1762 if (dt->size)
1763 mask |= set_parameter_ref (&block, &post_end_block, var,
1764 IOPARM_dt_size, dt->size);
1766 if (dt->namelist)
1768 if (dt->format_expr || dt->format_label)
1769 gfc_internal_error ("build_dt: format with namelist");
1771 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1773 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1774 nmlname);
1776 if (last_dt == READ)
1777 mask |= IOPARM_dt_namelist_read_mode;
1779 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1781 dt_parm = var;
1783 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1784 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1785 NULL, NULL);
1787 else
1788 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1790 if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER)
1791 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1793 else
1794 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1796 tmp = build_fold_addr_expr (var);
1797 tmp = build_call_expr (function, 1, tmp);
1798 gfc_add_expr_to_block (&block, tmp);
1800 gfc_add_block_to_block (&block, &post_block);
1802 dt_parm = var;
1803 dt_post_end_block = &post_end_block;
1805 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1807 gfc_add_block_to_block (&block, &post_iu_block);
1809 dt_parm = NULL;
1810 dt_post_end_block = NULL;
1812 return gfc_finish_block (&block);
1816 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1817 this as a third sort of data transfer statement, except that
1818 lengths are summed instead of actually transferring any data. */
1820 tree
1821 gfc_trans_iolength (gfc_code * code)
1823 last_dt = IOLENGTH;
1824 return build_dt (iocall[IOCALL_IOLENGTH], code);
1828 /* Translate a READ statement. */
1830 tree
1831 gfc_trans_read (gfc_code * code)
1833 last_dt = READ;
1834 return build_dt (iocall[IOCALL_READ], code);
1838 /* Translate a WRITE statement */
1840 tree
1841 gfc_trans_write (gfc_code * code)
1843 last_dt = WRITE;
1844 return build_dt (iocall[IOCALL_WRITE], code);
1848 /* Finish a data transfer statement. */
1850 tree
1851 gfc_trans_dt_end (gfc_code * code)
1853 tree function, tmp;
1854 stmtblock_t block;
1856 gfc_init_block (&block);
1858 switch (last_dt)
1860 case READ:
1861 function = iocall[IOCALL_READ_DONE];
1862 break;
1864 case WRITE:
1865 function = iocall[IOCALL_WRITE_DONE];
1866 break;
1868 case IOLENGTH:
1869 function = iocall[IOCALL_IOLENGTH_DONE];
1870 break;
1872 default:
1873 gcc_unreachable ();
1876 tmp = build_fold_addr_expr (dt_parm);
1877 tmp = build_call_expr (function, 1, tmp);
1878 gfc_add_expr_to_block (&block, tmp);
1879 gfc_add_block_to_block (&block, dt_post_end_block);
1880 gfc_init_block (dt_post_end_block);
1882 if (last_dt != IOLENGTH)
1884 gcc_assert (code->ext.dt != NULL);
1885 io_result (&block, dt_parm, code->ext.dt->err,
1886 code->ext.dt->end, code->ext.dt->eor);
1889 return gfc_finish_block (&block);
1892 static void
1893 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code);
1895 /* Given an array field in a derived type variable, generate the code
1896 for the loop that iterates over array elements, and the code that
1897 accesses those array elements. Use transfer_expr to generate code
1898 for transferring that element. Because elements may also be
1899 derived types, transfer_expr and transfer_array_component are mutually
1900 recursive. */
1902 static tree
1903 transfer_array_component (tree expr, gfc_component * cm, locus * where)
1905 tree tmp;
1906 stmtblock_t body;
1907 stmtblock_t block;
1908 gfc_loopinfo loop;
1909 int n;
1910 gfc_ss *ss;
1911 gfc_se se;
1913 gfc_start_block (&block);
1914 gfc_init_se (&se, NULL);
1916 /* Create and initialize Scalarization Status. Unlike in
1917 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1918 care of this task, because we don't have a gfc_expr at hand.
1919 Build one manually, as in gfc_trans_subarray_assign. */
1921 ss = gfc_get_ss ();
1922 ss->type = GFC_SS_COMPONENT;
1923 ss->expr = NULL;
1924 ss->shape = gfc_get_shape (cm->as->rank);
1925 ss->next = gfc_ss_terminator;
1926 ss->data.info.dimen = cm->as->rank;
1927 ss->data.info.descriptor = expr;
1928 ss->data.info.data = gfc_conv_array_data (expr);
1929 ss->data.info.offset = gfc_conv_array_offset (expr);
1930 for (n = 0; n < cm->as->rank; n++)
1932 ss->data.info.dim[n] = n;
1933 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1934 ss->data.info.stride[n] = gfc_index_one_node;
1936 mpz_init (ss->shape[n]);
1937 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1938 cm->as->lower[n]->value.integer);
1939 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1942 /* Once we got ss, we use scalarizer to create the loop. */
1944 gfc_init_loopinfo (&loop);
1945 gfc_add_ss_to_loop (&loop, ss);
1946 gfc_conv_ss_startstride (&loop);
1947 gfc_conv_loop_setup (&loop, where);
1948 gfc_mark_ss_chain_used (ss, 1);
1949 gfc_start_scalarized_body (&loop, &body);
1951 gfc_copy_loopinfo_to_se (&se, &loop);
1952 se.ss = ss;
1954 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1955 se.expr = expr;
1956 gfc_conv_tmp_array_ref (&se);
1958 /* Now se.expr contains an element of the array. Take the address and pass
1959 it to the IO routines. */
1960 tmp = build_fold_addr_expr (se.expr);
1961 transfer_expr (&se, &cm->ts, tmp, NULL);
1963 /* We are done now with the loop body. Wrap up the scalarizer and
1964 return. */
1966 gfc_add_block_to_block (&body, &se.pre);
1967 gfc_add_block_to_block (&body, &se.post);
1969 gfc_trans_scalarizing_loops (&loop, &body);
1971 gfc_add_block_to_block (&block, &loop.pre);
1972 gfc_add_block_to_block (&block, &loop.post);
1974 for (n = 0; n < cm->as->rank; n++)
1975 mpz_clear (ss->shape[n]);
1976 gfc_free (ss->shape);
1978 gfc_cleanup_loop (&loop);
1980 return gfc_finish_block (&block);
1983 /* Generate the call for a scalar transfer node. */
1985 static void
1986 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
1988 tree tmp, function, arg2, arg3, field, expr;
1989 gfc_component *c;
1990 int kind;
1992 /* It is possible to get a C_NULL_PTR or C_NULL_FUNPTR expression here if
1993 the user says something like: print *, 'c_null_ptr: ', c_null_ptr
1994 We need to translate the expression to a constant if it's either
1995 C_NULL_PTR or C_NULL_FUNPTR. We could also get a user variable of
1996 type C_PTR or C_FUNPTR, in which case the ts->type may no longer be
1997 BT_DERIVED (could have been changed by gfc_conv_expr). */
1998 if ((ts->type == BT_DERIVED && ts->is_iso_c == 1 && ts->derived != NULL)
1999 || (ts->derived != NULL && ts->derived->ts.is_iso_c == 1))
2001 /* C_PTR and C_FUNPTR have private components which means they can not
2002 be printed. However, if -std=gnu and not -pedantic, allow
2003 the component to be printed to help debugging. */
2004 if (gfc_notification_std (GFC_STD_GNU) != SILENT)
2006 gfc_error_now ("Derived type '%s' at %L has PRIVATE components",
2007 ts->derived->name, code != NULL ? &(code->loc) :
2008 &gfc_current_locus);
2009 return;
2012 ts->type = ts->derived->ts.type;
2013 ts->kind = ts->derived->ts.kind;
2014 ts->f90_type = ts->derived->ts.f90_type;
2017 kind = ts->kind;
2018 function = NULL;
2019 arg2 = NULL;
2020 arg3 = NULL;
2022 switch (ts->type)
2024 case BT_INTEGER:
2025 arg2 = build_int_cst (NULL_TREE, kind);
2026 function = iocall[IOCALL_X_INTEGER];
2027 break;
2029 case BT_REAL:
2030 arg2 = build_int_cst (NULL_TREE, kind);
2031 function = iocall[IOCALL_X_REAL];
2032 break;
2034 case BT_COMPLEX:
2035 arg2 = build_int_cst (NULL_TREE, kind);
2036 function = iocall[IOCALL_X_COMPLEX];
2037 break;
2039 case BT_LOGICAL:
2040 arg2 = build_int_cst (NULL_TREE, kind);
2041 function = iocall[IOCALL_X_LOGICAL];
2042 break;
2044 case BT_CHARACTER:
2045 if (kind == 4)
2047 if (se->string_length)
2048 arg2 = se->string_length;
2049 else
2051 tmp = build_fold_indirect_ref (addr_expr);
2052 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2053 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2054 arg2 = fold_convert (gfc_charlen_type_node, arg2);
2056 arg3 = build_int_cst (NULL_TREE, kind);
2057 function = iocall[IOCALL_X_CHARACTER_WIDE];
2058 tmp = build_fold_addr_expr (dt_parm);
2059 tmp = build_call_expr (function, 4, tmp, addr_expr, arg2, arg3);
2060 gfc_add_expr_to_block (&se->pre, tmp);
2061 gfc_add_block_to_block (&se->pre, &se->post);
2062 return;
2064 /* Fall through. */
2065 case BT_HOLLERITH:
2066 if (se->string_length)
2067 arg2 = se->string_length;
2068 else
2070 tmp = build_fold_indirect_ref (addr_expr);
2071 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2072 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2074 function = iocall[IOCALL_X_CHARACTER];
2075 break;
2077 case BT_DERIVED:
2078 /* Recurse into the elements of the derived type. */
2079 expr = gfc_evaluate_now (addr_expr, &se->pre);
2080 expr = build_fold_indirect_ref (expr);
2082 for (c = ts->derived->components; c; c = c->next)
2084 field = c->backend_decl;
2085 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2087 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (field),
2088 expr, field, NULL_TREE);
2090 if (c->attr.dimension)
2092 tmp = transfer_array_component (tmp, c, & code->loc);
2093 gfc_add_expr_to_block (&se->pre, tmp);
2095 else
2097 if (!c->attr.pointer)
2098 tmp = build_fold_addr_expr (tmp);
2099 transfer_expr (se, &c->ts, tmp, code);
2102 return;
2104 default:
2105 internal_error ("Bad IO basetype (%d)", ts->type);
2108 tmp = build_fold_addr_expr (dt_parm);
2109 tmp = build_call_expr (function, 3, tmp, addr_expr, arg2);
2110 gfc_add_expr_to_block (&se->pre, tmp);
2111 gfc_add_block_to_block (&se->pre, &se->post);
2116 /* Generate a call to pass an array descriptor to the IO library. The
2117 array should be of one of the intrinsic types. */
2119 static void
2120 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
2122 tree tmp, charlen_arg, kind_arg;
2124 if (ts->type == BT_CHARACTER)
2125 charlen_arg = se->string_length;
2126 else
2127 charlen_arg = build_int_cst (NULL_TREE, 0);
2129 kind_arg = build_int_cst (NULL_TREE, ts->kind);
2131 tmp = build_fold_addr_expr (dt_parm);
2132 tmp = build_call_expr (iocall[IOCALL_X_ARRAY], 4,
2133 tmp, addr_expr, kind_arg, charlen_arg);
2134 gfc_add_expr_to_block (&se->pre, tmp);
2135 gfc_add_block_to_block (&se->pre, &se->post);
2139 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
2141 tree
2142 gfc_trans_transfer (gfc_code * code)
2144 stmtblock_t block, body;
2145 gfc_loopinfo loop;
2146 gfc_expr *expr;
2147 gfc_ref *ref;
2148 gfc_ss *ss;
2149 gfc_se se;
2150 tree tmp;
2151 int n;
2153 gfc_start_block (&block);
2154 gfc_init_block (&body);
2156 expr = code->expr;
2157 ss = gfc_walk_expr (expr);
2159 ref = NULL;
2160 gfc_init_se (&se, NULL);
2162 if (ss == gfc_ss_terminator)
2164 /* Transfer a scalar value. */
2165 gfc_conv_expr_reference (&se, expr);
2166 transfer_expr (&se, &expr->ts, se.expr, code);
2168 else
2170 /* Transfer an array. If it is an array of an intrinsic
2171 type, pass the descriptor to the library. Otherwise
2172 scalarize the transfer. */
2173 if (expr->ref)
2175 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
2176 ref = ref->next);
2177 gcc_assert (ref->type == REF_ARRAY);
2180 if (expr->ts.type != BT_DERIVED
2181 && ref && ref->next == NULL
2182 && !is_subref_array (expr))
2184 bool seen_vector = false;
2186 if (ref && ref->u.ar.type == AR_SECTION)
2188 for (n = 0; n < ref->u.ar.dimen; n++)
2189 if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
2190 seen_vector = true;
2193 if (seen_vector && last_dt == READ)
2195 /* Create a temp, read to that and copy it back. */
2196 gfc_conv_subref_array_arg (&se, expr, 0, INTENT_OUT);
2197 tmp = se.expr;
2199 else
2201 /* Get the descriptor. */
2202 gfc_conv_expr_descriptor (&se, expr, ss);
2203 tmp = build_fold_addr_expr (se.expr);
2206 transfer_array_desc (&se, &expr->ts, tmp);
2207 goto finish_block_label;
2210 /* Initialize the scalarizer. */
2211 gfc_init_loopinfo (&loop);
2212 gfc_add_ss_to_loop (&loop, ss);
2214 /* Initialize the loop. */
2215 gfc_conv_ss_startstride (&loop);
2216 gfc_conv_loop_setup (&loop, &code->expr->where);
2218 /* The main loop body. */
2219 gfc_mark_ss_chain_used (ss, 1);
2220 gfc_start_scalarized_body (&loop, &body);
2222 gfc_copy_loopinfo_to_se (&se, &loop);
2223 se.ss = ss;
2225 gfc_conv_expr_reference (&se, expr);
2226 transfer_expr (&se, &expr->ts, se.expr, code);
2229 finish_block_label:
2231 gfc_add_block_to_block (&body, &se.pre);
2232 gfc_add_block_to_block (&body, &se.post);
2234 if (se.ss == NULL)
2235 tmp = gfc_finish_block (&body);
2236 else
2238 gcc_assert (se.ss == gfc_ss_terminator);
2239 gfc_trans_scalarizing_loops (&loop, &body);
2241 gfc_add_block_to_block (&loop.pre, &loop.post);
2242 tmp = gfc_finish_block (&loop.pre);
2243 gfc_cleanup_loop (&loop);
2246 gfc_add_expr_to_block (&block, tmp);
2248 return gfc_finish_block (&block);
2251 #include "gt-fortran-trans-io.h"