* gimple-ssa-store-merging.c (struct store_immediate_info): Add
[official-gcc.git] / gcc / fortran / trans-io.c
blob9cd33b331e19d2b76faba4ae31ca5db13133dd95
1 /* IO Code translation/library interface
2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
3 Contributed by Paul Brook
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree.h"
26 #include "gfortran.h"
27 #include "trans.h"
28 #include "stringpool.h"
29 #include "fold-const.h"
30 #include "stor-layout.h"
31 #include "trans-stmt.h"
32 #include "trans-array.h"
33 #include "trans-types.h"
34 #include "trans-const.h"
35 #include "options.h"
37 /* Members of the ioparm structure. */
39 enum ioparam_type
41 IOPARM_ptype_common,
42 IOPARM_ptype_open,
43 IOPARM_ptype_close,
44 IOPARM_ptype_filepos,
45 IOPARM_ptype_inquire,
46 IOPARM_ptype_dt,
47 IOPARM_ptype_wait,
48 IOPARM_ptype_num
51 enum iofield_type
53 IOPARM_type_int4,
54 IOPARM_type_intio,
55 IOPARM_type_pint4,
56 IOPARM_type_pintio,
57 IOPARM_type_pchar,
58 IOPARM_type_parray,
59 IOPARM_type_pad,
60 IOPARM_type_char1,
61 IOPARM_type_char2,
62 IOPARM_type_common,
63 IOPARM_type_num
66 typedef struct GTY(()) gfc_st_parameter_field {
67 const char *name;
68 unsigned int mask;
69 enum ioparam_type param_type;
70 enum iofield_type type;
71 tree field;
72 tree field_len;
74 gfc_st_parameter_field;
76 typedef struct GTY(()) gfc_st_parameter {
77 const char *name;
78 tree type;
80 gfc_st_parameter;
82 enum iofield
84 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
85 #include "ioparm.def"
86 #undef IOPARM
87 IOPARM_field_num
90 static GTY(()) gfc_st_parameter st_parameter[] =
92 { "common", NULL },
93 { "open", NULL },
94 { "close", NULL },
95 { "filepos", NULL },
96 { "inquire", NULL },
97 { "dt", NULL },
98 { "wait", NULL }
101 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
103 #define IOPARM(param_type, name, mask, type) \
104 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
105 #include "ioparm.def"
106 #undef IOPARM
107 { NULL, 0, (enum ioparam_type) 0, (enum iofield_type) 0, NULL, NULL }
110 /* Library I/O subroutines */
112 enum iocall
114 IOCALL_READ,
115 IOCALL_READ_DONE,
116 IOCALL_WRITE,
117 IOCALL_WRITE_DONE,
118 IOCALL_X_INTEGER,
119 IOCALL_X_INTEGER_WRITE,
120 IOCALL_X_LOGICAL,
121 IOCALL_X_LOGICAL_WRITE,
122 IOCALL_X_CHARACTER,
123 IOCALL_X_CHARACTER_WRITE,
124 IOCALL_X_CHARACTER_WIDE,
125 IOCALL_X_CHARACTER_WIDE_WRITE,
126 IOCALL_X_REAL,
127 IOCALL_X_REAL_WRITE,
128 IOCALL_X_COMPLEX,
129 IOCALL_X_COMPLEX_WRITE,
130 IOCALL_X_REAL128,
131 IOCALL_X_REAL128_WRITE,
132 IOCALL_X_COMPLEX128,
133 IOCALL_X_COMPLEX128_WRITE,
134 IOCALL_X_ARRAY,
135 IOCALL_X_ARRAY_WRITE,
136 IOCALL_X_DERIVED,
137 IOCALL_OPEN,
138 IOCALL_CLOSE,
139 IOCALL_INQUIRE,
140 IOCALL_IOLENGTH,
141 IOCALL_IOLENGTH_DONE,
142 IOCALL_REWIND,
143 IOCALL_BACKSPACE,
144 IOCALL_ENDFILE,
145 IOCALL_FLUSH,
146 IOCALL_SET_NML_VAL,
147 IOCALL_SET_NML_DTIO_VAL,
148 IOCALL_SET_NML_VAL_DIM,
149 IOCALL_WAIT,
150 IOCALL_NUM
153 static GTY(()) tree iocall[IOCALL_NUM];
155 /* Variable for keeping track of what the last data transfer statement
156 was. Used for deciding which subroutine to call when the data
157 transfer is complete. */
158 static enum { READ, WRITE, IOLENGTH } last_dt;
160 /* The data transfer parameter block that should be shared by all
161 data transfer calls belonging to the same read/write/iolength. */
162 static GTY(()) tree dt_parm;
163 static stmtblock_t *dt_post_end_block;
165 static void
166 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
168 unsigned int type;
169 gfc_st_parameter_field *p;
170 char name[64];
171 size_t len;
172 tree t = make_node (RECORD_TYPE);
173 tree *chain = NULL;
175 len = strlen (st_parameter[ptype].name);
176 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
177 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
178 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
179 len + 1);
180 TYPE_NAME (t) = get_identifier (name);
182 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
183 if (p->param_type == ptype)
184 switch (p->type)
186 case IOPARM_type_int4:
187 case IOPARM_type_intio:
188 case IOPARM_type_pint4:
189 case IOPARM_type_pintio:
190 case IOPARM_type_parray:
191 case IOPARM_type_pchar:
192 case IOPARM_type_pad:
193 p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
194 types[p->type], &chain);
195 break;
196 case IOPARM_type_char1:
197 p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
198 pchar_type_node, &chain);
199 /* FALLTHROUGH */
200 case IOPARM_type_char2:
201 len = strlen (p->name);
202 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
203 memcpy (name, p->name, len);
204 memcpy (name + len, "_len", sizeof ("_len"));
205 p->field_len = gfc_add_field_to_struct (t, get_identifier (name),
206 gfc_charlen_type_node,
207 &chain);
208 if (p->type == IOPARM_type_char2)
209 p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
210 pchar_type_node, &chain);
211 break;
212 case IOPARM_type_common:
213 p->field
214 = gfc_add_field_to_struct (t,
215 get_identifier (p->name),
216 st_parameter[IOPARM_ptype_common].type,
217 &chain);
218 break;
219 case IOPARM_type_num:
220 gcc_unreachable ();
223 /* -Wpadded warnings on these artificially created structures are not
224 helpful; suppress them. */
225 int save_warn_padded = warn_padded;
226 warn_padded = 0;
227 gfc_finish_type (t);
228 warn_padded = save_warn_padded;
229 st_parameter[ptype].type = t;
233 /* Build code to test an error condition and call generate_error if needed.
234 Note: This builds calls to generate_error in the runtime library function.
235 The function generate_error is dependent on certain parameters in the
236 st_parameter_common flags to be set. (See libgfortran/runtime/error.c)
237 Therefore, the code to set these flags must be generated before
238 this function is used. */
240 static void
241 gfc_trans_io_runtime_check (bool has_iostat, tree cond, tree var,
242 int error_code, const char * msgid,
243 stmtblock_t * pblock)
245 stmtblock_t block;
246 tree body;
247 tree tmp;
248 tree arg1, arg2, arg3;
249 char *message;
251 if (integer_zerop (cond))
252 return;
254 /* The code to generate the error. */
255 gfc_start_block (&block);
257 if (has_iostat)
258 gfc_add_expr_to_block (&block, build_predict_expr (PRED_FORTRAN_FAIL_IO,
259 NOT_TAKEN));
260 else
261 gfc_add_expr_to_block (&block, build_predict_expr (PRED_NORETURN,
262 NOT_TAKEN));
264 arg1 = gfc_build_addr_expr (NULL_TREE, var);
266 arg2 = build_int_cst (integer_type_node, error_code),
268 message = xasprintf ("%s", _(msgid));
269 arg3 = gfc_build_addr_expr (pchar_type_node,
270 gfc_build_localized_cstring_const (message));
271 free (message);
273 tmp = build_call_expr_loc (input_location,
274 gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
276 gfc_add_expr_to_block (&block, tmp);
278 body = gfc_finish_block (&block);
280 if (integer_onep (cond))
282 gfc_add_expr_to_block (pblock, body);
284 else
286 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location));
287 gfc_add_expr_to_block (pblock, tmp);
292 /* Create function decls for IO library functions. */
294 void
295 gfc_build_io_library_fndecls (void)
297 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
298 tree gfc_intio_type_node;
299 tree parm_type, dt_parm_type;
300 HOST_WIDE_INT pad_size;
301 unsigned int ptype;
303 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
304 types[IOPARM_type_intio] = gfc_intio_type_node
305 = gfc_get_int_type (gfc_intio_kind);
306 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
307 types[IOPARM_type_pintio]
308 = build_pointer_type (gfc_intio_type_node);
309 types[IOPARM_type_parray] = pchar_type_node;
310 types[IOPARM_type_pchar] = pchar_type_node;
311 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
312 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
313 pad_idx = build_index_type (size_int (pad_size - 1));
314 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
316 /* pad actually contains pointers and integers so it needs to have an
317 alignment that is at least as large as the needed alignment for those
318 types. See the st_parameter_dt structure in libgfortran/io/io.h for
319 what really goes into this space. */
320 SET_TYPE_ALIGN (types[IOPARM_type_pad], MAX (TYPE_ALIGN (pchar_type_node),
321 TYPE_ALIGN (gfc_get_int_type (gfc_intio_kind))));
323 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
324 gfc_build_st_parameter ((enum ioparam_type) ptype, types);
326 /* Define the transfer functions. */
328 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
330 iocall[IOCALL_X_INTEGER] = gfc_build_library_function_decl_with_spec (
331 get_identifier (PREFIX("transfer_integer")), ".wW",
332 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
334 iocall[IOCALL_X_INTEGER_WRITE] = gfc_build_library_function_decl_with_spec (
335 get_identifier (PREFIX("transfer_integer_write")), ".wR",
336 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
338 iocall[IOCALL_X_LOGICAL] = gfc_build_library_function_decl_with_spec (
339 get_identifier (PREFIX("transfer_logical")), ".wW",
340 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
342 iocall[IOCALL_X_LOGICAL_WRITE] = gfc_build_library_function_decl_with_spec (
343 get_identifier (PREFIX("transfer_logical_write")), ".wR",
344 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
346 iocall[IOCALL_X_CHARACTER] = gfc_build_library_function_decl_with_spec (
347 get_identifier (PREFIX("transfer_character")), ".wW",
348 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
350 iocall[IOCALL_X_CHARACTER_WRITE] = gfc_build_library_function_decl_with_spec (
351 get_identifier (PREFIX("transfer_character_write")), ".wR",
352 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
354 iocall[IOCALL_X_CHARACTER_WIDE] = gfc_build_library_function_decl_with_spec (
355 get_identifier (PREFIX("transfer_character_wide")), ".wW",
356 void_type_node, 4, dt_parm_type, pvoid_type_node,
357 gfc_charlen_type_node, gfc_int4_type_node);
359 iocall[IOCALL_X_CHARACTER_WIDE_WRITE] =
360 gfc_build_library_function_decl_with_spec (
361 get_identifier (PREFIX("transfer_character_wide_write")), ".wR",
362 void_type_node, 4, dt_parm_type, pvoid_type_node,
363 gfc_charlen_type_node, gfc_int4_type_node);
365 iocall[IOCALL_X_REAL] = gfc_build_library_function_decl_with_spec (
366 get_identifier (PREFIX("transfer_real")), ".wW",
367 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
369 iocall[IOCALL_X_REAL_WRITE] = gfc_build_library_function_decl_with_spec (
370 get_identifier (PREFIX("transfer_real_write")), ".wR",
371 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
373 iocall[IOCALL_X_COMPLEX] = gfc_build_library_function_decl_with_spec (
374 get_identifier (PREFIX("transfer_complex")), ".wW",
375 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
377 iocall[IOCALL_X_COMPLEX_WRITE] = gfc_build_library_function_decl_with_spec (
378 get_identifier (PREFIX("transfer_complex_write")), ".wR",
379 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
381 /* Version for __float128. */
382 iocall[IOCALL_X_REAL128] = gfc_build_library_function_decl_with_spec (
383 get_identifier (PREFIX("transfer_real128")), ".wW",
384 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
386 iocall[IOCALL_X_REAL128_WRITE] = gfc_build_library_function_decl_with_spec (
387 get_identifier (PREFIX("transfer_real128_write")), ".wR",
388 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
390 iocall[IOCALL_X_COMPLEX128] = gfc_build_library_function_decl_with_spec (
391 get_identifier (PREFIX("transfer_complex128")), ".wW",
392 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
394 iocall[IOCALL_X_COMPLEX128_WRITE] = gfc_build_library_function_decl_with_spec (
395 get_identifier (PREFIX("transfer_complex128_write")), ".wR",
396 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
398 iocall[IOCALL_X_ARRAY] = gfc_build_library_function_decl_with_spec (
399 get_identifier (PREFIX("transfer_array")), ".ww",
400 void_type_node, 4, dt_parm_type, pvoid_type_node,
401 integer_type_node, gfc_charlen_type_node);
403 iocall[IOCALL_X_ARRAY_WRITE] = gfc_build_library_function_decl_with_spec (
404 get_identifier (PREFIX("transfer_array_write")), ".wr",
405 void_type_node, 4, dt_parm_type, pvoid_type_node,
406 integer_type_node, gfc_charlen_type_node);
408 iocall[IOCALL_X_DERIVED] = gfc_build_library_function_decl_with_spec (
409 get_identifier (PREFIX("transfer_derived")), ".wrR",
410 void_type_node, 2, dt_parm_type, pvoid_type_node, pchar_type_node);
412 /* Library entry points */
414 iocall[IOCALL_READ] = gfc_build_library_function_decl_with_spec (
415 get_identifier (PREFIX("st_read")), ".w",
416 void_type_node, 1, dt_parm_type);
418 iocall[IOCALL_WRITE] = gfc_build_library_function_decl_with_spec (
419 get_identifier (PREFIX("st_write")), ".w",
420 void_type_node, 1, dt_parm_type);
422 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
423 iocall[IOCALL_OPEN] = gfc_build_library_function_decl_with_spec (
424 get_identifier (PREFIX("st_open")), ".w",
425 void_type_node, 1, parm_type);
427 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
428 iocall[IOCALL_CLOSE] = gfc_build_library_function_decl_with_spec (
429 get_identifier (PREFIX("st_close")), ".w",
430 void_type_node, 1, parm_type);
432 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
433 iocall[IOCALL_INQUIRE] = gfc_build_library_function_decl_with_spec (
434 get_identifier (PREFIX("st_inquire")), ".w",
435 void_type_node, 1, parm_type);
437 iocall[IOCALL_IOLENGTH] = gfc_build_library_function_decl_with_spec(
438 get_identifier (PREFIX("st_iolength")), ".w",
439 void_type_node, 1, dt_parm_type);
441 /* TODO: Change when asynchronous I/O is implemented. */
442 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_wait].type);
443 iocall[IOCALL_WAIT] = gfc_build_library_function_decl_with_spec (
444 get_identifier (PREFIX("st_wait")), ".X",
445 void_type_node, 1, parm_type);
447 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
448 iocall[IOCALL_REWIND] = gfc_build_library_function_decl_with_spec (
449 get_identifier (PREFIX("st_rewind")), ".w",
450 void_type_node, 1, parm_type);
452 iocall[IOCALL_BACKSPACE] = gfc_build_library_function_decl_with_spec (
453 get_identifier (PREFIX("st_backspace")), ".w",
454 void_type_node, 1, parm_type);
456 iocall[IOCALL_ENDFILE] = gfc_build_library_function_decl_with_spec (
457 get_identifier (PREFIX("st_endfile")), ".w",
458 void_type_node, 1, parm_type);
460 iocall[IOCALL_FLUSH] = gfc_build_library_function_decl_with_spec (
461 get_identifier (PREFIX("st_flush")), ".w",
462 void_type_node, 1, parm_type);
464 /* Library helpers */
466 iocall[IOCALL_READ_DONE] = gfc_build_library_function_decl_with_spec (
467 get_identifier (PREFIX("st_read_done")), ".w",
468 void_type_node, 1, dt_parm_type);
470 iocall[IOCALL_WRITE_DONE] = gfc_build_library_function_decl_with_spec (
471 get_identifier (PREFIX("st_write_done")), ".w",
472 void_type_node, 1, dt_parm_type);
474 iocall[IOCALL_IOLENGTH_DONE] = gfc_build_library_function_decl_with_spec (
475 get_identifier (PREFIX("st_iolength_done")), ".w",
476 void_type_node, 1, dt_parm_type);
478 iocall[IOCALL_SET_NML_VAL] = gfc_build_library_function_decl_with_spec (
479 get_identifier (PREFIX("st_set_nml_var")), ".w.R",
480 void_type_node, 6, dt_parm_type, pvoid_type_node, pvoid_type_node,
481 gfc_int4_type_node, gfc_charlen_type_node, gfc_int4_type_node);
483 iocall[IOCALL_SET_NML_DTIO_VAL] = gfc_build_library_function_decl_with_spec (
484 get_identifier (PREFIX("st_set_nml_dtio_var")), ".w.R",
485 void_type_node, 8, dt_parm_type, pvoid_type_node, pvoid_type_node,
486 gfc_int4_type_node, gfc_charlen_type_node, gfc_int4_type_node,
487 pvoid_type_node, pvoid_type_node);
489 iocall[IOCALL_SET_NML_VAL_DIM] = gfc_build_library_function_decl_with_spec (
490 get_identifier (PREFIX("st_set_nml_var_dim")), ".w",
491 void_type_node, 5, dt_parm_type, gfc_int4_type_node,
492 gfc_array_index_type, gfc_array_index_type, gfc_array_index_type);
496 static void
497 set_parameter_tree (stmtblock_t *block, tree var, enum iofield type, tree value)
499 tree tmp;
500 gfc_st_parameter_field *p = &st_parameter_field[type];
502 if (p->param_type == IOPARM_ptype_common)
503 var = fold_build3_loc (input_location, COMPONENT_REF,
504 st_parameter[IOPARM_ptype_common].type,
505 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
506 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (p->field),
507 var, p->field, NULL_TREE);
508 gfc_add_modify (block, tmp, value);
512 /* Generate code to store an integer constant into the
513 st_parameter_XXX structure. */
515 static unsigned int
516 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
517 unsigned int val)
519 gfc_st_parameter_field *p = &st_parameter_field[type];
521 set_parameter_tree (block, var, type,
522 build_int_cst (TREE_TYPE (p->field), val));
523 return p->mask;
527 /* Generate code to store a non-string I/O parameter into the
528 st_parameter_XXX structure. This is a pass by value. */
530 static unsigned int
531 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
532 gfc_expr *e)
534 gfc_se se;
535 tree tmp;
536 gfc_st_parameter_field *p = &st_parameter_field[type];
537 tree dest_type = TREE_TYPE (p->field);
539 gfc_init_se (&se, NULL);
540 gfc_conv_expr_val (&se, e);
542 se.expr = convert (dest_type, se.expr);
543 gfc_add_block_to_block (block, &se.pre);
545 if (p->param_type == IOPARM_ptype_common)
546 var = fold_build3_loc (input_location, COMPONENT_REF,
547 st_parameter[IOPARM_ptype_common].type,
548 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
550 tmp = fold_build3_loc (input_location, COMPONENT_REF, dest_type, var,
551 p->field, NULL_TREE);
552 gfc_add_modify (block, tmp, se.expr);
553 return p->mask;
557 /* Similar to set_parameter_value except generate runtime
558 error checks. */
560 static unsigned int
561 set_parameter_value_chk (stmtblock_t *block, bool has_iostat, tree var,
562 enum iofield type, gfc_expr *e)
564 gfc_se se;
565 tree tmp;
566 gfc_st_parameter_field *p = &st_parameter_field[type];
567 tree dest_type = TREE_TYPE (p->field);
569 gfc_init_se (&se, NULL);
570 gfc_conv_expr_val (&se, e);
572 /* If we're storing a UNIT number, we need to check it first. */
573 if (type == IOPARM_common_unit && e->ts.kind > 4)
575 tree cond, val;
576 int i;
578 /* Don't evaluate the UNIT number multiple times. */
579 se.expr = gfc_evaluate_now (se.expr, &se.pre);
581 /* UNIT numbers should be greater than the min. */
582 i = gfc_validate_kind (BT_INTEGER, 4, false);
583 val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].pedantic_min_int, 4);
584 cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
585 se.expr,
586 fold_convert (TREE_TYPE (se.expr), val));
587 gfc_trans_io_runtime_check (has_iostat, cond, var, LIBERROR_BAD_UNIT,
588 "Unit number in I/O statement too small",
589 &se.pre);
591 /* UNIT numbers should be less than the max. */
592 val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
593 cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
594 se.expr,
595 fold_convert (TREE_TYPE (se.expr), val));
596 gfc_trans_io_runtime_check (has_iostat, cond, var, LIBERROR_BAD_UNIT,
597 "Unit number in I/O statement too large",
598 &se.pre);
601 se.expr = convert (dest_type, se.expr);
602 gfc_add_block_to_block (block, &se.pre);
604 if (p->param_type == IOPARM_ptype_common)
605 var = fold_build3_loc (input_location, COMPONENT_REF,
606 st_parameter[IOPARM_ptype_common].type,
607 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
609 tmp = fold_build3_loc (input_location, COMPONENT_REF, dest_type, var,
610 p->field, NULL_TREE);
611 gfc_add_modify (block, tmp, se.expr);
612 return p->mask;
616 /* Build code to check the unit range if KIND=8 is used. Similar to
617 set_parameter_value_chk but we do not generate error calls for
618 inquire statements. */
620 static unsigned int
621 set_parameter_value_inquire (stmtblock_t *block, tree var,
622 enum iofield type, gfc_expr *e)
624 gfc_se se;
625 gfc_st_parameter_field *p = &st_parameter_field[type];
626 tree dest_type = TREE_TYPE (p->field);
628 gfc_init_se (&se, NULL);
629 gfc_conv_expr_val (&se, e);
631 /* If we're inquiring on a UNIT number, we need to check to make
632 sure it exists for larger than kind = 4. */
633 if (type == IOPARM_common_unit && e->ts.kind > 4)
635 stmtblock_t newblock;
636 tree cond1, cond2, cond3, val, body;
637 int i;
639 /* Don't evaluate the UNIT number multiple times. */
640 se.expr = gfc_evaluate_now (se.expr, &se.pre);
642 /* UNIT numbers should be greater than zero. */
643 i = gfc_validate_kind (BT_INTEGER, 4, false);
644 cond1 = build2_loc (input_location, LT_EXPR, logical_type_node,
645 se.expr,
646 fold_convert (TREE_TYPE (se.expr),
647 integer_zero_node));
648 /* UNIT numbers should be less than the max. */
649 val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
650 cond2 = build2_loc (input_location, GT_EXPR, logical_type_node,
651 se.expr,
652 fold_convert (TREE_TYPE (se.expr), val));
653 cond3 = build2_loc (input_location, TRUTH_OR_EXPR,
654 logical_type_node, cond1, cond2);
656 gfc_start_block (&newblock);
658 /* The unit number GFC_INVALID_UNIT is reserved. No units can
659 ever have this value. It is used here to signal to the
660 runtime library that the inquire unit number is outside the
661 allowable range and so cannot exist. It is needed when
662 -fdefault-integer-8 is used. */
663 set_parameter_const (&newblock, var, IOPARM_common_unit,
664 GFC_INVALID_UNIT);
666 body = gfc_finish_block (&newblock);
668 cond3 = gfc_unlikely (cond3, PRED_FORTRAN_FAIL_IO);
669 var = build3_v (COND_EXPR, cond3, body, build_empty_stmt (input_location));
670 gfc_add_expr_to_block (&se.pre, var);
673 se.expr = convert (dest_type, se.expr);
674 gfc_add_block_to_block (block, &se.pre);
676 return p->mask;
680 /* Generate code to store a non-string I/O parameter into the
681 st_parameter_XXX structure. This is pass by reference. */
683 static unsigned int
684 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
685 tree var, enum iofield type, gfc_expr *e)
687 gfc_se se;
688 tree tmp, addr;
689 gfc_st_parameter_field *p = &st_parameter_field[type];
691 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
692 gfc_init_se (&se, NULL);
693 gfc_conv_expr_lhs (&se, e);
695 gfc_add_block_to_block (block, &se.pre);
697 if (TYPE_MODE (TREE_TYPE (se.expr))
698 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
700 addr = convert (TREE_TYPE (p->field), gfc_build_addr_expr (NULL_TREE, se.expr));
702 /* If this is for the iostat variable initialize the
703 user variable to LIBERROR_OK which is zero. */
704 if (type == IOPARM_common_iostat)
705 gfc_add_modify (block, se.expr,
706 build_int_cst (TREE_TYPE (se.expr), LIBERROR_OK));
708 else
710 /* The type used by the library has different size
711 from the type of the variable supplied by the user.
712 Need to use a temporary. */
713 tree tmpvar = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
714 st_parameter_field[type].name);
716 /* If this is for the iostat variable, initialize the
717 user variable to LIBERROR_OK which is zero. */
718 if (type == IOPARM_common_iostat)
719 gfc_add_modify (block, tmpvar,
720 build_int_cst (TREE_TYPE (tmpvar), LIBERROR_OK));
722 addr = gfc_build_addr_expr (NULL_TREE, tmpvar);
723 /* After the I/O operation, we set the variable from the temporary. */
724 tmp = convert (TREE_TYPE (se.expr), tmpvar);
725 gfc_add_modify (postblock, se.expr, tmp);
728 set_parameter_tree (block, var, type, addr);
729 return p->mask;
732 /* Given an array expr, find its address and length to get a string. If the
733 array is full, the string's address is the address of array's first element
734 and the length is the size of the whole array. If it is an element, the
735 string's address is the element's address and the length is the rest size of
736 the array. */
738 static void
739 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
741 tree size;
743 if (e->rank == 0)
745 tree type, array, tmp;
746 gfc_symbol *sym;
747 int rank;
749 /* If it is an element, we need its address and size of the rest. */
750 gcc_assert (e->expr_type == EXPR_VARIABLE);
751 gcc_assert (e->ref->u.ar.type == AR_ELEMENT);
752 sym = e->symtree->n.sym;
753 rank = sym->as->rank - 1;
754 gfc_conv_expr (se, e);
756 array = sym->backend_decl;
757 type = TREE_TYPE (array);
759 if (GFC_ARRAY_TYPE_P (type))
760 size = GFC_TYPE_ARRAY_SIZE (type);
761 else
763 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
764 size = gfc_conv_array_stride (array, rank);
765 tmp = fold_build2_loc (input_location, MINUS_EXPR,
766 gfc_array_index_type,
767 gfc_conv_array_ubound (array, rank),
768 gfc_conv_array_lbound (array, rank));
769 tmp = fold_build2_loc (input_location, PLUS_EXPR,
770 gfc_array_index_type, tmp,
771 gfc_index_one_node);
772 size = fold_build2_loc (input_location, MULT_EXPR,
773 gfc_array_index_type, tmp, size);
775 gcc_assert (size);
777 size = fold_build2_loc (input_location, MINUS_EXPR,
778 gfc_array_index_type, size,
779 TREE_OPERAND (se->expr, 1));
780 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
781 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
782 size = fold_build2_loc (input_location, MULT_EXPR,
783 gfc_array_index_type, size,
784 fold_convert (gfc_array_index_type, tmp));
785 se->string_length = fold_convert (gfc_charlen_type_node, size);
786 return;
789 gfc_conv_array_parameter (se, e, true, NULL, NULL, &size);
790 se->string_length = fold_convert (gfc_charlen_type_node, size);
794 /* Generate code to store a string and its length into the
795 st_parameter_XXX structure. */
797 static unsigned int
798 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
799 enum iofield type, gfc_expr * e)
801 gfc_se se;
802 tree tmp;
803 tree io;
804 tree len;
805 gfc_st_parameter_field *p = &st_parameter_field[type];
807 gfc_init_se (&se, NULL);
809 if (p->param_type == IOPARM_ptype_common)
810 var = fold_build3_loc (input_location, COMPONENT_REF,
811 st_parameter[IOPARM_ptype_common].type,
812 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
813 io = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (p->field),
814 var, p->field, NULL_TREE);
815 len = fold_build3_loc (input_location, COMPONENT_REF,
816 TREE_TYPE (p->field_len),
817 var, p->field_len, NULL_TREE);
819 /* Integer variable assigned a format label. */
820 if (e->ts.type == BT_INTEGER
821 && e->rank == 0
822 && e->symtree->n.sym->attr.assign == 1)
824 char * msg;
825 tree cond;
827 gfc_conv_label_variable (&se, e);
828 tmp = GFC_DECL_STRING_LEN (se.expr);
829 cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
830 tmp, build_int_cst (TREE_TYPE (tmp), 0));
832 msg = xasprintf ("Label assigned to variable '%s' (%%ld) is not a format "
833 "label", e->symtree->name);
834 gfc_trans_runtime_check (true, false, cond, &se.pre, &e->where, msg,
835 fold_convert (long_integer_type_node, tmp));
836 free (msg);
838 gfc_add_modify (&se.pre, io,
839 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
840 gfc_add_modify (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
842 else
844 /* General character. */
845 if (e->ts.type == BT_CHARACTER && e->rank == 0)
846 gfc_conv_expr (&se, e);
847 /* Array assigned Hollerith constant or character array. */
848 else if (e->rank > 0 || (e->symtree && e->symtree->n.sym->as->rank > 0))
849 gfc_convert_array_to_string (&se, e);
850 else
851 gcc_unreachable ();
853 gfc_conv_string_parameter (&se);
854 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
855 gfc_add_modify (&se.pre, len, se.string_length);
858 gfc_add_block_to_block (block, &se.pre);
859 gfc_add_block_to_block (postblock, &se.post);
860 return p->mask;
864 /* Generate code to store the character (array) and the character length
865 for an internal unit. */
867 static unsigned int
868 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
869 tree var, gfc_expr * e)
871 gfc_se se;
872 tree io;
873 tree len;
874 tree desc;
875 tree tmp;
876 gfc_st_parameter_field *p;
877 unsigned int mask;
879 gfc_init_se (&se, NULL);
881 p = &st_parameter_field[IOPARM_dt_internal_unit];
882 mask = p->mask;
883 io = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (p->field),
884 var, p->field, NULL_TREE);
885 len = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (p->field_len),
886 var, p->field_len, NULL_TREE);
887 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
888 desc = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (p->field),
889 var, p->field, NULL_TREE);
891 gcc_assert (e->ts.type == BT_CHARACTER);
893 /* Character scalars. */
894 if (e->rank == 0)
896 gfc_conv_expr (&se, e);
897 gfc_conv_string_parameter (&se);
898 tmp = se.expr;
899 se.expr = build_int_cst (pchar_type_node, 0);
902 /* Character array. */
903 else if (e->rank > 0)
905 if (is_subref_array (e))
907 /* Use a temporary for components of arrays of derived types
908 or substring array references. */
909 gfc_conv_subref_array_arg (&se, e, 0,
910 last_dt == READ ? INTENT_IN : INTENT_OUT, false);
911 tmp = build_fold_indirect_ref_loc (input_location,
912 se.expr);
913 se.expr = gfc_build_addr_expr (pchar_type_node, tmp);
914 tmp = gfc_conv_descriptor_data_get (tmp);
916 else
918 /* Return the data pointer and rank from the descriptor. */
919 gfc_conv_expr_descriptor (&se, e);
920 tmp = gfc_conv_descriptor_data_get (se.expr);
921 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
924 else
925 gcc_unreachable ();
927 /* The cast is needed for character substrings and the descriptor
928 data. */
929 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
930 gfc_add_modify (&se.pre, len,
931 fold_convert (TREE_TYPE (len), se.string_length));
932 gfc_add_modify (&se.pre, desc, se.expr);
934 gfc_add_block_to_block (block, &se.pre);
935 gfc_add_block_to_block (post_block, &se.post);
936 return mask;
939 /* Add a case to a IO-result switch. */
941 static void
942 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
944 tree tmp, value;
946 if (label == NULL)
947 return; /* No label, no case */
949 value = build_int_cst (integer_type_node, label_value);
951 /* Make a backend label for this case. */
952 tmp = gfc_build_label_decl (NULL_TREE);
954 /* And the case itself. */
955 tmp = build_case_label (value, NULL_TREE, tmp);
956 gfc_add_expr_to_block (body, tmp);
958 /* Jump to the label. */
959 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
960 gfc_add_expr_to_block (body, tmp);
964 /* Generate a switch statement that branches to the correct I/O
965 result label. The last statement of an I/O call stores the
966 result into a variable because there is often cleanup that
967 must be done before the switch, so a temporary would have to
968 be created anyway. */
970 static void
971 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
972 gfc_st_label * end_label, gfc_st_label * eor_label)
974 stmtblock_t body;
975 tree tmp, rc;
976 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
978 /* If no labels are specified, ignore the result instead
979 of building an empty switch. */
980 if (err_label == NULL
981 && end_label == NULL
982 && eor_label == NULL)
983 return;
985 /* Build a switch statement. */
986 gfc_start_block (&body);
988 /* The label values here must be the same as the values
989 in the library_return enum in the runtime library */
990 add_case (1, err_label, &body);
991 add_case (2, end_label, &body);
992 add_case (3, eor_label, &body);
994 tmp = gfc_finish_block (&body);
996 var = fold_build3_loc (input_location, COMPONENT_REF,
997 st_parameter[IOPARM_ptype_common].type,
998 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
999 rc = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (p->field),
1000 var, p->field, NULL_TREE);
1001 rc = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (rc),
1002 rc, build_int_cst (TREE_TYPE (rc),
1003 IOPARM_common_libreturn_mask));
1005 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
1006 rc, tmp, NULL_TREE);
1008 gfc_add_expr_to_block (block, tmp);
1012 /* Store the current file and line number to variables so that if a
1013 library call goes awry, we can tell the user where the problem is. */
1015 static void
1016 set_error_locus (stmtblock_t * block, tree var, locus * where)
1018 gfc_file *f;
1019 tree str, locus_file;
1020 int line;
1021 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
1023 locus_file = fold_build3_loc (input_location, COMPONENT_REF,
1024 st_parameter[IOPARM_ptype_common].type,
1025 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
1026 locus_file = fold_build3_loc (input_location, COMPONENT_REF,
1027 TREE_TYPE (p->field), locus_file,
1028 p->field, NULL_TREE);
1029 f = where->lb->file;
1030 str = gfc_build_cstring_const (f->filename);
1032 str = gfc_build_addr_expr (pchar_type_node, str);
1033 gfc_add_modify (block, locus_file, str);
1035 line = LOCATION_LINE (where->lb->location);
1036 set_parameter_const (block, var, IOPARM_common_line, line);
1040 /* Translate an OPEN statement. */
1042 tree
1043 gfc_trans_open (gfc_code * code)
1045 stmtblock_t block, post_block;
1046 gfc_open *p;
1047 tree tmp, var;
1048 unsigned int mask = 0;
1050 gfc_start_block (&block);
1051 gfc_init_block (&post_block);
1053 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
1055 set_error_locus (&block, var, &code->loc);
1056 p = code->ext.open;
1058 if (p->iomsg)
1059 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1060 p->iomsg);
1062 if (p->iostat)
1063 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1064 p->iostat);
1066 if (p->err)
1067 mask |= IOPARM_common_err;
1069 if (p->file)
1070 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
1072 if (p->status)
1073 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
1074 p->status);
1076 if (p->access)
1077 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
1078 p->access);
1080 if (p->form)
1081 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
1083 if (p->recl)
1084 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in,
1085 p->recl);
1087 if (p->blank)
1088 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
1089 p->blank);
1091 if (p->position)
1092 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
1093 p->position);
1095 if (p->action)
1096 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
1097 p->action);
1099 if (p->delim)
1100 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
1101 p->delim);
1103 if (p->pad)
1104 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
1106 if (p->decimal)
1107 mask |= set_string (&block, &post_block, var, IOPARM_open_decimal,
1108 p->decimal);
1110 if (p->encoding)
1111 mask |= set_string (&block, &post_block, var, IOPARM_open_encoding,
1112 p->encoding);
1114 if (p->round)
1115 mask |= set_string (&block, &post_block, var, IOPARM_open_round, p->round);
1117 if (p->sign)
1118 mask |= set_string (&block, &post_block, var, IOPARM_open_sign, p->sign);
1120 if (p->asynchronous)
1121 mask |= set_string (&block, &post_block, var, IOPARM_open_asynchronous,
1122 p->asynchronous);
1124 if (p->convert)
1125 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
1126 p->convert);
1128 if (p->newunit)
1129 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_open_newunit,
1130 p->newunit);
1132 if (p->cc)
1133 mask |= set_string (&block, &post_block, var, IOPARM_open_cc, p->cc);
1135 if (p->share)
1136 mask |= set_string (&block, &post_block, var, IOPARM_open_share, p->share);
1138 mask |= set_parameter_const (&block, var, IOPARM_open_readonly, p->readonly);
1140 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1142 if (p->unit)
1143 set_parameter_value_chk (&block, p->iostat, var, IOPARM_common_unit, p->unit);
1144 else
1145 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1147 tmp = gfc_build_addr_expr (NULL_TREE, var);
1148 tmp = build_call_expr_loc (input_location,
1149 iocall[IOCALL_OPEN], 1, tmp);
1150 gfc_add_expr_to_block (&block, tmp);
1152 gfc_add_block_to_block (&block, &post_block);
1154 io_result (&block, var, p->err, NULL, NULL);
1156 return gfc_finish_block (&block);
1160 /* Translate a CLOSE statement. */
1162 tree
1163 gfc_trans_close (gfc_code * code)
1165 stmtblock_t block, post_block;
1166 gfc_close *p;
1167 tree tmp, var;
1168 unsigned int mask = 0;
1170 gfc_start_block (&block);
1171 gfc_init_block (&post_block);
1173 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
1175 set_error_locus (&block, var, &code->loc);
1176 p = code->ext.close;
1178 if (p->iomsg)
1179 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1180 p->iomsg);
1182 if (p->iostat)
1183 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1184 p->iostat);
1186 if (p->err)
1187 mask |= IOPARM_common_err;
1189 if (p->status)
1190 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
1191 p->status);
1193 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1195 if (p->unit)
1196 set_parameter_value_chk (&block, p->iostat, var, IOPARM_common_unit, p->unit);
1197 else
1198 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1200 tmp = gfc_build_addr_expr (NULL_TREE, var);
1201 tmp = build_call_expr_loc (input_location,
1202 iocall[IOCALL_CLOSE], 1, tmp);
1203 gfc_add_expr_to_block (&block, tmp);
1205 gfc_add_block_to_block (&block, &post_block);
1207 io_result (&block, var, p->err, NULL, NULL);
1209 return gfc_finish_block (&block);
1213 /* Common subroutine for building a file positioning statement. */
1215 static tree
1216 build_filepos (tree function, gfc_code * code)
1218 stmtblock_t block, post_block;
1219 gfc_filepos *p;
1220 tree tmp, var;
1221 unsigned int mask = 0;
1223 p = code->ext.filepos;
1225 gfc_start_block (&block);
1226 gfc_init_block (&post_block);
1228 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
1229 "filepos_parm");
1231 set_error_locus (&block, var, &code->loc);
1233 if (p->iomsg)
1234 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1235 p->iomsg);
1237 if (p->iostat)
1238 mask |= set_parameter_ref (&block, &post_block, var,
1239 IOPARM_common_iostat, p->iostat);
1241 if (p->err)
1242 mask |= IOPARM_common_err;
1244 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1246 if (p->unit)
1247 set_parameter_value_chk (&block, p->iostat, var, IOPARM_common_unit,
1248 p->unit);
1249 else
1250 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1252 tmp = gfc_build_addr_expr (NULL_TREE, var);
1253 tmp = build_call_expr_loc (input_location,
1254 function, 1, tmp);
1255 gfc_add_expr_to_block (&block, tmp);
1257 gfc_add_block_to_block (&block, &post_block);
1259 io_result (&block, var, p->err, NULL, NULL);
1261 return gfc_finish_block (&block);
1265 /* Translate a BACKSPACE statement. */
1267 tree
1268 gfc_trans_backspace (gfc_code * code)
1270 return build_filepos (iocall[IOCALL_BACKSPACE], code);
1274 /* Translate an ENDFILE statement. */
1276 tree
1277 gfc_trans_endfile (gfc_code * code)
1279 return build_filepos (iocall[IOCALL_ENDFILE], code);
1283 /* Translate a REWIND statement. */
1285 tree
1286 gfc_trans_rewind (gfc_code * code)
1288 return build_filepos (iocall[IOCALL_REWIND], code);
1292 /* Translate a FLUSH statement. */
1294 tree
1295 gfc_trans_flush (gfc_code * code)
1297 return build_filepos (iocall[IOCALL_FLUSH], code);
1301 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
1303 tree
1304 gfc_trans_inquire (gfc_code * code)
1306 stmtblock_t block, post_block;
1307 gfc_inquire *p;
1308 tree tmp, var;
1309 unsigned int mask = 0, mask2 = 0;
1311 gfc_start_block (&block);
1312 gfc_init_block (&post_block);
1314 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1315 "inquire_parm");
1317 set_error_locus (&block, var, &code->loc);
1318 p = code->ext.inquire;
1320 if (p->iomsg)
1321 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1322 p->iomsg);
1324 if (p->iostat)
1325 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1326 p->iostat);
1328 if (p->err)
1329 mask |= IOPARM_common_err;
1331 /* Sanity check. */
1332 if (p->unit && p->file)
1333 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1335 if (p->file)
1336 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1337 p->file);
1339 if (p->exist)
1340 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1341 p->exist);
1343 if (p->opened)
1344 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1345 p->opened);
1347 if (p->number)
1348 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1349 p->number);
1351 if (p->named)
1352 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1353 p->named);
1355 if (p->name)
1356 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1357 p->name);
1359 if (p->access)
1360 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1361 p->access);
1363 if (p->sequential)
1364 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1365 p->sequential);
1367 if (p->direct)
1368 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1369 p->direct);
1371 if (p->form)
1372 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1373 p->form);
1375 if (p->formatted)
1376 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1377 p->formatted);
1379 if (p->unformatted)
1380 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1381 p->unformatted);
1383 if (p->recl)
1384 mask |= set_parameter_ref (&block, &post_block, var,
1385 IOPARM_inquire_recl_out, p->recl);
1387 if (p->nextrec)
1388 mask |= set_parameter_ref (&block, &post_block, var,
1389 IOPARM_inquire_nextrec, p->nextrec);
1391 if (p->blank)
1392 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1393 p->blank);
1395 if (p->delim)
1396 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1397 p->delim);
1399 if (p->position)
1400 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1401 p->position);
1403 if (p->action)
1404 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1405 p->action);
1407 if (p->read)
1408 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1409 p->read);
1411 if (p->write)
1412 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1413 p->write);
1415 if (p->readwrite)
1416 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1417 p->readwrite);
1419 if (p->pad)
1420 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1421 p->pad);
1423 if (p->convert)
1424 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1425 p->convert);
1427 if (p->strm_pos)
1428 mask |= set_parameter_ref (&block, &post_block, var,
1429 IOPARM_inquire_strm_pos_out, p->strm_pos);
1431 /* The second series of flags. */
1432 if (p->asynchronous)
1433 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_asynchronous,
1434 p->asynchronous);
1436 if (p->decimal)
1437 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_decimal,
1438 p->decimal);
1440 if (p->encoding)
1441 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_encoding,
1442 p->encoding);
1444 if (p->round)
1445 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_round,
1446 p->round);
1448 if (p->sign)
1449 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_sign,
1450 p->sign);
1452 if (p->pending)
1453 mask2 |= set_parameter_ref (&block, &post_block, var,
1454 IOPARM_inquire_pending, p->pending);
1456 if (p->size)
1457 mask2 |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_size,
1458 p->size);
1460 if (p->id)
1461 mask2 |= set_parameter_ref (&block, &post_block,var, IOPARM_inquire_id,
1462 p->id);
1463 if (p->iqstream)
1464 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_iqstream,
1465 p->iqstream);
1467 if (p->share)
1468 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_share,
1469 p->share);
1471 if (p->cc)
1472 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_cc, p->cc);
1474 if (mask2)
1475 mask |= set_parameter_const (&block, var, IOPARM_inquire_flags2, mask2);
1477 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1479 if (p->unit)
1481 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1482 set_parameter_value_inquire (&block, var, IOPARM_common_unit, p->unit);
1484 else
1485 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1487 tmp = gfc_build_addr_expr (NULL_TREE, var);
1488 tmp = build_call_expr_loc (input_location,
1489 iocall[IOCALL_INQUIRE], 1, tmp);
1490 gfc_add_expr_to_block (&block, tmp);
1492 gfc_add_block_to_block (&block, &post_block);
1494 io_result (&block, var, p->err, NULL, NULL);
1496 return gfc_finish_block (&block);
1500 tree
1501 gfc_trans_wait (gfc_code * code)
1503 stmtblock_t block, post_block;
1504 gfc_wait *p;
1505 tree tmp, var;
1506 unsigned int mask = 0;
1508 gfc_start_block (&block);
1509 gfc_init_block (&post_block);
1511 var = gfc_create_var (st_parameter[IOPARM_ptype_wait].type,
1512 "wait_parm");
1514 set_error_locus (&block, var, &code->loc);
1515 p = code->ext.wait;
1517 /* Set parameters here. */
1518 if (p->iomsg)
1519 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1520 p->iomsg);
1522 if (p->iostat)
1523 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1524 p->iostat);
1526 if (p->err)
1527 mask |= IOPARM_common_err;
1529 if (p->id)
1530 mask |= set_parameter_value (&block, var, IOPARM_wait_id, p->id);
1532 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1534 if (p->unit)
1535 set_parameter_value_chk (&block, p->iostat, var, IOPARM_common_unit, p->unit);
1537 tmp = gfc_build_addr_expr (NULL_TREE, var);
1538 tmp = build_call_expr_loc (input_location,
1539 iocall[IOCALL_WAIT], 1, tmp);
1540 gfc_add_expr_to_block (&block, tmp);
1542 gfc_add_block_to_block (&block, &post_block);
1544 io_result (&block, var, p->err, NULL, NULL);
1546 return gfc_finish_block (&block);
1551 /* nml_full_name builds up the fully qualified name of a
1552 derived type component. '+' is used to denote a type extension. */
1554 static char*
1555 nml_full_name (const char* var_name, const char* cmp_name, bool parent)
1557 int full_name_length;
1558 char * full_name;
1560 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1561 full_name = XCNEWVEC (char, full_name_length + 1);
1562 strcpy (full_name, var_name);
1563 full_name = strcat (full_name, parent ? "+" : "%");
1564 full_name = strcat (full_name, cmp_name);
1565 return full_name;
1569 /* nml_get_addr_expr builds an address expression from the
1570 gfc_symbol or gfc_component backend_decl's. An offset is
1571 provided so that the address of an element of an array of
1572 derived types is returned. This is used in the runtime to
1573 determine that span of the derived type. */
1575 static tree
1576 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1577 tree base_addr)
1579 tree decl = NULL_TREE;
1580 tree tmp;
1582 if (sym)
1584 sym->attr.referenced = 1;
1585 decl = gfc_get_symbol_decl (sym);
1587 /* If this is the enclosing function declaration, use
1588 the fake result instead. */
1589 if (decl == current_function_decl)
1590 decl = gfc_get_fake_result_decl (sym, 0);
1591 else if (decl == DECL_CONTEXT (current_function_decl))
1592 decl = gfc_get_fake_result_decl (sym, 1);
1594 else
1595 decl = c->backend_decl;
1597 gcc_assert (decl && (TREE_CODE (decl) == FIELD_DECL
1598 || VAR_P (decl)
1599 || TREE_CODE (decl) == PARM_DECL
1600 || TREE_CODE (decl) == COMPONENT_REF));
1602 tmp = decl;
1604 /* Build indirect reference, if dummy argument. */
1606 if (POINTER_TYPE_P (TREE_TYPE(tmp)))
1607 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1609 /* Treat the component of a derived type, using base_addr for
1610 the derived type. */
1612 if (TREE_CODE (decl) == FIELD_DECL)
1613 tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (tmp),
1614 base_addr, tmp, NULL_TREE);
1616 if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
1617 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_class_data_get (tmp))))
1618 tmp = gfc_class_data_get (tmp);
1620 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
1621 tmp = gfc_conv_array_data (tmp);
1622 else
1624 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1625 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1627 if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1628 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL);
1630 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1631 tmp = build_fold_indirect_ref_loc (input_location,
1632 tmp);
1635 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1637 return tmp;
1641 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1642 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1643 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1645 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1647 static void
1648 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1649 gfc_symbol * sym, gfc_component * c,
1650 tree base_addr)
1652 gfc_typespec * ts = NULL;
1653 gfc_array_spec * as = NULL;
1654 tree addr_expr = NULL;
1655 tree dt = NULL;
1656 tree string;
1657 tree tmp;
1658 tree dtype;
1659 tree dt_parm_addr;
1660 tree decl = NULL_TREE;
1661 tree gfc_int4_type_node = gfc_get_int_type (4);
1662 tree dtio_proc = null_pointer_node;
1663 tree vtable = null_pointer_node;
1664 int n_dim;
1665 int itype;
1666 int rank = 0;
1668 gcc_assert (sym || c);
1670 /* Build the namelist object name. */
1672 string = gfc_build_cstring_const (var_name);
1673 string = gfc_build_addr_expr (pchar_type_node, string);
1675 /* Build ts, as and data address using symbol or component. */
1677 ts = sym ? &sym->ts : &c->ts;
1679 if (ts->type != BT_CLASS)
1680 as = sym ? sym->as : c->as;
1681 else
1682 as = sym ? CLASS_DATA (sym)->as : CLASS_DATA (c)->as;
1684 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1686 if (as)
1687 rank = as->rank;
1689 if (rank)
1691 decl = sym ? sym->backend_decl : c->backend_decl;
1692 if (sym && sym->attr.dummy)
1693 decl = build_fold_indirect_ref_loc (input_location, decl);
1695 if (ts->type == BT_CLASS)
1696 decl = gfc_class_data_get (decl);
1697 dt = TREE_TYPE (decl);
1698 dtype = gfc_get_dtype (dt);
1700 else
1702 itype = ts->type;
1703 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1706 /* Build up the arguments for the transfer call.
1707 The call for the scalar part transfers:
1708 (address, name, type, kind or string_length, dtype) */
1710 dt_parm_addr = gfc_build_addr_expr (NULL_TREE, dt_parm);
1712 /* Check if the derived type has a specific DTIO for the mode.
1713 Note that although namelist io is forbidden to have a format
1714 list, the specific subroutine is of the formatted kind. */
1715 if (ts->type == BT_DERIVED || ts->type == BT_CLASS)
1717 gfc_symbol *derived;
1718 if (ts->type==BT_CLASS)
1719 derived = ts->u.derived->components->ts.u.derived;
1720 else
1721 derived = ts->u.derived;
1723 gfc_symtree *tb_io_st = gfc_find_typebound_dtio_proc (derived,
1724 last_dt == WRITE, true);
1726 if (ts->type == BT_CLASS && tb_io_st)
1728 // polymorphic DTIO call (based on the dynamic type)
1729 gfc_se se;
1730 gfc_symtree *st = gfc_find_symtree (sym->ns->sym_root, sym->name);
1731 // build vtable expr
1732 gfc_expr *expr = gfc_get_variable_expr (st);
1733 gfc_add_vptr_component (expr);
1734 gfc_init_se (&se, NULL);
1735 se.want_pointer = 1;
1736 gfc_conv_expr (&se, expr);
1737 vtable = se.expr;
1738 // build dtio expr
1739 gfc_add_component_ref (expr,
1740 tb_io_st->n.tb->u.generic->specific_st->name);
1741 gfc_init_se (&se, NULL);
1742 se.want_pointer = 1;
1743 gfc_conv_expr (&se, expr);
1744 gfc_free_expr (expr);
1745 dtio_proc = se.expr;
1747 else
1749 // non-polymorphic DTIO call (based on the declared type)
1750 gfc_symbol *dtio_sub = gfc_find_specific_dtio_proc (derived,
1751 last_dt == WRITE, true);
1752 if (dtio_sub != NULL)
1754 dtio_proc = gfc_get_symbol_decl (dtio_sub);
1755 dtio_proc = gfc_build_addr_expr (NULL, dtio_proc);
1756 gfc_symbol *vtab = gfc_find_derived_vtab (derived);
1757 vtable = vtab->backend_decl;
1758 if (vtable == NULL_TREE)
1759 vtable = gfc_get_symbol_decl (vtab);
1760 vtable = gfc_build_addr_expr (pvoid_type_node, vtable);
1765 if (ts->type == BT_CHARACTER)
1766 tmp = ts->u.cl->backend_decl;
1767 else
1768 tmp = build_int_cst (gfc_charlen_type_node, 0);
1770 if (dtio_proc == null_pointer_node)
1771 tmp = build_call_expr_loc (input_location,
1772 iocall[IOCALL_SET_NML_VAL], 6,
1773 dt_parm_addr, addr_expr, string,
1774 build_int_cst (gfc_int4_type_node, ts->kind),
1775 tmp, dtype);
1776 else
1777 tmp = build_call_expr_loc (input_location,
1778 iocall[IOCALL_SET_NML_DTIO_VAL], 8,
1779 dt_parm_addr, addr_expr, string,
1780 build_int_cst (gfc_int4_type_node, ts->kind),
1781 tmp, dtype, dtio_proc, vtable);
1782 gfc_add_expr_to_block (block, tmp);
1784 /* If the object is an array, transfer rank times:
1785 (null pointer, name, stride, lbound, ubound) */
1787 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1789 tmp = build_call_expr_loc (input_location,
1790 iocall[IOCALL_SET_NML_VAL_DIM], 5,
1791 dt_parm_addr,
1792 build_int_cst (gfc_int4_type_node, n_dim),
1793 gfc_conv_array_stride (decl, n_dim),
1794 gfc_conv_array_lbound (decl, n_dim),
1795 gfc_conv_array_ubound (decl, n_dim));
1796 gfc_add_expr_to_block (block, tmp);
1799 if (gfc_bt_struct (ts->type) && ts->u.derived->components
1800 && dtio_proc == null_pointer_node)
1802 gfc_component *cmp;
1804 /* Provide the RECORD_TYPE to build component references. */
1806 tree expr = build_fold_indirect_ref_loc (input_location,
1807 addr_expr);
1809 for (cmp = ts->u.derived->components; cmp; cmp = cmp->next)
1811 char *full_name = nml_full_name (var_name, cmp->name,
1812 ts->u.derived->attr.extension);
1813 transfer_namelist_element (block,
1814 full_name,
1815 NULL, cmp, expr);
1816 free (full_name);
1821 #undef IARG
1823 /* Create a data transfer statement. Not all of the fields are valid
1824 for both reading and writing, but improper use has been filtered
1825 out by now. */
1827 static tree
1828 build_dt (tree function, gfc_code * code)
1830 stmtblock_t block, post_block, post_end_block, post_iu_block;
1831 gfc_dt *dt;
1832 tree tmp, var;
1833 gfc_expr *nmlname;
1834 gfc_namelist *nml;
1835 unsigned int mask = 0;
1837 gfc_start_block (&block);
1838 gfc_init_block (&post_block);
1839 gfc_init_block (&post_end_block);
1840 gfc_init_block (&post_iu_block);
1842 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1844 set_error_locus (&block, var, &code->loc);
1846 if (last_dt == IOLENGTH)
1848 gfc_inquire *inq;
1850 inq = code->ext.inquire;
1852 /* First check that preconditions are met. */
1853 gcc_assert (inq != NULL);
1854 gcc_assert (inq->iolength != NULL);
1856 /* Connect to the iolength variable. */
1857 mask |= set_parameter_ref (&block, &post_end_block, var,
1858 IOPARM_dt_iolength, inq->iolength);
1859 dt = NULL;
1861 else
1863 dt = code->ext.dt;
1864 gcc_assert (dt != NULL);
1867 if (dt && dt->io_unit)
1869 if (dt->io_unit->ts.type == BT_CHARACTER)
1871 mask |= set_internal_unit (&block, &post_iu_block,
1872 var, dt->io_unit);
1873 set_parameter_const (&block, var, IOPARM_common_unit,
1874 dt->io_unit->ts.kind == 1 ?
1875 GFC_INTERNAL_UNIT : GFC_INTERNAL_UNIT4);
1878 else
1879 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1881 if (dt)
1883 if (dt->iomsg)
1884 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1885 dt->iomsg);
1887 if (dt->iostat)
1888 mask |= set_parameter_ref (&block, &post_end_block, var,
1889 IOPARM_common_iostat, dt->iostat);
1891 if (dt->err)
1892 mask |= IOPARM_common_err;
1894 if (dt->eor)
1895 mask |= IOPARM_common_eor;
1897 if (dt->end)
1898 mask |= IOPARM_common_end;
1900 if (dt->id)
1901 mask |= set_parameter_ref (&block, &post_end_block, var,
1902 IOPARM_dt_id, dt->id);
1904 if (dt->pos)
1905 mask |= set_parameter_value (&block, var, IOPARM_dt_pos, dt->pos);
1907 if (dt->asynchronous)
1908 mask |= set_string (&block, &post_block, var,
1909 IOPARM_dt_asynchronous, dt->asynchronous);
1911 if (dt->blank)
1912 mask |= set_string (&block, &post_block, var, IOPARM_dt_blank,
1913 dt->blank);
1915 if (dt->decimal)
1916 mask |= set_string (&block, &post_block, var, IOPARM_dt_decimal,
1917 dt->decimal);
1919 if (dt->delim)
1920 mask |= set_string (&block, &post_block, var, IOPARM_dt_delim,
1921 dt->delim);
1923 if (dt->pad)
1924 mask |= set_string (&block, &post_block, var, IOPARM_dt_pad,
1925 dt->pad);
1927 if (dt->round)
1928 mask |= set_string (&block, &post_block, var, IOPARM_dt_round,
1929 dt->round);
1931 if (dt->sign)
1932 mask |= set_string (&block, &post_block, var, IOPARM_dt_sign,
1933 dt->sign);
1935 if (dt->rec)
1936 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1938 if (dt->advance)
1939 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1940 dt->advance);
1942 if (dt->format_expr)
1943 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1944 dt->format_expr);
1946 if (dt->format_label)
1948 if (dt->format_label == &format_asterisk)
1949 mask |= IOPARM_dt_list_format;
1950 else
1951 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1952 dt->format_label->format);
1955 if (dt->size)
1956 mask |= set_parameter_ref (&block, &post_end_block, var,
1957 IOPARM_dt_size, dt->size);
1959 if (dt->udtio)
1960 mask |= IOPARM_dt_dtio;
1962 if (dt->default_exp)
1963 mask |= IOPARM_dt_default_exp;
1965 if (dt->namelist)
1967 if (dt->format_expr || dt->format_label)
1968 gfc_internal_error ("build_dt: format with namelist");
1970 nmlname = gfc_get_character_expr (gfc_default_character_kind, NULL,
1971 dt->namelist->name,
1972 strlen (dt->namelist->name));
1974 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1975 nmlname);
1977 gfc_free_expr (nmlname);
1979 if (last_dt == READ)
1980 mask |= IOPARM_dt_namelist_read_mode;
1982 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1984 dt_parm = var;
1986 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1987 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1988 NULL, NULL_TREE);
1990 else
1991 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1993 if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER)
1994 set_parameter_value_chk (&block, dt->iostat, var,
1995 IOPARM_common_unit, dt->io_unit);
1997 else
1998 set_parameter_const (&block, var, IOPARM_common_flags, mask);
2000 tmp = gfc_build_addr_expr (NULL_TREE, var);
2001 tmp = build_call_expr_loc (UNKNOWN_LOCATION,
2002 function, 1, tmp);
2003 gfc_add_expr_to_block (&block, tmp);
2005 gfc_add_block_to_block (&block, &post_block);
2007 dt_parm = var;
2008 dt_post_end_block = &post_end_block;
2010 /* Set implied do loop exit condition. */
2011 if (last_dt == READ || last_dt == WRITE)
2013 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
2015 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2016 st_parameter[IOPARM_ptype_common].type,
2017 dt_parm, TYPE_FIELDS (TREE_TYPE (dt_parm)),
2018 NULL_TREE);
2019 tmp = fold_build3_loc (input_location, COMPONENT_REF,
2020 TREE_TYPE (p->field), tmp, p->field, NULL_TREE);
2021 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (tmp),
2022 tmp, build_int_cst (TREE_TYPE (tmp),
2023 IOPARM_common_libreturn_mask));
2025 else /* IOLENGTH */
2026 tmp = NULL_TREE;
2028 gfc_add_expr_to_block (&block, gfc_trans_code_cond (code->block->next, tmp));
2030 gfc_add_block_to_block (&block, &post_iu_block);
2032 dt_parm = NULL;
2033 dt_post_end_block = NULL;
2035 return gfc_finish_block (&block);
2039 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
2040 this as a third sort of data transfer statement, except that
2041 lengths are summed instead of actually transferring any data. */
2043 tree
2044 gfc_trans_iolength (gfc_code * code)
2046 last_dt = IOLENGTH;
2047 return build_dt (iocall[IOCALL_IOLENGTH], code);
2051 /* Translate a READ statement. */
2053 tree
2054 gfc_trans_read (gfc_code * code)
2056 last_dt = READ;
2057 return build_dt (iocall[IOCALL_READ], code);
2061 /* Translate a WRITE statement */
2063 tree
2064 gfc_trans_write (gfc_code * code)
2066 last_dt = WRITE;
2067 return build_dt (iocall[IOCALL_WRITE], code);
2071 /* Finish a data transfer statement. */
2073 tree
2074 gfc_trans_dt_end (gfc_code * code)
2076 tree function, tmp;
2077 stmtblock_t block;
2079 gfc_init_block (&block);
2081 switch (last_dt)
2083 case READ:
2084 function = iocall[IOCALL_READ_DONE];
2085 break;
2087 case WRITE:
2088 function = iocall[IOCALL_WRITE_DONE];
2089 break;
2091 case IOLENGTH:
2092 function = iocall[IOCALL_IOLENGTH_DONE];
2093 break;
2095 default:
2096 gcc_unreachable ();
2099 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2100 tmp = build_call_expr_loc (input_location,
2101 function, 1, tmp);
2102 gfc_add_expr_to_block (&block, tmp);
2103 gfc_add_block_to_block (&block, dt_post_end_block);
2104 gfc_init_block (dt_post_end_block);
2106 if (last_dt != IOLENGTH)
2108 gcc_assert (code->ext.dt != NULL);
2109 io_result (&block, dt_parm, code->ext.dt->err,
2110 code->ext.dt->end, code->ext.dt->eor);
2113 return gfc_finish_block (&block);
2116 static void
2117 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr,
2118 gfc_code * code, tree vptr);
2120 /* Given an array field in a derived type variable, generate the code
2121 for the loop that iterates over array elements, and the code that
2122 accesses those array elements. Use transfer_expr to generate code
2123 for transferring that element. Because elements may also be
2124 derived types, transfer_expr and transfer_array_component are mutually
2125 recursive. */
2127 static tree
2128 transfer_array_component (tree expr, gfc_component * cm, locus * where)
2130 tree tmp;
2131 stmtblock_t body;
2132 stmtblock_t block;
2133 gfc_loopinfo loop;
2134 int n;
2135 gfc_ss *ss;
2136 gfc_se se;
2137 gfc_array_info *ss_array;
2139 gfc_start_block (&block);
2140 gfc_init_se (&se, NULL);
2142 /* Create and initialize Scalarization Status. Unlike in
2143 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
2144 care of this task, because we don't have a gfc_expr at hand.
2145 Build one manually, as in gfc_trans_subarray_assign. */
2147 ss = gfc_get_array_ss (gfc_ss_terminator, NULL, cm->as->rank,
2148 GFC_SS_COMPONENT);
2149 ss_array = &ss->info->data.array;
2150 ss_array->shape = gfc_get_shape (cm->as->rank);
2151 ss_array->descriptor = expr;
2152 ss_array->data = gfc_conv_array_data (expr);
2153 ss_array->offset = gfc_conv_array_offset (expr);
2154 for (n = 0; n < cm->as->rank; n++)
2156 ss_array->start[n] = gfc_conv_array_lbound (expr, n);
2157 ss_array->stride[n] = gfc_index_one_node;
2159 mpz_init (ss_array->shape[n]);
2160 mpz_sub (ss_array->shape[n], cm->as->upper[n]->value.integer,
2161 cm->as->lower[n]->value.integer);
2162 mpz_add_ui (ss_array->shape[n], ss_array->shape[n], 1);
2165 /* Once we got ss, we use scalarizer to create the loop. */
2167 gfc_init_loopinfo (&loop);
2168 gfc_add_ss_to_loop (&loop, ss);
2169 gfc_conv_ss_startstride (&loop);
2170 gfc_conv_loop_setup (&loop, where);
2171 gfc_mark_ss_chain_used (ss, 1);
2172 gfc_start_scalarized_body (&loop, &body);
2174 gfc_copy_loopinfo_to_se (&se, &loop);
2175 se.ss = ss;
2177 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
2178 se.expr = expr;
2179 gfc_conv_tmp_array_ref (&se);
2181 /* Now se.expr contains an element of the array. Take the address and pass
2182 it to the IO routines. */
2183 tmp = gfc_build_addr_expr (NULL_TREE, se.expr);
2184 transfer_expr (&se, &cm->ts, tmp, NULL, NULL_TREE);
2186 /* We are done now with the loop body. Wrap up the scalarizer and
2187 return. */
2189 gfc_add_block_to_block (&body, &se.pre);
2190 gfc_add_block_to_block (&body, &se.post);
2192 gfc_trans_scalarizing_loops (&loop, &body);
2194 gfc_add_block_to_block (&block, &loop.pre);
2195 gfc_add_block_to_block (&block, &loop.post);
2197 gcc_assert (ss_array->shape != NULL);
2198 gfc_free_shape (&ss_array->shape, cm->as->rank);
2199 gfc_cleanup_loop (&loop);
2201 return gfc_finish_block (&block);
2205 /* Helper function for transfer_expr that looks for the DTIO procedure
2206 either as a typebound binding or in a generic interface. If present,
2207 the address expression of the procedure is returned. It is assumed
2208 that the procedure interface has been checked during resolution. */
2210 static tree
2211 get_dtio_proc (gfc_typespec * ts, gfc_code * code, gfc_symbol **dtio_sub)
2213 gfc_symbol *derived;
2214 bool formatted = false;
2215 gfc_dt *dt = code->ext.dt;
2217 if (dt)
2219 char *fmt = NULL;
2221 if (dt->format_label == &format_asterisk)
2223 /* List directed io must call the formatted DTIO procedure. */
2224 formatted = true;
2226 else if (dt->format_expr)
2227 fmt = gfc_widechar_to_char (dt->format_expr->value.character.string,
2228 -1);
2229 else if (dt->format_label)
2230 fmt = gfc_widechar_to_char (dt->format_label->format->value.character.string,
2231 -1);
2232 if (fmt && strtok (fmt, "DT") != NULL)
2233 formatted = true;
2237 if (ts->type == BT_CLASS)
2238 derived = ts->u.derived->components->ts.u.derived;
2239 else
2240 derived = ts->u.derived;
2242 gfc_symtree *tb_io_st = gfc_find_typebound_dtio_proc (derived,
2243 last_dt == WRITE, formatted);
2244 if (ts->type == BT_CLASS && tb_io_st)
2246 // polymorphic DTIO call (based on the dynamic type)
2247 gfc_se se;
2248 gfc_expr *expr = gfc_find_and_cut_at_last_class_ref (code->expr1);
2249 gfc_add_vptr_component (expr);
2250 gfc_add_component_ref (expr,
2251 tb_io_st->n.tb->u.generic->specific_st->name);
2252 *dtio_sub = tb_io_st->n.tb->u.generic->specific->u.specific->n.sym;
2253 gfc_init_se (&se, NULL);
2254 se.want_pointer = 1;
2255 gfc_conv_expr (&se, expr);
2256 gfc_free_expr (expr);
2257 return se.expr;
2259 else
2261 // non-polymorphic DTIO call (based on the declared type)
2262 *dtio_sub = gfc_find_specific_dtio_proc (derived, last_dt == WRITE,
2263 formatted);
2265 if (*dtio_sub)
2266 return gfc_build_addr_expr (NULL, gfc_get_symbol_decl (*dtio_sub));
2269 return NULL_TREE;
2272 /* Generate the call for a scalar transfer node. */
2274 static void
2275 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr,
2276 gfc_code * code, tree vptr)
2278 tree tmp, function, arg2, arg3, field, expr;
2279 gfc_component *c;
2280 int kind;
2282 /* It is possible to get a C_NULL_PTR or C_NULL_FUNPTR expression here if
2283 the user says something like: print *, 'c_null_ptr: ', c_null_ptr
2284 We need to translate the expression to a constant if it's either
2285 C_NULL_PTR or C_NULL_FUNPTR. We could also get a user variable of
2286 type C_PTR or C_FUNPTR, in which case the ts->type may no longer be
2287 BT_DERIVED (could have been changed by gfc_conv_expr). */
2288 if ((ts->type == BT_DERIVED || ts->type == BT_INTEGER)
2289 && ts->u.derived != NULL
2290 && (ts->is_iso_c == 1 || ts->u.derived->ts.is_iso_c == 1))
2292 ts->type = BT_INTEGER;
2293 ts->kind = gfc_index_integer_kind;
2296 kind = ts->kind;
2297 function = NULL;
2298 arg2 = NULL;
2299 arg3 = NULL;
2301 switch (ts->type)
2303 case BT_INTEGER:
2304 arg2 = build_int_cst (integer_type_node, kind);
2305 if (last_dt == READ)
2306 function = iocall[IOCALL_X_INTEGER];
2307 else
2308 function = iocall[IOCALL_X_INTEGER_WRITE];
2310 break;
2312 case BT_REAL:
2313 arg2 = build_int_cst (integer_type_node, kind);
2314 if (last_dt == READ)
2316 if (gfc_real16_is_float128 && ts->kind == 16)
2317 function = iocall[IOCALL_X_REAL128];
2318 else
2319 function = iocall[IOCALL_X_REAL];
2321 else
2323 if (gfc_real16_is_float128 && ts->kind == 16)
2324 function = iocall[IOCALL_X_REAL128_WRITE];
2325 else
2326 function = iocall[IOCALL_X_REAL_WRITE];
2329 break;
2331 case BT_COMPLEX:
2332 arg2 = build_int_cst (integer_type_node, kind);
2333 if (last_dt == READ)
2335 if (gfc_real16_is_float128 && ts->kind == 16)
2336 function = iocall[IOCALL_X_COMPLEX128];
2337 else
2338 function = iocall[IOCALL_X_COMPLEX];
2340 else
2342 if (gfc_real16_is_float128 && ts->kind == 16)
2343 function = iocall[IOCALL_X_COMPLEX128_WRITE];
2344 else
2345 function = iocall[IOCALL_X_COMPLEX_WRITE];
2348 break;
2350 case BT_LOGICAL:
2351 arg2 = build_int_cst (integer_type_node, kind);
2352 if (last_dt == READ)
2353 function = iocall[IOCALL_X_LOGICAL];
2354 else
2355 function = iocall[IOCALL_X_LOGICAL_WRITE];
2357 break;
2359 case BT_CHARACTER:
2360 if (kind == 4)
2362 if (se->string_length)
2363 arg2 = se->string_length;
2364 else
2366 tmp = build_fold_indirect_ref_loc (input_location,
2367 addr_expr);
2368 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2369 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2370 arg2 = fold_convert (gfc_charlen_type_node, arg2);
2372 arg3 = build_int_cst (integer_type_node, kind);
2373 if (last_dt == READ)
2374 function = iocall[IOCALL_X_CHARACTER_WIDE];
2375 else
2376 function = iocall[IOCALL_X_CHARACTER_WIDE_WRITE];
2378 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2379 tmp = build_call_expr_loc (input_location,
2380 function, 4, tmp, addr_expr, arg2, arg3);
2381 gfc_add_expr_to_block (&se->pre, tmp);
2382 gfc_add_block_to_block (&se->pre, &se->post);
2383 return;
2385 /* Fall through. */
2386 case BT_HOLLERITH:
2387 if (se->string_length)
2388 arg2 = se->string_length;
2389 else
2391 tmp = build_fold_indirect_ref_loc (input_location,
2392 addr_expr);
2393 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2394 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2396 if (last_dt == READ)
2397 function = iocall[IOCALL_X_CHARACTER];
2398 else
2399 function = iocall[IOCALL_X_CHARACTER_WRITE];
2401 break;
2403 case_bt_struct:
2404 case BT_CLASS:
2405 if (ts->u.derived->components == NULL)
2406 return;
2407 if (gfc_bt_struct (ts->type) || ts->type == BT_CLASS)
2409 gfc_symbol *derived;
2410 gfc_symbol *dtio_sub = NULL;
2411 /* Test for a specific DTIO subroutine. */
2412 if (ts->type == BT_DERIVED)
2413 derived = ts->u.derived;
2414 else
2415 derived = ts->u.derived->components->ts.u.derived;
2417 if (derived->attr.has_dtio_procs)
2418 arg2 = get_dtio_proc (ts, code, &dtio_sub);
2420 if ((dtio_sub != NULL) && (last_dt != IOLENGTH))
2422 tree decl;
2423 decl = build_fold_indirect_ref_loc (input_location,
2424 se->expr);
2425 /* Remember that the first dummy of the DTIO subroutines
2426 is CLASS(derived) for extensible derived types, so the
2427 conversion must be done here for derived type and for
2428 scalarized CLASS array element io-list objects. */
2429 if ((ts->type == BT_DERIVED
2430 && !(ts->u.derived->attr.sequence
2431 || ts->u.derived->attr.is_bind_c))
2432 || (ts->type == BT_CLASS
2433 && !GFC_CLASS_TYPE_P (TREE_TYPE (decl))))
2434 gfc_conv_derived_to_class (se, code->expr1,
2435 dtio_sub->formal->sym->ts,
2436 vptr, false, false);
2437 addr_expr = se->expr;
2438 function = iocall[IOCALL_X_DERIVED];
2439 break;
2441 else if (gfc_bt_struct (ts->type))
2443 /* Recurse into the elements of the derived type. */
2444 expr = gfc_evaluate_now (addr_expr, &se->pre);
2445 expr = build_fold_indirect_ref_loc (input_location,
2446 expr);
2448 /* Make sure that the derived type has been built. An external
2449 function, if only referenced in an io statement, requires this
2450 check (see PR58771). */
2451 if (ts->u.derived->backend_decl == NULL_TREE)
2452 (void) gfc_typenode_for_spec (ts);
2454 for (c = ts->u.derived->components; c; c = c->next)
2456 field = c->backend_decl;
2457 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2459 tmp = fold_build3_loc (UNKNOWN_LOCATION,
2460 COMPONENT_REF, TREE_TYPE (field),
2461 expr, field, NULL_TREE);
2463 if (c->attr.dimension)
2465 tmp = transfer_array_component (tmp, c, & code->loc);
2466 gfc_add_expr_to_block (&se->pre, tmp);
2468 else
2470 if (!c->attr.pointer)
2471 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2472 transfer_expr (se, &c->ts, tmp, code, NULL_TREE);
2475 return;
2477 /* If a CLASS object gets through to here, fall through and ICE. */
2479 gcc_fallthrough ();
2480 default:
2481 gfc_internal_error ("Bad IO basetype (%d)", ts->type);
2484 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2485 tmp = build_call_expr_loc (input_location,
2486 function, 3, tmp, addr_expr, arg2);
2487 gfc_add_expr_to_block (&se->pre, tmp);
2488 gfc_add_block_to_block (&se->pre, &se->post);
2493 /* Generate a call to pass an array descriptor to the IO library. The
2494 array should be of one of the intrinsic types. */
2496 static void
2497 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
2499 tree tmp, charlen_arg, kind_arg, io_call;
2501 if (ts->type == BT_CHARACTER)
2502 charlen_arg = se->string_length;
2503 else
2504 charlen_arg = build_int_cst (gfc_charlen_type_node, 0);
2506 kind_arg = build_int_cst (integer_type_node, ts->kind);
2508 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2509 if (last_dt == READ)
2510 io_call = iocall[IOCALL_X_ARRAY];
2511 else
2512 io_call = iocall[IOCALL_X_ARRAY_WRITE];
2514 tmp = build_call_expr_loc (UNKNOWN_LOCATION,
2515 io_call, 4,
2516 tmp, addr_expr, kind_arg, charlen_arg);
2517 gfc_add_expr_to_block (&se->pre, tmp);
2518 gfc_add_block_to_block (&se->pre, &se->post);
2522 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
2524 tree
2525 gfc_trans_transfer (gfc_code * code)
2527 stmtblock_t block, body;
2528 gfc_loopinfo loop;
2529 gfc_expr *expr;
2530 gfc_ref *ref;
2531 gfc_ss *ss;
2532 gfc_se se;
2533 tree tmp;
2534 tree vptr;
2535 int n;
2537 gfc_start_block (&block);
2538 gfc_init_block (&body);
2540 expr = code->expr1;
2541 ref = NULL;
2542 gfc_init_se (&se, NULL);
2544 if (expr->rank == 0)
2546 /* Transfer a scalar value. */
2547 if (expr->ts.type == BT_CLASS)
2549 se.want_pointer = 1;
2550 gfc_conv_expr (&se, expr);
2551 vptr = gfc_get_vptr_from_expr (se.expr);
2553 else
2555 vptr = NULL_TREE;
2556 gfc_conv_expr_reference (&se, expr);
2558 transfer_expr (&se, &expr->ts, se.expr, code, vptr);
2560 else
2562 /* Transfer an array. If it is an array of an intrinsic
2563 type, pass the descriptor to the library. Otherwise
2564 scalarize the transfer. */
2565 if (expr->ref && !gfc_is_proc_ptr_comp (expr))
2567 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
2568 ref = ref->next);
2569 gcc_assert (ref && ref->type == REF_ARRAY);
2572 if (expr->ts.type != BT_CLASS
2573 && expr->expr_type == EXPR_VARIABLE
2574 && gfc_expr_attr (expr).pointer)
2575 goto scalarize;
2578 if (!(gfc_bt_struct (expr->ts.type)
2579 || expr->ts.type == BT_CLASS)
2580 && ref && ref->next == NULL
2581 && !is_subref_array (expr))
2583 bool seen_vector = false;
2585 if (ref && ref->u.ar.type == AR_SECTION)
2587 for (n = 0; n < ref->u.ar.dimen; n++)
2588 if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
2590 seen_vector = true;
2591 break;
2595 if (seen_vector && last_dt == READ)
2597 /* Create a temp, read to that and copy it back. */
2598 gfc_conv_subref_array_arg (&se, expr, 0, INTENT_OUT, false);
2599 tmp = se.expr;
2601 else
2603 /* Get the descriptor. */
2604 gfc_conv_expr_descriptor (&se, expr);
2605 tmp = gfc_build_addr_expr (NULL_TREE, se.expr);
2608 transfer_array_desc (&se, &expr->ts, tmp);
2609 goto finish_block_label;
2612 scalarize:
2613 /* Initialize the scalarizer. */
2614 ss = gfc_walk_expr (expr);
2615 gfc_init_loopinfo (&loop);
2616 gfc_add_ss_to_loop (&loop, ss);
2618 /* Initialize the loop. */
2619 gfc_conv_ss_startstride (&loop);
2620 gfc_conv_loop_setup (&loop, &code->expr1->where);
2622 /* The main loop body. */
2623 gfc_mark_ss_chain_used (ss, 1);
2624 gfc_start_scalarized_body (&loop, &body);
2626 gfc_copy_loopinfo_to_se (&se, &loop);
2627 se.ss = ss;
2629 gfc_conv_expr_reference (&se, expr);
2631 if (expr->ts.type == BT_CLASS)
2632 vptr = gfc_get_vptr_from_expr (ss->info->data.array.descriptor);
2633 else
2634 vptr = NULL_TREE;
2635 transfer_expr (&se, &expr->ts, se.expr, code, vptr);
2638 finish_block_label:
2640 gfc_add_block_to_block (&body, &se.pre);
2641 gfc_add_block_to_block (&body, &se.post);
2643 if (se.ss == NULL)
2644 tmp = gfc_finish_block (&body);
2645 else
2647 gcc_assert (expr->rank != 0);
2648 gcc_assert (se.ss == gfc_ss_terminator);
2649 gfc_trans_scalarizing_loops (&loop, &body);
2651 gfc_add_block_to_block (&loop.pre, &loop.post);
2652 tmp = gfc_finish_block (&loop.pre);
2653 gfc_cleanup_loop (&loop);
2656 gfc_add_expr_to_block (&block, tmp);
2658 return gfc_finish_block (&block);
2661 #include "gt-fortran-trans-io.h"