2008-01-22 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans-io.c
blob1e124154a4add3597e27afb26f768f1c002da618
1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software
3 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 "tree-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_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 gfc_st_parameter_field GTY(())
68 const char *name;
69 unsigned int mask;
70 enum ioparam_type param_type;
71 enum iofield_type type;
72 tree field;
73 tree field_len;
75 gfc_st_parameter_field;
77 typedef struct gfc_st_parameter GTY(())
79 const char *name;
80 tree type;
82 gfc_st_parameter;
84 enum iofield
86 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
87 #include "ioparm.def"
88 #undef IOPARM
89 IOPARM_field_num
92 static GTY(()) gfc_st_parameter st_parameter[] =
94 { "common", NULL },
95 { "open", NULL },
96 { "close", NULL },
97 { "filepos", NULL },
98 { "inquire", NULL },
99 { "dt", NULL }
102 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
104 #define IOPARM(param_type, name, mask, type) \
105 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
106 #include "ioparm.def"
107 #undef IOPARM
108 { NULL, 0, 0, 0, NULL, NULL }
111 /* Library I/O subroutines */
113 enum iocall
115 IOCALL_READ,
116 IOCALL_READ_DONE,
117 IOCALL_WRITE,
118 IOCALL_WRITE_DONE,
119 IOCALL_X_INTEGER,
120 IOCALL_X_LOGICAL,
121 IOCALL_X_CHARACTER,
122 IOCALL_X_REAL,
123 IOCALL_X_COMPLEX,
124 IOCALL_X_ARRAY,
125 IOCALL_OPEN,
126 IOCALL_CLOSE,
127 IOCALL_INQUIRE,
128 IOCALL_IOLENGTH,
129 IOCALL_IOLENGTH_DONE,
130 IOCALL_REWIND,
131 IOCALL_BACKSPACE,
132 IOCALL_ENDFILE,
133 IOCALL_FLUSH,
134 IOCALL_SET_NML_VAL,
135 IOCALL_SET_NML_VAL_DIM,
136 IOCALL_NUM
139 static GTY(()) tree iocall[IOCALL_NUM];
141 /* Variable for keeping track of what the last data transfer statement
142 was. Used for deciding which subroutine to call when the data
143 transfer is complete. */
144 static enum { READ, WRITE, IOLENGTH } last_dt;
146 /* The data transfer parameter block that should be shared by all
147 data transfer calls belonging to the same read/write/iolength. */
148 static GTY(()) tree dt_parm;
149 static stmtblock_t *dt_post_end_block;
151 static void
152 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
154 enum iofield type;
155 gfc_st_parameter_field *p;
156 char name[64];
157 size_t len;
158 tree t = make_node (RECORD_TYPE);
160 len = strlen (st_parameter[ptype].name);
161 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
162 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
163 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
164 len + 1);
165 TYPE_NAME (t) = get_identifier (name);
167 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
168 if (p->param_type == ptype)
169 switch (p->type)
171 case IOPARM_type_int4:
172 case IOPARM_type_intio:
173 case IOPARM_type_pint4:
174 case IOPARM_type_pintio:
175 case IOPARM_type_parray:
176 case IOPARM_type_pchar:
177 case IOPARM_type_pad:
178 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
179 get_identifier (p->name),
180 types[p->type]);
181 break;
182 case IOPARM_type_char1:
183 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
184 get_identifier (p->name),
185 pchar_type_node);
186 /* FALLTHROUGH */
187 case IOPARM_type_char2:
188 len = strlen (p->name);
189 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
190 memcpy (name, p->name, len);
191 memcpy (name + len, "_len", sizeof ("_len"));
192 p->field_len = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
193 get_identifier (name),
194 gfc_charlen_type_node);
195 if (p->type == IOPARM_type_char2)
196 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
197 get_identifier (p->name),
198 pchar_type_node);
199 break;
200 case IOPARM_type_common:
201 p->field
202 = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
203 get_identifier (p->name),
204 st_parameter[IOPARM_ptype_common].type);
205 break;
206 case IOPARM_type_num:
207 gcc_unreachable ();
210 gfc_finish_type (t);
211 st_parameter[ptype].type = t;
215 /* Build code to test an error condition and call generate_error if needed.
216 Note: This builds calls to generate_error in the runtime library function.
217 The function generate_error is dependent on certain parameters in the
218 st_parameter_common flags to be set. (See libgfortran/runtime/error.c)
219 Therefore, the code to set these flags must be generated before
220 this function is used. */
222 void
223 gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
224 const char * msgid, stmtblock_t * pblock)
226 stmtblock_t block;
227 tree body;
228 tree tmp;
229 tree arg1, arg2, arg3;
230 char *message;
232 if (integer_zerop (cond))
233 return;
235 /* The code to generate the error. */
236 gfc_start_block (&block);
238 arg1 = build_fold_addr_expr (var);
240 arg2 = build_int_cst (integer_type_node, error_code),
242 asprintf (&message, "%s", _(msgid));
243 arg3 = gfc_build_addr_expr (pchar_type_node, gfc_build_cstring_const(message));
244 gfc_free(message);
246 tmp = build_call_expr (gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
248 gfc_add_expr_to_block (&block, tmp);
250 body = gfc_finish_block (&block);
252 if (integer_onep (cond))
254 gfc_add_expr_to_block (pblock, body);
256 else
258 /* Tell the compiler that this isn't likely. */
259 cond = fold_convert (long_integer_type_node, cond);
260 tmp = build_int_cst (long_integer_type_node, 0);
261 cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
262 cond = fold_convert (boolean_type_node, cond);
264 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
265 gfc_add_expr_to_block (pblock, tmp);
270 /* Create function decls for IO library functions. */
272 void
273 gfc_build_io_library_fndecls (void)
275 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
276 tree gfc_intio_type_node;
277 tree parm_type, dt_parm_type;
278 HOST_WIDE_INT pad_size;
279 enum ioparam_type ptype;
281 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
282 types[IOPARM_type_intio] = gfc_intio_type_node
283 = gfc_get_int_type (gfc_intio_kind);
284 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
285 types[IOPARM_type_pintio]
286 = build_pointer_type (gfc_intio_type_node);
287 types[IOPARM_type_parray] = pchar_type_node;
288 types[IOPARM_type_pchar] = pchar_type_node;
289 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
290 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
291 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size));
292 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
294 /* pad actually contains pointers and integers so it needs to have an
295 alignment that is at least as large as the needed alignment for those
296 types. See the st_parameter_dt structure in libgfortran/io/io.h for
297 what really goes into this space. */
298 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
299 TYPE_ALIGN (gfc_get_int_type (gfc_max_integer_kind)));
301 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
302 gfc_build_st_parameter (ptype, types);
304 /* Define the transfer functions. */
306 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
308 iocall[IOCALL_X_INTEGER] =
309 gfc_build_library_function_decl (get_identifier
310 (PREFIX("transfer_integer")),
311 void_type_node, 3, dt_parm_type,
312 pvoid_type_node, gfc_int4_type_node);
314 iocall[IOCALL_X_LOGICAL] =
315 gfc_build_library_function_decl (get_identifier
316 (PREFIX("transfer_logical")),
317 void_type_node, 3, dt_parm_type,
318 pvoid_type_node, gfc_int4_type_node);
320 iocall[IOCALL_X_CHARACTER] =
321 gfc_build_library_function_decl (get_identifier
322 (PREFIX("transfer_character")),
323 void_type_node, 3, dt_parm_type,
324 pvoid_type_node, gfc_int4_type_node);
326 iocall[IOCALL_X_REAL] =
327 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
328 void_type_node, 3, dt_parm_type,
329 pvoid_type_node, gfc_int4_type_node);
331 iocall[IOCALL_X_COMPLEX] =
332 gfc_build_library_function_decl (get_identifier
333 (PREFIX("transfer_complex")),
334 void_type_node, 3, dt_parm_type,
335 pvoid_type_node, gfc_int4_type_node);
337 iocall[IOCALL_X_ARRAY] =
338 gfc_build_library_function_decl (get_identifier
339 (PREFIX("transfer_array")),
340 void_type_node, 4, dt_parm_type,
341 pvoid_type_node, integer_type_node,
342 gfc_charlen_type_node);
344 /* Library entry points */
346 iocall[IOCALL_READ] =
347 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
348 void_type_node, 1, dt_parm_type);
350 iocall[IOCALL_WRITE] =
351 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
352 void_type_node, 1, dt_parm_type);
354 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
355 iocall[IOCALL_OPEN] =
356 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
357 void_type_node, 1, parm_type);
360 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
361 iocall[IOCALL_CLOSE] =
362 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
363 void_type_node, 1, parm_type);
365 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
366 iocall[IOCALL_INQUIRE] =
367 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
368 gfc_int4_type_node, 1, parm_type);
370 iocall[IOCALL_IOLENGTH] =
371 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
372 void_type_node, 1, dt_parm_type);
374 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
375 iocall[IOCALL_REWIND] =
376 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
377 gfc_int4_type_node, 1, parm_type);
379 iocall[IOCALL_BACKSPACE] =
380 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
381 gfc_int4_type_node, 1, parm_type);
383 iocall[IOCALL_ENDFILE] =
384 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
385 gfc_int4_type_node, 1, parm_type);
387 iocall[IOCALL_FLUSH] =
388 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
389 gfc_int4_type_node, 1, parm_type);
391 /* Library helpers */
393 iocall[IOCALL_READ_DONE] =
394 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
395 gfc_int4_type_node, 1, dt_parm_type);
397 iocall[IOCALL_WRITE_DONE] =
398 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
399 gfc_int4_type_node, 1, dt_parm_type);
401 iocall[IOCALL_IOLENGTH_DONE] =
402 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
403 gfc_int4_type_node, 1, dt_parm_type);
406 iocall[IOCALL_SET_NML_VAL] =
407 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
408 void_type_node, 6, dt_parm_type,
409 pvoid_type_node, pvoid_type_node,
410 gfc_int4_type_node, gfc_charlen_type_node,
411 gfc_int4_type_node);
413 iocall[IOCALL_SET_NML_VAL_DIM] =
414 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
415 void_type_node, 5, dt_parm_type,
416 gfc_int4_type_node, gfc_array_index_type,
417 gfc_array_index_type, gfc_array_index_type);
421 /* Generate code to store an integer constant into the
422 st_parameter_XXX structure. */
424 static unsigned int
425 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
426 unsigned int val)
428 tree tmp;
429 gfc_st_parameter_field *p = &st_parameter_field[type];
431 if (p->param_type == IOPARM_ptype_common)
432 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
433 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
434 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
435 NULL_TREE);
436 gfc_add_modify_expr (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
437 return p->mask;
441 /* Generate code to store a non-string I/O parameter into the
442 st_parameter_XXX structure. This is a pass by value. */
444 static unsigned int
445 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
446 gfc_expr *e)
448 gfc_se se;
449 tree tmp;
450 gfc_st_parameter_field *p = &st_parameter_field[type];
451 tree dest_type = TREE_TYPE (p->field);
453 gfc_init_se (&se, NULL);
454 gfc_conv_expr_val (&se, e);
456 /* If we're storing a UNIT number, we need to check it first. */
457 if (type == IOPARM_common_unit && e->ts.kind != 4)
459 tree cond, max;
460 int i;
462 /* Don't evaluate the UNIT number multiple times. */
463 se.expr = gfc_evaluate_now (se.expr, &se.pre);
465 /* UNIT numbers should be nonnegative. */
466 cond = fold_build2 (LT_EXPR, boolean_type_node, se.expr,
467 build_int_cst (TREE_TYPE (se.expr),0));
468 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
469 "Negative unit number in I/O statement",
470 &se.pre);
472 /* UNIT numbers should be less than the max. */
473 i = gfc_validate_kind (BT_INTEGER, 4, false);
474 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
475 cond = fold_build2 (GT_EXPR, boolean_type_node, se.expr,
476 fold_convert (TREE_TYPE (se.expr), max));
477 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
478 "Unit number in I/O statement too large",
479 &se.pre);
483 se.expr = convert (dest_type, se.expr);
484 gfc_add_block_to_block (block, &se.pre);
486 if (p->param_type == IOPARM_ptype_common)
487 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
488 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
490 tmp = build3 (COMPONENT_REF, dest_type, var, p->field, NULL_TREE);
491 gfc_add_modify_expr (block, tmp, se.expr);
492 return p->mask;
496 /* Generate code to store a non-string I/O parameter into the
497 st_parameter_XXX structure. This is pass by reference. */
499 static unsigned int
500 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
501 tree var, enum iofield type, gfc_expr *e)
503 gfc_se se;
504 tree tmp, addr;
505 gfc_st_parameter_field *p = &st_parameter_field[type];
507 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
508 gfc_init_se (&se, NULL);
509 gfc_conv_expr_lhs (&se, e);
511 gfc_add_block_to_block (block, &se.pre);
513 if (TYPE_MODE (TREE_TYPE (se.expr))
514 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
516 addr = convert (TREE_TYPE (p->field), build_fold_addr_expr (se.expr));
518 /* If this is for the iostat variable initialize the
519 user variable to LIBERROR_OK which is zero. */
520 if (type == IOPARM_common_iostat)
521 gfc_add_modify_expr (block, se.expr,
522 build_int_cst (TREE_TYPE (se.expr), LIBERROR_OK));
524 else
526 /* The type used by the library has different size
527 from the type of the variable supplied by the user.
528 Need to use a temporary. */
529 tree tmpvar = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
530 st_parameter_field[type].name);
532 /* If this is for the iostat variable, initialize the
533 user variable to LIBERROR_OK which is zero. */
534 if (type == IOPARM_common_iostat)
535 gfc_add_modify_expr (block, tmpvar,
536 build_int_cst (TREE_TYPE (tmpvar), LIBERROR_OK));
538 addr = build_fold_addr_expr (tmpvar);
539 /* After the I/O operation, we set the variable from the temporary. */
540 tmp = convert (TREE_TYPE (se.expr), tmpvar);
541 gfc_add_modify_expr (postblock, se.expr, tmp);
544 if (p->param_type == IOPARM_ptype_common)
545 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
546 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
547 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
548 NULL_TREE);
549 gfc_add_modify_expr (block, tmp, addr);
550 return p->mask;
553 /* Given an array expr, find its address and length to get a string. If the
554 array is full, the string's address is the address of array's first element
555 and the length is the size of the whole array. If it is an element, the
556 string's address is the element's address and the length is the rest size of
557 the array.
560 static void
561 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
563 tree tmp;
564 tree array;
565 tree type;
566 tree size;
567 int rank;
568 gfc_symbol *sym;
570 sym = e->symtree->n.sym;
571 rank = sym->as->rank - 1;
573 if (e->ref->u.ar.type == AR_FULL)
575 se->expr = gfc_get_symbol_decl (sym);
576 se->expr = gfc_conv_array_data (se->expr);
578 else
580 gfc_conv_expr (se, e);
583 array = sym->backend_decl;
584 type = TREE_TYPE (array);
586 if (GFC_ARRAY_TYPE_P (type))
587 size = GFC_TYPE_ARRAY_SIZE (type);
588 else
590 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
591 size = gfc_conv_array_stride (array, rank);
592 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
593 gfc_conv_array_ubound (array, rank),
594 gfc_conv_array_lbound (array, rank));
595 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
596 gfc_index_one_node);
597 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
600 gcc_assert (size);
602 /* If it is an element, we need the its address and size of the rest. */
603 if (e->ref->u.ar.type == AR_ELEMENT)
605 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
606 TREE_OPERAND (se->expr, 1));
607 se->expr = build_fold_addr_expr (se->expr);
610 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
611 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
612 fold_convert (gfc_array_index_type, tmp));
614 se->string_length = fold_convert (gfc_charlen_type_node, size);
618 /* Generate code to store a string and its length into the
619 st_parameter_XXX structure. */
621 static unsigned int
622 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
623 enum iofield type, gfc_expr * e)
625 gfc_se se;
626 tree tmp;
627 tree io;
628 tree len;
629 gfc_st_parameter_field *p = &st_parameter_field[type];
631 gfc_init_se (&se, NULL);
633 if (p->param_type == IOPARM_ptype_common)
634 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
635 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
636 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
637 NULL_TREE);
638 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
639 NULL_TREE);
641 /* Integer variable assigned a format label. */
642 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
644 char * msg;
645 tree cond;
647 gfc_conv_label_variable (&se, e);
648 tmp = GFC_DECL_STRING_LEN (se.expr);
649 cond = fold_build2 (LT_EXPR, boolean_type_node,
650 tmp, build_int_cst (TREE_TYPE (tmp), 0));
652 asprintf(&msg, "Label assigned to variable '%s' (%%ld) is not a format "
653 "label", e->symtree->name);
654 gfc_trans_runtime_check (cond, &se.pre, &e->where, msg,
655 fold_convert (long_integer_type_node, tmp));
656 gfc_free (msg);
658 gfc_add_modify_expr (&se.pre, io,
659 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
660 gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
662 else
664 /* General character. */
665 if (e->ts.type == BT_CHARACTER && e->rank == 0)
666 gfc_conv_expr (&se, e);
667 /* Array assigned Hollerith constant or character array. */
668 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
669 gfc_convert_array_to_string (&se, e);
670 else
671 gcc_unreachable ();
673 gfc_conv_string_parameter (&se);
674 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
675 gfc_add_modify_expr (&se.pre, len, se.string_length);
678 gfc_add_block_to_block (block, &se.pre);
679 gfc_add_block_to_block (postblock, &se.post);
680 return p->mask;
684 /* Generate code to store the character (array) and the character length
685 for an internal unit. */
687 static unsigned int
688 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
689 tree var, gfc_expr * e)
691 gfc_se se;
692 tree io;
693 tree len;
694 tree desc;
695 tree tmp;
696 gfc_st_parameter_field *p;
697 unsigned int mask;
699 gfc_init_se (&se, NULL);
701 p = &st_parameter_field[IOPARM_dt_internal_unit];
702 mask = p->mask;
703 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
704 NULL_TREE);
705 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
706 NULL_TREE);
707 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
708 desc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
709 NULL_TREE);
711 gcc_assert (e->ts.type == BT_CHARACTER);
713 /* Character scalars. */
714 if (e->rank == 0)
716 gfc_conv_expr (&se, e);
717 gfc_conv_string_parameter (&se);
718 tmp = se.expr;
719 se.expr = build_int_cst (pchar_type_node, 0);
722 /* Character array. */
723 else if (e->rank > 0)
725 se.ss = gfc_walk_expr (e);
727 if (is_subref_array (e))
729 /* Use a temporary for components of arrays of derived types
730 or substring array references. */
731 gfc_conv_subref_array_arg (&se, e, 0,
732 last_dt == READ ? INTENT_IN : INTENT_OUT);
733 tmp = build_fold_indirect_ref (se.expr);
734 se.expr = gfc_build_addr_expr (pchar_type_node, tmp);
735 tmp = gfc_conv_descriptor_data_get (tmp);
737 else
739 /* Return the data pointer and rank from the descriptor. */
740 gfc_conv_expr_descriptor (&se, e, se.ss);
741 tmp = gfc_conv_descriptor_data_get (se.expr);
742 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
745 else
746 gcc_unreachable ();
748 /* The cast is needed for character substrings and the descriptor
749 data. */
750 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
751 gfc_add_modify_expr (&se.pre, len,
752 fold_convert (TREE_TYPE (len), se.string_length));
753 gfc_add_modify_expr (&se.pre, desc, se.expr);
755 gfc_add_block_to_block (block, &se.pre);
756 gfc_add_block_to_block (post_block, &se.post);
757 return mask;
760 /* Add a case to a IO-result switch. */
762 static void
763 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
765 tree tmp, value;
767 if (label == NULL)
768 return; /* No label, no case */
770 value = build_int_cst (NULL_TREE, label_value);
772 /* Make a backend label for this case. */
773 tmp = gfc_build_label_decl (NULL_TREE);
775 /* And the case itself. */
776 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
777 gfc_add_expr_to_block (body, tmp);
779 /* Jump to the label. */
780 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
781 gfc_add_expr_to_block (body, tmp);
785 /* Generate a switch statement that branches to the correct I/O
786 result label. The last statement of an I/O call stores the
787 result into a variable because there is often cleanup that
788 must be done before the switch, so a temporary would have to
789 be created anyway. */
791 static void
792 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
793 gfc_st_label * end_label, gfc_st_label * eor_label)
795 stmtblock_t body;
796 tree tmp, rc;
797 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
799 /* If no labels are specified, ignore the result instead
800 of building an empty switch. */
801 if (err_label == NULL
802 && end_label == NULL
803 && eor_label == NULL)
804 return;
806 /* Build a switch statement. */
807 gfc_start_block (&body);
809 /* The label values here must be the same as the values
810 in the library_return enum in the runtime library */
811 add_case (1, err_label, &body);
812 add_case (2, end_label, &body);
813 add_case (3, eor_label, &body);
815 tmp = gfc_finish_block (&body);
817 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
818 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
819 rc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
820 NULL_TREE);
821 rc = build2 (BIT_AND_EXPR, TREE_TYPE (rc), rc,
822 build_int_cst (TREE_TYPE (rc), IOPARM_common_libreturn_mask));
824 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
826 gfc_add_expr_to_block (block, tmp);
830 /* Store the current file and line number to variables so that if a
831 library call goes awry, we can tell the user where the problem is. */
833 static void
834 set_error_locus (stmtblock_t * block, tree var, locus * where)
836 gfc_file *f;
837 tree str, locus_file;
838 int line;
839 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
841 locus_file = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
842 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
843 locus_file = build3 (COMPONENT_REF, TREE_TYPE (p->field), locus_file,
844 p->field, NULL_TREE);
845 f = where->lb->file;
846 str = gfc_build_cstring_const (f->filename);
848 str = gfc_build_addr_expr (pchar_type_node, str);
849 gfc_add_modify_expr (block, locus_file, str);
851 #ifdef USE_MAPPED_LOCATION
852 line = LOCATION_LINE (where->lb->location);
853 #else
854 line = where->lb->linenum;
855 #endif
856 set_parameter_const (block, var, IOPARM_common_line, line);
860 /* Translate an OPEN statement. */
862 tree
863 gfc_trans_open (gfc_code * code)
865 stmtblock_t block, post_block;
866 gfc_open *p;
867 tree tmp, var;
868 unsigned int mask = 0;
870 gfc_start_block (&block);
871 gfc_init_block (&post_block);
873 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
875 set_error_locus (&block, var, &code->loc);
876 p = code->ext.open;
878 if (p->iomsg)
879 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
880 p->iomsg);
882 if (p->iostat)
883 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
884 p->iostat);
886 if (p->err)
887 mask |= IOPARM_common_err;
889 if (p->file)
890 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
892 if (p->status)
893 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
894 p->status);
896 if (p->access)
897 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
898 p->access);
900 if (p->form)
901 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
903 if (p->recl)
904 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
906 if (p->blank)
907 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
908 p->blank);
910 if (p->position)
911 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
912 p->position);
914 if (p->action)
915 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
916 p->action);
918 if (p->delim)
919 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
920 p->delim);
922 if (p->pad)
923 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
925 if (p->convert)
926 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
927 p->convert);
929 set_parameter_const (&block, var, IOPARM_common_flags, mask);
931 if (p->unit)
932 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
933 else
934 set_parameter_const (&block, var, IOPARM_common_unit, 0);
936 tmp = build_fold_addr_expr (var);
937 tmp = build_call_expr (iocall[IOCALL_OPEN], 1, tmp);
938 gfc_add_expr_to_block (&block, tmp);
940 gfc_add_block_to_block (&block, &post_block);
942 io_result (&block, var, p->err, NULL, NULL);
944 return gfc_finish_block (&block);
948 /* Translate a CLOSE statement. */
950 tree
951 gfc_trans_close (gfc_code * code)
953 stmtblock_t block, post_block;
954 gfc_close *p;
955 tree tmp, var;
956 unsigned int mask = 0;
958 gfc_start_block (&block);
959 gfc_init_block (&post_block);
961 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
963 set_error_locus (&block, var, &code->loc);
964 p = code->ext.close;
966 if (p->iomsg)
967 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
968 p->iomsg);
970 if (p->iostat)
971 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
972 p->iostat);
974 if (p->err)
975 mask |= IOPARM_common_err;
977 if (p->status)
978 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
979 p->status);
981 set_parameter_const (&block, var, IOPARM_common_flags, mask);
983 if (p->unit)
984 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
985 else
986 set_parameter_const (&block, var, IOPARM_common_unit, 0);
988 tmp = build_fold_addr_expr (var);
989 tmp = build_call_expr (iocall[IOCALL_CLOSE], 1, tmp);
990 gfc_add_expr_to_block (&block, tmp);
992 gfc_add_block_to_block (&block, &post_block);
994 io_result (&block, var, p->err, NULL, NULL);
996 return gfc_finish_block (&block);
1000 /* Common subroutine for building a file positioning statement. */
1002 static tree
1003 build_filepos (tree function, gfc_code * code)
1005 stmtblock_t block, post_block;
1006 gfc_filepos *p;
1007 tree tmp, var;
1008 unsigned int mask = 0;
1010 p = code->ext.filepos;
1012 gfc_start_block (&block);
1013 gfc_init_block (&post_block);
1015 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
1016 "filepos_parm");
1018 set_error_locus (&block, var, &code->loc);
1020 if (p->iomsg)
1021 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1022 p->iomsg);
1024 if (p->iostat)
1025 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1026 p->iostat);
1028 if (p->err)
1029 mask |= IOPARM_common_err;
1031 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1033 if (p->unit)
1034 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1035 else
1036 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1038 tmp = build_fold_addr_expr (var);
1039 tmp = build_call_expr (function, 1, tmp);
1040 gfc_add_expr_to_block (&block, tmp);
1042 gfc_add_block_to_block (&block, &post_block);
1044 io_result (&block, var, p->err, NULL, NULL);
1046 return gfc_finish_block (&block);
1050 /* Translate a BACKSPACE statement. */
1052 tree
1053 gfc_trans_backspace (gfc_code * code)
1055 return build_filepos (iocall[IOCALL_BACKSPACE], code);
1059 /* Translate an ENDFILE statement. */
1061 tree
1062 gfc_trans_endfile (gfc_code * code)
1064 return build_filepos (iocall[IOCALL_ENDFILE], code);
1068 /* Translate a REWIND statement. */
1070 tree
1071 gfc_trans_rewind (gfc_code * code)
1073 return build_filepos (iocall[IOCALL_REWIND], code);
1077 /* Translate a FLUSH statement. */
1079 tree
1080 gfc_trans_flush (gfc_code * code)
1082 return build_filepos (iocall[IOCALL_FLUSH], code);
1086 /* Create a dummy iostat variable to catch any error due to bad unit. */
1088 static gfc_expr *
1089 create_dummy_iostat (void)
1091 gfc_symtree *st;
1092 gfc_expr *e;
1094 gfc_get_ha_sym_tree ("@iostat", &st);
1095 st->n.sym->ts.type = BT_INTEGER;
1096 st->n.sym->ts.kind = gfc_default_integer_kind;
1097 gfc_set_sym_referenced (st->n.sym);
1098 gfc_commit_symbol (st->n.sym);
1099 st->n.sym->backend_decl
1100 = gfc_create_var (gfc_get_int_type (st->n.sym->ts.kind),
1101 st->n.sym->name);
1103 e = gfc_get_expr ();
1104 e->expr_type = EXPR_VARIABLE;
1105 e->symtree = st;
1106 e->ts.type = BT_INTEGER;
1107 e->ts.kind = st->n.sym->ts.kind;
1109 return e;
1113 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
1115 tree
1116 gfc_trans_inquire (gfc_code * code)
1118 stmtblock_t block, post_block;
1119 gfc_inquire *p;
1120 tree tmp, var;
1121 unsigned int mask = 0;
1123 gfc_start_block (&block);
1124 gfc_init_block (&post_block);
1126 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1127 "inquire_parm");
1129 set_error_locus (&block, var, &code->loc);
1130 p = code->ext.inquire;
1132 if (p->iomsg)
1133 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1134 p->iomsg);
1136 if (p->iostat)
1137 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1138 p->iostat);
1140 if (p->err)
1141 mask |= IOPARM_common_err;
1143 /* Sanity check. */
1144 if (p->unit && p->file)
1145 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1147 if (p->file)
1148 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1149 p->file);
1151 if (p->exist)
1153 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1154 p->exist);
1156 if (p->unit && !p->iostat)
1158 p->iostat = create_dummy_iostat ();
1159 mask |= set_parameter_ref (&block, &post_block, var,
1160 IOPARM_common_iostat, p->iostat);
1164 if (p->opened)
1165 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1166 p->opened);
1168 if (p->number)
1169 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1170 p->number);
1172 if (p->named)
1173 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1174 p->named);
1176 if (p->name)
1177 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1178 p->name);
1180 if (p->access)
1181 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1182 p->access);
1184 if (p->sequential)
1185 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1186 p->sequential);
1188 if (p->direct)
1189 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1190 p->direct);
1192 if (p->form)
1193 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1194 p->form);
1196 if (p->formatted)
1197 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1198 p->formatted);
1200 if (p->unformatted)
1201 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1202 p->unformatted);
1204 if (p->recl)
1205 mask |= set_parameter_ref (&block, &post_block, var,
1206 IOPARM_inquire_recl_out, p->recl);
1208 if (p->nextrec)
1209 mask |= set_parameter_ref (&block, &post_block, var,
1210 IOPARM_inquire_nextrec, p->nextrec);
1212 if (p->blank)
1213 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1214 p->blank);
1216 if (p->position)
1217 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1218 p->position);
1220 if (p->action)
1221 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1222 p->action);
1224 if (p->read)
1225 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1226 p->read);
1228 if (p->write)
1229 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1230 p->write);
1232 if (p->readwrite)
1233 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1234 p->readwrite);
1236 if (p->delim)
1237 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1238 p->delim);
1240 if (p->pad)
1241 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1242 p->pad);
1244 if (p->convert)
1245 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1246 p->convert);
1248 if (p->strm_pos)
1249 mask |= set_parameter_ref (&block, &post_block, var,
1250 IOPARM_inquire_strm_pos_out, p->strm_pos);
1252 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1254 if (p->unit)
1255 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1256 else
1257 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1259 tmp = build_fold_addr_expr (var);
1260 tmp = build_call_expr (iocall[IOCALL_INQUIRE], 1, tmp);
1261 gfc_add_expr_to_block (&block, tmp);
1263 gfc_add_block_to_block (&block, &post_block);
1265 io_result (&block, var, p->err, NULL, NULL);
1267 return gfc_finish_block (&block);
1270 static gfc_expr *
1271 gfc_new_nml_name_expr (const char * name)
1273 gfc_expr * nml_name;
1275 nml_name = gfc_get_expr();
1276 nml_name->ref = NULL;
1277 nml_name->expr_type = EXPR_CONSTANT;
1278 nml_name->ts.kind = gfc_default_character_kind;
1279 nml_name->ts.type = BT_CHARACTER;
1280 nml_name->value.character.length = strlen(name);
1281 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
1282 strcpy (nml_name->value.character.string, name);
1284 return nml_name;
1287 /* nml_full_name builds up the fully qualified name of a
1288 derived type component. */
1290 static char*
1291 nml_full_name (const char* var_name, const char* cmp_name)
1293 int full_name_length;
1294 char * full_name;
1296 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1297 full_name = (char*)gfc_getmem (full_name_length + 1);
1298 strcpy (full_name, var_name);
1299 full_name = strcat (full_name, "%");
1300 full_name = strcat (full_name, cmp_name);
1301 return full_name;
1304 /* nml_get_addr_expr builds an address expression from the
1305 gfc_symbol or gfc_component backend_decl's. An offset is
1306 provided so that the address of an element of an array of
1307 derived types is returned. This is used in the runtime to
1308 determine that span of the derived type. */
1310 static tree
1311 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1312 tree base_addr)
1314 tree decl = NULL_TREE;
1315 tree tmp;
1316 tree itmp;
1317 int array_flagged;
1318 int dummy_arg_flagged;
1320 if (sym)
1322 sym->attr.referenced = 1;
1323 decl = gfc_get_symbol_decl (sym);
1325 /* If this is the enclosing function declaration, use
1326 the fake result instead. */
1327 if (decl == current_function_decl)
1328 decl = gfc_get_fake_result_decl (sym, 0);
1329 else if (decl == DECL_CONTEXT (current_function_decl))
1330 decl = gfc_get_fake_result_decl (sym, 1);
1332 else
1333 decl = c->backend_decl;
1335 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1336 || TREE_CODE (decl) == VAR_DECL
1337 || TREE_CODE (decl) == PARM_DECL)
1338 || TREE_CODE (decl) == COMPONENT_REF));
1340 tmp = decl;
1342 /* Build indirect reference, if dummy argument. */
1344 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1346 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1348 /* If an array, set flag and use indirect ref. if built. */
1350 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1351 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1353 if (array_flagged)
1354 tmp = itmp;
1356 /* Treat the component of a derived type, using base_addr for
1357 the derived type. */
1359 if (TREE_CODE (decl) == FIELD_DECL)
1360 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1361 base_addr, tmp, NULL_TREE);
1363 /* If we have a derived type component, a reference to the first
1364 element of the array is built. This is done so that base_addr,
1365 used in the build of the component reference, always points to
1366 a RECORD_TYPE. */
1368 if (array_flagged)
1369 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL);
1371 /* Now build the address expression. */
1373 tmp = build_fold_addr_expr (tmp);
1375 /* If scalar dummy, resolve indirect reference now. */
1377 if (dummy_arg_flagged && !array_flagged)
1378 tmp = build_fold_indirect_ref (tmp);
1380 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1382 return tmp;
1385 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1386 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1387 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1389 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1391 static void
1392 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1393 gfc_symbol * sym, gfc_component * c,
1394 tree base_addr)
1396 gfc_typespec * ts = NULL;
1397 gfc_array_spec * as = NULL;
1398 tree addr_expr = NULL;
1399 tree dt = NULL;
1400 tree string;
1401 tree tmp;
1402 tree dtype;
1403 tree dt_parm_addr;
1404 int n_dim;
1405 int itype;
1406 int rank = 0;
1408 gcc_assert (sym || c);
1410 /* Build the namelist object name. */
1412 string = gfc_build_cstring_const (var_name);
1413 string = gfc_build_addr_expr (pchar_type_node, string);
1415 /* Build ts, as and data address using symbol or component. */
1417 ts = (sym) ? &sym->ts : &c->ts;
1418 as = (sym) ? sym->as : c->as;
1420 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1422 if (as)
1423 rank = as->rank;
1425 if (rank)
1427 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1428 dtype = gfc_get_dtype (dt);
1430 else
1432 itype = GFC_DTYPE_UNKNOWN;
1434 switch (ts->type)
1437 case BT_INTEGER:
1438 itype = GFC_DTYPE_INTEGER;
1439 break;
1440 case BT_LOGICAL:
1441 itype = GFC_DTYPE_LOGICAL;
1442 break;
1443 case BT_REAL:
1444 itype = GFC_DTYPE_REAL;
1445 break;
1446 case BT_COMPLEX:
1447 itype = GFC_DTYPE_COMPLEX;
1448 break;
1449 case BT_DERIVED:
1450 itype = GFC_DTYPE_DERIVED;
1451 break;
1452 case BT_CHARACTER:
1453 itype = GFC_DTYPE_CHARACTER;
1454 break;
1455 default:
1456 gcc_unreachable ();
1459 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1462 /* Build up the arguments for the transfer call.
1463 The call for the scalar part transfers:
1464 (address, name, type, kind or string_length, dtype) */
1466 dt_parm_addr = build_fold_addr_expr (dt_parm);
1468 if (ts->type == BT_CHARACTER)
1469 tmp = ts->cl->backend_decl;
1470 else
1471 tmp = build_int_cst (gfc_charlen_type_node, 0);
1472 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL], 6,
1473 dt_parm_addr, addr_expr, string,
1474 IARG (ts->kind), tmp, dtype);
1475 gfc_add_expr_to_block (block, tmp);
1477 /* If the object is an array, transfer rank times:
1478 (null pointer, name, stride, lbound, ubound) */
1480 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1482 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], 5,
1483 dt_parm_addr,
1484 IARG (n_dim),
1485 GFC_TYPE_ARRAY_STRIDE (dt, n_dim),
1486 GFC_TYPE_ARRAY_LBOUND (dt, n_dim),
1487 GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1488 gfc_add_expr_to_block (block, tmp);
1491 if (ts->type == BT_DERIVED)
1493 gfc_component *cmp;
1495 /* Provide the RECORD_TYPE to build component references. */
1497 tree expr = build_fold_indirect_ref (addr_expr);
1499 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1501 char *full_name = nml_full_name (var_name, cmp->name);
1502 transfer_namelist_element (block,
1503 full_name,
1504 NULL, cmp, expr);
1505 gfc_free (full_name);
1510 #undef IARG
1512 /* Create a data transfer statement. Not all of the fields are valid
1513 for both reading and writing, but improper use has been filtered
1514 out by now. */
1516 static tree
1517 build_dt (tree function, gfc_code * code)
1519 stmtblock_t block, post_block, post_end_block, post_iu_block;
1520 gfc_dt *dt;
1521 tree tmp, var;
1522 gfc_expr *nmlname;
1523 gfc_namelist *nml;
1524 unsigned int mask = 0;
1526 gfc_start_block (&block);
1527 gfc_init_block (&post_block);
1528 gfc_init_block (&post_end_block);
1529 gfc_init_block (&post_iu_block);
1531 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1533 set_error_locus (&block, var, &code->loc);
1535 if (last_dt == IOLENGTH)
1537 gfc_inquire *inq;
1539 inq = code->ext.inquire;
1541 /* First check that preconditions are met. */
1542 gcc_assert (inq != NULL);
1543 gcc_assert (inq->iolength != NULL);
1545 /* Connect to the iolength variable. */
1546 mask |= set_parameter_ref (&block, &post_end_block, var,
1547 IOPARM_dt_iolength, inq->iolength);
1548 dt = NULL;
1550 else
1552 dt = code->ext.dt;
1553 gcc_assert (dt != NULL);
1556 if (dt && dt->io_unit)
1558 if (dt->io_unit->ts.type == BT_CHARACTER)
1560 mask |= set_internal_unit (&block, &post_iu_block,
1561 var, dt->io_unit);
1562 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1565 else
1566 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1568 if (dt)
1570 if (dt->iomsg)
1571 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1572 dt->iomsg);
1574 if (dt->iostat)
1575 mask |= set_parameter_ref (&block, &post_end_block, var,
1576 IOPARM_common_iostat, dt->iostat);
1578 if (dt->err)
1579 mask |= IOPARM_common_err;
1581 if (dt->eor)
1582 mask |= IOPARM_common_eor;
1584 if (dt->end)
1585 mask |= IOPARM_common_end;
1587 if (dt->rec)
1588 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1590 if (dt->advance)
1591 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1592 dt->advance);
1594 if (dt->format_expr)
1595 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1596 dt->format_expr);
1598 if (dt->format_label)
1600 if (dt->format_label == &format_asterisk)
1601 mask |= IOPARM_dt_list_format;
1602 else
1603 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1604 dt->format_label->format);
1607 if (dt->size)
1608 mask |= set_parameter_ref (&block, &post_end_block, var,
1609 IOPARM_dt_size, dt->size);
1611 if (dt->namelist)
1613 if (dt->format_expr || dt->format_label)
1614 gfc_internal_error ("build_dt: format with namelist");
1616 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1618 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1619 nmlname);
1621 if (last_dt == READ)
1622 mask |= IOPARM_dt_namelist_read_mode;
1624 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1626 dt_parm = var;
1628 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1629 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1630 NULL, NULL);
1632 else
1633 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1635 if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER)
1636 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1638 else
1639 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1641 tmp = build_fold_addr_expr (var);
1642 tmp = build_call_expr (function, 1, tmp);
1643 gfc_add_expr_to_block (&block, tmp);
1645 gfc_add_block_to_block (&block, &post_block);
1647 dt_parm = var;
1648 dt_post_end_block = &post_end_block;
1650 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1652 gfc_add_block_to_block (&block, &post_iu_block);
1654 dt_parm = NULL;
1655 dt_post_end_block = NULL;
1657 return gfc_finish_block (&block);
1661 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1662 this as a third sort of data transfer statement, except that
1663 lengths are summed instead of actually transferring any data. */
1665 tree
1666 gfc_trans_iolength (gfc_code * code)
1668 last_dt = IOLENGTH;
1669 return build_dt (iocall[IOCALL_IOLENGTH], code);
1673 /* Translate a READ statement. */
1675 tree
1676 gfc_trans_read (gfc_code * code)
1678 last_dt = READ;
1679 return build_dt (iocall[IOCALL_READ], code);
1683 /* Translate a WRITE statement */
1685 tree
1686 gfc_trans_write (gfc_code * code)
1688 last_dt = WRITE;
1689 return build_dt (iocall[IOCALL_WRITE], code);
1693 /* Finish a data transfer statement. */
1695 tree
1696 gfc_trans_dt_end (gfc_code * code)
1698 tree function, tmp;
1699 stmtblock_t block;
1701 gfc_init_block (&block);
1703 switch (last_dt)
1705 case READ:
1706 function = iocall[IOCALL_READ_DONE];
1707 break;
1709 case WRITE:
1710 function = iocall[IOCALL_WRITE_DONE];
1711 break;
1713 case IOLENGTH:
1714 function = iocall[IOCALL_IOLENGTH_DONE];
1715 break;
1717 default:
1718 gcc_unreachable ();
1721 tmp = build_fold_addr_expr (dt_parm);
1722 tmp = build_call_expr (function, 1, tmp);
1723 gfc_add_expr_to_block (&block, tmp);
1724 gfc_add_block_to_block (&block, dt_post_end_block);
1725 gfc_init_block (dt_post_end_block);
1727 if (last_dt != IOLENGTH)
1729 gcc_assert (code->ext.dt != NULL);
1730 io_result (&block, dt_parm, code->ext.dt->err,
1731 code->ext.dt->end, code->ext.dt->eor);
1734 return gfc_finish_block (&block);
1737 static void
1738 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code);
1740 /* Given an array field in a derived type variable, generate the code
1741 for the loop that iterates over array elements, and the code that
1742 accesses those array elements. Use transfer_expr to generate code
1743 for transferring that element. Because elements may also be
1744 derived types, transfer_expr and transfer_array_component are mutually
1745 recursive. */
1747 static tree
1748 transfer_array_component (tree expr, gfc_component * cm)
1750 tree tmp;
1751 stmtblock_t body;
1752 stmtblock_t block;
1753 gfc_loopinfo loop;
1754 int n;
1755 gfc_ss *ss;
1756 gfc_se se;
1758 gfc_start_block (&block);
1759 gfc_init_se (&se, NULL);
1761 /* Create and initialize Scalarization Status. Unlike in
1762 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1763 care of this task, because we don't have a gfc_expr at hand.
1764 Build one manually, as in gfc_trans_subarray_assign. */
1766 ss = gfc_get_ss ();
1767 ss->type = GFC_SS_COMPONENT;
1768 ss->expr = NULL;
1769 ss->shape = gfc_get_shape (cm->as->rank);
1770 ss->next = gfc_ss_terminator;
1771 ss->data.info.dimen = cm->as->rank;
1772 ss->data.info.descriptor = expr;
1773 ss->data.info.data = gfc_conv_array_data (expr);
1774 ss->data.info.offset = gfc_conv_array_offset (expr);
1775 for (n = 0; n < cm->as->rank; n++)
1777 ss->data.info.dim[n] = n;
1778 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1779 ss->data.info.stride[n] = gfc_index_one_node;
1781 mpz_init (ss->shape[n]);
1782 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1783 cm->as->lower[n]->value.integer);
1784 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1787 /* Once we got ss, we use scalarizer to create the loop. */
1789 gfc_init_loopinfo (&loop);
1790 gfc_add_ss_to_loop (&loop, ss);
1791 gfc_conv_ss_startstride (&loop);
1792 gfc_conv_loop_setup (&loop);
1793 gfc_mark_ss_chain_used (ss, 1);
1794 gfc_start_scalarized_body (&loop, &body);
1796 gfc_copy_loopinfo_to_se (&se, &loop);
1797 se.ss = ss;
1799 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1800 se.expr = expr;
1801 gfc_conv_tmp_array_ref (&se);
1803 /* Now se.expr contains an element of the array. Take the address and pass
1804 it to the IO routines. */
1805 tmp = build_fold_addr_expr (se.expr);
1806 transfer_expr (&se, &cm->ts, tmp, NULL);
1808 /* We are done now with the loop body. Wrap up the scalarizer and
1809 return. */
1811 gfc_add_block_to_block (&body, &se.pre);
1812 gfc_add_block_to_block (&body, &se.post);
1814 gfc_trans_scalarizing_loops (&loop, &body);
1816 gfc_add_block_to_block (&block, &loop.pre);
1817 gfc_add_block_to_block (&block, &loop.post);
1819 for (n = 0; n < cm->as->rank; n++)
1820 mpz_clear (ss->shape[n]);
1821 gfc_free (ss->shape);
1823 gfc_cleanup_loop (&loop);
1825 return gfc_finish_block (&block);
1828 /* Generate the call for a scalar transfer node. */
1830 static void
1831 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
1833 tree tmp, function, arg2, field, expr;
1834 gfc_component *c;
1835 int kind;
1837 /* It is possible to get a C_NULL_PTR or C_NULL_FUNPTR expression here if
1838 the user says something like: print *, 'c_null_ptr: ', c_null_ptr
1839 We need to translate the expression to a constant if it's either
1840 C_NULL_PTR or C_NULL_FUNPTR. We could also get a user variable of
1841 type C_PTR or C_FUNPTR, in which case the ts->type may no longer be
1842 BT_DERIVED (could have been changed by gfc_conv_expr). */
1843 if ((ts->type == BT_DERIVED && ts->is_iso_c == 1 && ts->derived != NULL)
1844 || (ts->derived != NULL && ts->derived->ts.is_iso_c == 1))
1846 /* C_PTR and C_FUNPTR have private components which means they can not
1847 be printed. However, if -std=gnu and not -pedantic, allow
1848 the component to be printed to help debugging. */
1849 if (gfc_notification_std (GFC_STD_GNU) != SILENT)
1851 gfc_error_now ("Derived type '%s' at %L has PRIVATE components",
1852 ts->derived->name, code != NULL ? &(code->loc) :
1853 &gfc_current_locus);
1854 return;
1857 ts->type = ts->derived->ts.type;
1858 ts->kind = ts->derived->ts.kind;
1859 ts->f90_type = ts->derived->ts.f90_type;
1862 kind = ts->kind;
1863 function = NULL;
1864 arg2 = NULL;
1866 switch (ts->type)
1868 case BT_INTEGER:
1869 arg2 = build_int_cst (NULL_TREE, kind);
1870 function = iocall[IOCALL_X_INTEGER];
1871 break;
1873 case BT_REAL:
1874 arg2 = build_int_cst (NULL_TREE, kind);
1875 function = iocall[IOCALL_X_REAL];
1876 break;
1878 case BT_COMPLEX:
1879 arg2 = build_int_cst (NULL_TREE, kind);
1880 function = iocall[IOCALL_X_COMPLEX];
1881 break;
1883 case BT_LOGICAL:
1884 arg2 = build_int_cst (NULL_TREE, kind);
1885 function = iocall[IOCALL_X_LOGICAL];
1886 break;
1888 case BT_CHARACTER:
1889 case BT_HOLLERITH:
1890 if (se->string_length)
1891 arg2 = se->string_length;
1892 else
1894 tmp = build_fold_indirect_ref (addr_expr);
1895 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1896 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1898 function = iocall[IOCALL_X_CHARACTER];
1899 break;
1901 case BT_DERIVED:
1902 /* Recurse into the elements of the derived type. */
1903 expr = gfc_evaluate_now (addr_expr, &se->pre);
1904 expr = build_fold_indirect_ref (expr);
1906 for (c = ts->derived->components; c; c = c->next)
1908 field = c->backend_decl;
1909 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1911 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1912 NULL_TREE);
1914 if (c->dimension)
1916 tmp = transfer_array_component (tmp, c);
1917 gfc_add_expr_to_block (&se->pre, tmp);
1919 else
1921 if (!c->pointer)
1922 tmp = build_fold_addr_expr (tmp);
1923 transfer_expr (se, &c->ts, tmp, code);
1926 return;
1928 default:
1929 internal_error ("Bad IO basetype (%d)", ts->type);
1932 tmp = build_fold_addr_expr (dt_parm);
1933 tmp = build_call_expr (function, 3, tmp, addr_expr, arg2);
1934 gfc_add_expr_to_block (&se->pre, tmp);
1935 gfc_add_block_to_block (&se->pre, &se->post);
1940 /* Generate a call to pass an array descriptor to the IO library. The
1941 array should be of one of the intrinsic types. */
1943 static void
1944 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1946 tree tmp, charlen_arg, kind_arg;
1948 if (ts->type == BT_CHARACTER)
1949 charlen_arg = se->string_length;
1950 else
1951 charlen_arg = build_int_cst (NULL_TREE, 0);
1953 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1955 tmp = build_fold_addr_expr (dt_parm);
1956 tmp = build_call_expr (iocall[IOCALL_X_ARRAY], 4,
1957 tmp, addr_expr, kind_arg, charlen_arg);
1958 gfc_add_expr_to_block (&se->pre, tmp);
1959 gfc_add_block_to_block (&se->pre, &se->post);
1963 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1965 tree
1966 gfc_trans_transfer (gfc_code * code)
1968 stmtblock_t block, body;
1969 gfc_loopinfo loop;
1970 gfc_expr *expr;
1971 gfc_ref *ref;
1972 gfc_ss *ss;
1973 gfc_se se;
1974 tree tmp;
1975 int n;
1977 gfc_start_block (&block);
1978 gfc_init_block (&body);
1980 expr = code->expr;
1981 ss = gfc_walk_expr (expr);
1983 ref = NULL;
1984 gfc_init_se (&se, NULL);
1986 if (ss == gfc_ss_terminator)
1988 /* Transfer a scalar value. */
1989 gfc_conv_expr_reference (&se, expr);
1990 transfer_expr (&se, &expr->ts, se.expr, code);
1992 else
1994 /* Transfer an array. If it is an array of an intrinsic
1995 type, pass the descriptor to the library. Otherwise
1996 scalarize the transfer. */
1997 if (expr->ref)
1999 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
2000 ref = ref->next);
2001 gcc_assert (ref->type == REF_ARRAY);
2004 if (expr->ts.type != BT_DERIVED
2005 && ref && ref->next == NULL
2006 && !is_subref_array (expr))
2008 bool seen_vector = false;
2010 if (ref && ref->u.ar.type == AR_SECTION)
2012 for (n = 0; n < ref->u.ar.dimen; n++)
2013 if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
2014 seen_vector = true;
2017 if (seen_vector && last_dt == READ)
2019 /* Create a temp, read to that and copy it back. */
2020 gfc_conv_subref_array_arg (&se, expr, 0, INTENT_OUT);
2021 tmp = se.expr;
2023 else
2025 /* Get the descriptor. */
2026 gfc_conv_expr_descriptor (&se, expr, ss);
2027 tmp = build_fold_addr_expr (se.expr);
2030 transfer_array_desc (&se, &expr->ts, tmp);
2031 goto finish_block_label;
2034 /* Initialize the scalarizer. */
2035 gfc_init_loopinfo (&loop);
2036 gfc_add_ss_to_loop (&loop, ss);
2038 /* Initialize the loop. */
2039 gfc_conv_ss_startstride (&loop);
2040 gfc_conv_loop_setup (&loop);
2042 /* The main loop body. */
2043 gfc_mark_ss_chain_used (ss, 1);
2044 gfc_start_scalarized_body (&loop, &body);
2046 gfc_copy_loopinfo_to_se (&se, &loop);
2047 se.ss = ss;
2049 gfc_conv_expr_reference (&se, expr);
2050 transfer_expr (&se, &expr->ts, se.expr, code);
2053 finish_block_label:
2055 gfc_add_block_to_block (&body, &se.pre);
2056 gfc_add_block_to_block (&body, &se.post);
2058 if (se.ss == NULL)
2059 tmp = gfc_finish_block (&body);
2060 else
2062 gcc_assert (se.ss == gfc_ss_terminator);
2063 gfc_trans_scalarizing_loops (&loop, &body);
2065 gfc_add_block_to_block (&loop.pre, &loop.post);
2066 tmp = gfc_finish_block (&loop.pre);
2067 gfc_cleanup_loop (&loop);
2070 gfc_add_expr_to_block (&block, tmp);
2072 return gfc_finish_block (&block);
2075 #include "gt-fortran-trans-io.h"