b4c83f49f86fb2d180e3e3653bf7eed8e7a42344
[gcc.git] / gcc / fortran / trans-io.c
1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Paul Brook
4
5 This file is part of GCC.
6
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 2, or (at your option) any later
10 version.
11
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.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22
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"
37
38
39 /* Members of the ioparm structure. */
40
41 enum ioparam_type
42 {
43 IOPARM_ptype_common,
44 IOPARM_ptype_open,
45 IOPARM_ptype_close,
46 IOPARM_ptype_filepos,
47 IOPARM_ptype_inquire,
48 IOPARM_ptype_dt,
49 IOPARM_ptype_num
50 };
51
52 enum iofield_type
53 {
54 IOPARM_type_int4,
55 IOPARM_type_pint4,
56 IOPARM_type_pchar,
57 IOPARM_type_parray,
58 IOPARM_type_pad,
59 IOPARM_type_char1,
60 IOPARM_type_char2,
61 IOPARM_type_common,
62 IOPARM_type_num
63 };
64
65 typedef struct gfc_st_parameter_field GTY(())
66 {
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;
73 }
74 gfc_st_parameter_field;
75
76 typedef struct gfc_st_parameter GTY(())
77 {
78 const char *name;
79 tree type;
80 }
81 gfc_st_parameter;
82
83 enum iofield
84 {
85 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
86 #include "ioparm.def"
87 #undef IOPARM
88 IOPARM_field_num
89 };
90
91 static GTY(()) gfc_st_parameter st_parameter[] =
92 {
93 { "common", NULL },
94 { "open", NULL },
95 { "close", NULL },
96 { "filepos", NULL },
97 { "inquire", NULL },
98 { "dt", NULL }
99 };
100
101 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
102 {
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, 0, 0, NULL, NULL }
108 };
109
110 /* Library I/O subroutines */
111
112 enum iocall
113 {
114 IOCALL_READ,
115 IOCALL_READ_DONE,
116 IOCALL_WRITE,
117 IOCALL_WRITE_DONE,
118 IOCALL_X_INTEGER,
119 IOCALL_X_LOGICAL,
120 IOCALL_X_CHARACTER,
121 IOCALL_X_REAL,
122 IOCALL_X_COMPLEX,
123 IOCALL_X_ARRAY,
124 IOCALL_OPEN,
125 IOCALL_CLOSE,
126 IOCALL_INQUIRE,
127 IOCALL_IOLENGTH,
128 IOCALL_IOLENGTH_DONE,
129 IOCALL_REWIND,
130 IOCALL_BACKSPACE,
131 IOCALL_ENDFILE,
132 IOCALL_FLUSH,
133 IOCALL_SET_NML_VAL,
134 IOCALL_SET_NML_VAL_DIM,
135 IOCALL_NUM
136 };
137
138 static GTY(()) tree iocall[IOCALL_NUM];
139
140 /* Variable for keeping track of what the last data transfer statement
141 was. Used for deciding which subroutine to call when the data
142 transfer is complete. */
143 static enum { READ, WRITE, IOLENGTH } last_dt;
144
145 /* The data transfer parameter block that should be shared by all
146 data transfer calls belonging to the same read/write/iolength. */
147 static GTY(()) tree dt_parm;
148 static stmtblock_t *dt_post_end_block;
149
150 static void
151 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
152 {
153 enum iofield type;
154 gfc_st_parameter_field *p;
155 char name[64];
156 size_t len;
157 tree t = make_node (RECORD_TYPE);
158
159 len = strlen (st_parameter[ptype].name);
160 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
161 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
162 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
163 len + 1);
164 TYPE_NAME (t) = get_identifier (name);
165
166 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
167 if (p->param_type == ptype)
168 switch (p->type)
169 {
170 case IOPARM_type_int4:
171 case IOPARM_type_pint4:
172 case IOPARM_type_parray:
173 case IOPARM_type_pchar:
174 case IOPARM_type_pad:
175 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
176 get_identifier (p->name),
177 types[p->type]);
178 break;
179 case IOPARM_type_char1:
180 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
181 get_identifier (p->name),
182 pchar_type_node);
183 /* FALLTHROUGH */
184 case IOPARM_type_char2:
185 len = strlen (p->name);
186 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
187 memcpy (name, p->name, len);
188 memcpy (name + len, "_len", sizeof ("_len"));
189 p->field_len = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
190 get_identifier (name),
191 gfc_charlen_type_node);
192 if (p->type == IOPARM_type_char2)
193 p->field = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
194 get_identifier (p->name),
195 pchar_type_node);
196 break;
197 case IOPARM_type_common:
198 p->field
199 = gfc_add_field_to_struct (&TYPE_FIELDS (t), t,
200 get_identifier (p->name),
201 st_parameter[IOPARM_ptype_common].type);
202 break;
203 case IOPARM_type_num:
204 gcc_unreachable ();
205 }
206
207 gfc_finish_type (t);
208 st_parameter[ptype].type = t;
209 }
210
211 /* Create function decls for IO library functions. */
212
213 void
214 gfc_build_io_library_fndecls (void)
215 {
216 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
217 tree parm_type, dt_parm_type;
218 tree gfc_c_int_type_node;
219 HOST_WIDE_INT pad_size;
220 enum ioparam_type ptype;
221
222 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
223 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
224 types[IOPARM_type_parray] = pchar_type_node;
225 types[IOPARM_type_pchar] = pchar_type_node;
226 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
227 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
228 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size));
229 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
230
231 /* pad actually contains pointers and integers so it needs to have an
232 alignment that is at least as large as the needed alignment for those
233 types. See the st_parameter_dt structure in libgfortran/io/io.h for
234 what really goes into this space. */
235 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
236 TYPE_ALIGN (gfc_get_int_type (gfc_max_integer_kind)));
237
238 gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind);
239
240 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
241 gfc_build_st_parameter (ptype, types);
242
243 /* Define the transfer functions. */
244
245 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
246
247 iocall[IOCALL_X_INTEGER] =
248 gfc_build_library_function_decl (get_identifier
249 (PREFIX("transfer_integer")),
250 void_type_node, 3, dt_parm_type,
251 pvoid_type_node, gfc_int4_type_node);
252
253 iocall[IOCALL_X_LOGICAL] =
254 gfc_build_library_function_decl (get_identifier
255 (PREFIX("transfer_logical")),
256 void_type_node, 3, dt_parm_type,
257 pvoid_type_node, gfc_int4_type_node);
258
259 iocall[IOCALL_X_CHARACTER] =
260 gfc_build_library_function_decl (get_identifier
261 (PREFIX("transfer_character")),
262 void_type_node, 3, dt_parm_type,
263 pvoid_type_node, gfc_int4_type_node);
264
265 iocall[IOCALL_X_REAL] =
266 gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
267 void_type_node, 3, dt_parm_type,
268 pvoid_type_node, gfc_int4_type_node);
269
270 iocall[IOCALL_X_COMPLEX] =
271 gfc_build_library_function_decl (get_identifier
272 (PREFIX("transfer_complex")),
273 void_type_node, 3, dt_parm_type,
274 pvoid_type_node, gfc_int4_type_node);
275
276 iocall[IOCALL_X_ARRAY] =
277 gfc_build_library_function_decl (get_identifier
278 (PREFIX("transfer_array")),
279 void_type_node, 4, dt_parm_type,
280 pvoid_type_node, gfc_c_int_type_node,
281 gfc_charlen_type_node);
282
283 /* Library entry points */
284
285 iocall[IOCALL_READ] =
286 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
287 void_type_node, 1, dt_parm_type);
288
289 iocall[IOCALL_WRITE] =
290 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
291 void_type_node, 1, dt_parm_type);
292
293 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
294 iocall[IOCALL_OPEN] =
295 gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
296 void_type_node, 1, parm_type);
297
298
299 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
300 iocall[IOCALL_CLOSE] =
301 gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
302 void_type_node, 1, parm_type);
303
304 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
305 iocall[IOCALL_INQUIRE] =
306 gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
307 gfc_int4_type_node, 1, parm_type);
308
309 iocall[IOCALL_IOLENGTH] =
310 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
311 void_type_node, 1, dt_parm_type);
312
313 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
314 iocall[IOCALL_REWIND] =
315 gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
316 gfc_int4_type_node, 1, parm_type);
317
318 iocall[IOCALL_BACKSPACE] =
319 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
320 gfc_int4_type_node, 1, parm_type);
321
322 iocall[IOCALL_ENDFILE] =
323 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
324 gfc_int4_type_node, 1, parm_type);
325
326 iocall[IOCALL_FLUSH] =
327 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
328 gfc_int4_type_node, 1, parm_type);
329
330 /* Library helpers */
331
332 iocall[IOCALL_READ_DONE] =
333 gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
334 gfc_int4_type_node, 1, dt_parm_type);
335
336 iocall[IOCALL_WRITE_DONE] =
337 gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
338 gfc_int4_type_node, 1, dt_parm_type);
339
340 iocall[IOCALL_IOLENGTH_DONE] =
341 gfc_build_library_function_decl (get_identifier (PREFIX("st_iolength_done")),
342 gfc_int4_type_node, 1, dt_parm_type);
343
344
345 iocall[IOCALL_SET_NML_VAL] =
346 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var")),
347 void_type_node, 6, dt_parm_type,
348 pvoid_type_node, pvoid_type_node,
349 gfc_int4_type_node, gfc_charlen_type_node,
350 gfc_int4_type_node);
351
352 iocall[IOCALL_SET_NML_VAL_DIM] =
353 gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_dim")),
354 void_type_node, 5, dt_parm_type,
355 gfc_int4_type_node, gfc_int4_type_node,
356 gfc_int4_type_node, gfc_int4_type_node);
357 }
358
359
360 /* Generate code to store an integer constant into the
361 st_parameter_XXX structure. */
362
363 static unsigned int
364 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
365 unsigned int val)
366 {
367 tree tmp;
368 gfc_st_parameter_field *p = &st_parameter_field[type];
369
370 if (p->param_type == IOPARM_ptype_common)
371 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
372 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
373 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
374 NULL_TREE);
375 gfc_add_modify_expr (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
376 return p->mask;
377 }
378
379
380 /* Generate code to store a non-string I/O parameter into the
381 st_parameter_XXX structure. This is a pass by value. */
382
383 static unsigned int
384 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
385 gfc_expr *e)
386 {
387 gfc_se se;
388 tree tmp;
389 gfc_st_parameter_field *p = &st_parameter_field[type];
390
391 gfc_init_se (&se, NULL);
392 gfc_conv_expr_type (&se, e, TREE_TYPE (p->field));
393 gfc_add_block_to_block (block, &se.pre);
394
395 if (p->param_type == IOPARM_ptype_common)
396 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
397 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
398 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
399 NULL_TREE);
400 gfc_add_modify_expr (block, tmp, se.expr);
401 return p->mask;
402 }
403
404
405 /* Generate code to store a non-string I/O parameter into the
406 st_parameter_XXX structure. This is pass by reference. */
407
408 static unsigned int
409 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
410 tree var, enum iofield type, gfc_expr *e)
411 {
412 gfc_se se;
413 tree tmp, addr;
414 gfc_st_parameter_field *p = &st_parameter_field[type];
415
416 gcc_assert (e->ts.type == BT_INTEGER || e->ts.type == BT_LOGICAL);
417 gfc_init_se (&se, NULL);
418 gfc_conv_expr_lhs (&se, e);
419
420 gfc_add_block_to_block (block, &se.pre);
421
422 if (TYPE_MODE (TREE_TYPE (se.expr))
423 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
424 addr = convert (TREE_TYPE (p->field),
425 build_fold_addr_expr (se.expr));
426 else
427 {
428 /* The type used by the library has different size
429 from the type of the variable supplied by the user.
430 Need to use a temporary. */
431 tree tmpvar
432 = gfc_create_var (TREE_TYPE (TREE_TYPE (p->field)),
433 st_parameter_field[type].name);
434 addr = build_fold_addr_expr (tmpvar);
435 tmp = convert (TREE_TYPE (se.expr), tmpvar);
436 gfc_add_modify_expr (postblock, se.expr, tmp);
437 }
438
439 if (p->param_type == IOPARM_ptype_common)
440 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
441 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
442 tmp = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
443 NULL_TREE);
444 gfc_add_modify_expr (block, tmp, addr);
445 return p->mask;
446 }
447
448 /* Given an array expr, find its address and length to get a string. If the
449 array is full, the string's address is the address of array's first element
450 and the length is the size of the whole array. If it is an element, the
451 string's address is the element's address and the length is the rest size of
452 the array.
453 */
454
455 static void
456 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
457 {
458 tree tmp;
459 tree array;
460 tree type;
461 tree size;
462 int rank;
463 gfc_symbol *sym;
464
465 sym = e->symtree->n.sym;
466 rank = sym->as->rank - 1;
467
468 if (e->ref->u.ar.type == AR_FULL)
469 {
470 se->expr = gfc_get_symbol_decl (sym);
471 se->expr = gfc_conv_array_data (se->expr);
472 }
473 else
474 {
475 gfc_conv_expr (se, e);
476 }
477
478 array = sym->backend_decl;
479 type = TREE_TYPE (array);
480
481 if (GFC_ARRAY_TYPE_P (type))
482 size = GFC_TYPE_ARRAY_SIZE (type);
483 else
484 {
485 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
486 size = gfc_conv_array_stride (array, rank);
487 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
488 gfc_conv_array_ubound (array, rank),
489 gfc_conv_array_lbound (array, rank));
490 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
491 gfc_index_one_node);
492 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
493 }
494
495 gcc_assert (size);
496
497 /* If it is an element, we need the its address and size of the rest. */
498 if (e->ref->u.ar.type == AR_ELEMENT)
499 {
500 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
501 TREE_OPERAND (se->expr, 1));
502 se->expr = build_fold_addr_expr (se->expr);
503 }
504
505 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
506 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
507
508 se->string_length = fold_convert (gfc_charlen_type_node, size);
509 }
510
511
512 /* Generate code to store a string and its length into the
513 st_parameter_XXX structure. */
514
515 static unsigned int
516 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
517 enum iofield type, gfc_expr * e)
518 {
519 gfc_se se;
520 tree tmp;
521 tree msg;
522 tree io;
523 tree len;
524 gfc_st_parameter_field *p = &st_parameter_field[type];
525
526 gfc_init_se (&se, NULL);
527
528 if (p->param_type == IOPARM_ptype_common)
529 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
530 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
531 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
532 NULL_TREE);
533 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
534 NULL_TREE);
535
536 /* Integer variable assigned a format label. */
537 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
538 {
539 gfc_conv_label_variable (&se, e);
540 msg =
541 gfc_build_cstring_const ("Assigned label is not a format label");
542 tmp = GFC_DECL_STRING_LEN (se.expr);
543 tmp = fold_build2 (LT_EXPR, boolean_type_node,
544 tmp, build_int_cst (TREE_TYPE (tmp), 0));
545 gfc_trans_runtime_check (tmp, msg, &se.pre);
546 gfc_add_modify_expr (&se.pre, io,
547 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
548 gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
549 }
550 else
551 {
552 /* General character. */
553 if (e->ts.type == BT_CHARACTER && e->rank == 0)
554 gfc_conv_expr (&se, e);
555 /* Array assigned Hollerith constant or character array. */
556 else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
557 gfc_convert_array_to_string (&se, e);
558 else
559 gcc_unreachable ();
560
561 gfc_conv_string_parameter (&se);
562 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
563 gfc_add_modify_expr (&se.pre, len, se.string_length);
564 }
565
566 gfc_add_block_to_block (block, &se.pre);
567 gfc_add_block_to_block (postblock, &se.post);
568 return p->mask;
569 }
570
571
572 /* Generate code to store the character (array) and the character length
573 for an internal unit. */
574
575 static unsigned int
576 set_internal_unit (stmtblock_t * block, tree var, gfc_expr * e)
577 {
578 gfc_se se;
579 tree io;
580 tree len;
581 tree desc;
582 tree tmp;
583 gfc_st_parameter_field *p;
584 unsigned int mask;
585
586 gfc_init_se (&se, NULL);
587
588 p = &st_parameter_field[IOPARM_dt_internal_unit];
589 mask = p->mask;
590 io = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
591 NULL_TREE);
592 len = build3 (COMPONENT_REF, TREE_TYPE (p->field_len), var, p->field_len,
593 NULL_TREE);
594 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
595 desc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
596 NULL_TREE);
597
598 gcc_assert (e->ts.type == BT_CHARACTER);
599
600 /* Character scalars. */
601 if (e->rank == 0)
602 {
603 gfc_conv_expr (&se, e);
604 gfc_conv_string_parameter (&se);
605 tmp = se.expr;
606 se.expr = fold_convert (pchar_type_node, integer_zero_node);
607 }
608
609 /* Character array. */
610 else if (e->rank > 0)
611 {
612 se.ss = gfc_walk_expr (e);
613
614 /* Return the data pointer and rank from the descriptor. */
615 gfc_conv_expr_descriptor (&se, e, se.ss);
616 tmp = gfc_conv_descriptor_data_get (se.expr);
617 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
618 }
619 else
620 gcc_unreachable ();
621
622 /* The cast is needed for character substrings and the descriptor
623 data. */
624 gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
625 gfc_add_modify_expr (&se.pre, len, se.string_length);
626 gfc_add_modify_expr (&se.pre, desc, se.expr);
627
628 gfc_add_block_to_block (block, &se.pre);
629 return mask;
630 }
631
632 /* Add a case to a IO-result switch. */
633
634 static void
635 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
636 {
637 tree tmp, value;
638
639 if (label == NULL)
640 return; /* No label, no case */
641
642 value = build_int_cst (NULL_TREE, label_value);
643
644 /* Make a backend label for this case. */
645 tmp = gfc_build_label_decl (NULL_TREE);
646
647 /* And the case itself. */
648 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
649 gfc_add_expr_to_block (body, tmp);
650
651 /* Jump to the label. */
652 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
653 gfc_add_expr_to_block (body, tmp);
654 }
655
656
657 /* Generate a switch statement that branches to the correct I/O
658 result label. The last statement of an I/O call stores the
659 result into a variable because there is often cleanup that
660 must be done before the switch, so a temporary would have to
661 be created anyway. */
662
663 static void
664 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
665 gfc_st_label * end_label, gfc_st_label * eor_label)
666 {
667 stmtblock_t body;
668 tree tmp, rc;
669 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
670
671 /* If no labels are specified, ignore the result instead
672 of building an empty switch. */
673 if (err_label == NULL
674 && end_label == NULL
675 && eor_label == NULL)
676 return;
677
678 /* Build a switch statement. */
679 gfc_start_block (&body);
680
681 /* The label values here must be the same as the values
682 in the library_return enum in the runtime library */
683 add_case (1, err_label, &body);
684 add_case (2, end_label, &body);
685 add_case (3, eor_label, &body);
686
687 tmp = gfc_finish_block (&body);
688
689 var = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
690 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
691 rc = build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
692 NULL_TREE);
693 rc = build2 (BIT_AND_EXPR, TREE_TYPE (rc), rc,
694 build_int_cst (TREE_TYPE (rc), IOPARM_common_libreturn_mask));
695
696 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
697
698 gfc_add_expr_to_block (block, tmp);
699 }
700
701
702 /* Store the current file and line number to variables so that if a
703 library call goes awry, we can tell the user where the problem is. */
704
705 static void
706 set_error_locus (stmtblock_t * block, tree var, locus * where)
707 {
708 gfc_file *f;
709 tree str, locus_file;
710 int line;
711 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
712
713 locus_file = build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
714 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
715 locus_file = build3 (COMPONENT_REF, TREE_TYPE (p->field), locus_file,
716 p->field, NULL_TREE);
717 f = where->lb->file;
718 str = gfc_build_cstring_const (f->filename);
719
720 str = gfc_build_addr_expr (pchar_type_node, str);
721 gfc_add_modify_expr (block, locus_file, str);
722
723 #ifdef USE_MAPPED_LOCATION
724 line = LOCATION_LINE (where->lb->location);
725 #else
726 line = where->lb->linenum;
727 #endif
728 set_parameter_const (block, var, IOPARM_common_line, line);
729 }
730
731
732 /* Translate an OPEN statement. */
733
734 tree
735 gfc_trans_open (gfc_code * code)
736 {
737 stmtblock_t block, post_block;
738 gfc_open *p;
739 tree tmp, var;
740 unsigned int mask = 0;
741
742 gfc_start_block (&block);
743 gfc_init_block (&post_block);
744
745 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
746
747 set_error_locus (&block, var, &code->loc);
748 p = code->ext.open;
749
750 if (p->unit)
751 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
752 else
753 set_parameter_const (&block, var, IOPARM_common_unit, 0);
754
755 if (p->file)
756 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
757
758 if (p->status)
759 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
760 p->status);
761
762 if (p->access)
763 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
764 p->access);
765
766 if (p->form)
767 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
768
769 if (p->recl)
770 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
771
772 if (p->blank)
773 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
774 p->blank);
775
776 if (p->position)
777 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
778 p->position);
779
780 if (p->action)
781 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
782 p->action);
783
784 if (p->delim)
785 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
786 p->delim);
787
788 if (p->pad)
789 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
790
791 if (p->iomsg)
792 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
793 p->iomsg);
794
795 if (p->iostat)
796 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
797 p->iostat);
798
799 if (p->err)
800 mask |= IOPARM_common_err;
801
802 if (p->convert)
803 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
804 p->convert);
805
806 set_parameter_const (&block, var, IOPARM_common_flags, mask);
807
808 tmp = build_fold_addr_expr (var);
809 tmp = gfc_chainon_list (NULL_TREE, tmp);
810 tmp = build_function_call_expr (iocall[IOCALL_OPEN], tmp);
811 gfc_add_expr_to_block (&block, tmp);
812
813 gfc_add_block_to_block (&block, &post_block);
814
815 io_result (&block, var, p->err, NULL, NULL);
816
817 return gfc_finish_block (&block);
818 }
819
820
821 /* Translate a CLOSE statement. */
822
823 tree
824 gfc_trans_close (gfc_code * code)
825 {
826 stmtblock_t block, post_block;
827 gfc_close *p;
828 tree tmp, var;
829 unsigned int mask = 0;
830
831 gfc_start_block (&block);
832 gfc_init_block (&post_block);
833
834 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
835
836 set_error_locus (&block, var, &code->loc);
837 p = code->ext.close;
838
839 if (p->unit)
840 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
841 else
842 set_parameter_const (&block, var, IOPARM_common_unit, 0);
843
844 if (p->status)
845 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
846 p->status);
847
848 if (p->iomsg)
849 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
850 p->iomsg);
851
852 if (p->iostat)
853 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
854 p->iostat);
855
856 if (p->err)
857 mask |= IOPARM_common_err;
858
859 set_parameter_const (&block, var, IOPARM_common_flags, mask);
860
861 tmp = build_fold_addr_expr (var);
862 tmp = gfc_chainon_list (NULL_TREE, tmp);
863 tmp = build_function_call_expr (iocall[IOCALL_CLOSE], tmp);
864 gfc_add_expr_to_block (&block, tmp);
865
866 gfc_add_block_to_block (&block, &post_block);
867
868 io_result (&block, var, p->err, NULL, NULL);
869
870 return gfc_finish_block (&block);
871 }
872
873
874 /* Common subroutine for building a file positioning statement. */
875
876 static tree
877 build_filepos (tree function, gfc_code * code)
878 {
879 stmtblock_t block, post_block;
880 gfc_filepos *p;
881 tree tmp, var;
882 unsigned int mask = 0;
883
884 p = code->ext.filepos;
885
886 gfc_start_block (&block);
887 gfc_init_block (&post_block);
888
889 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
890 "filepos_parm");
891
892 set_error_locus (&block, var, &code->loc);
893
894 if (p->unit)
895 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
896 else
897 set_parameter_const (&block, var, IOPARM_common_unit, 0);
898
899 if (p->iomsg)
900 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
901 p->iomsg);
902
903 if (p->iostat)
904 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
905 p->iostat);
906
907 if (p->err)
908 mask |= IOPARM_common_err;
909
910 set_parameter_const (&block, var, IOPARM_common_flags, mask);
911
912 tmp = build_fold_addr_expr (var);
913 tmp = gfc_chainon_list (NULL_TREE, tmp);
914 tmp = build_function_call_expr (function, tmp);
915 gfc_add_expr_to_block (&block, tmp);
916
917 gfc_add_block_to_block (&block, &post_block);
918
919 io_result (&block, var, p->err, NULL, NULL);
920
921 return gfc_finish_block (&block);
922 }
923
924
925 /* Translate a BACKSPACE statement. */
926
927 tree
928 gfc_trans_backspace (gfc_code * code)
929 {
930 return build_filepos (iocall[IOCALL_BACKSPACE], code);
931 }
932
933
934 /* Translate an ENDFILE statement. */
935
936 tree
937 gfc_trans_endfile (gfc_code * code)
938 {
939 return build_filepos (iocall[IOCALL_ENDFILE], code);
940 }
941
942
943 /* Translate a REWIND statement. */
944
945 tree
946 gfc_trans_rewind (gfc_code * code)
947 {
948 return build_filepos (iocall[IOCALL_REWIND], code);
949 }
950
951
952 /* Translate a FLUSH statement. */
953
954 tree
955 gfc_trans_flush (gfc_code * code)
956 {
957 return build_filepos (iocall[IOCALL_FLUSH], code);
958 }
959
960
961 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
962
963 tree
964 gfc_trans_inquire (gfc_code * code)
965 {
966 stmtblock_t block, post_block;
967 gfc_inquire *p;
968 tree tmp, var;
969 unsigned int mask = 0;
970
971 gfc_start_block (&block);
972 gfc_init_block (&post_block);
973
974 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
975 "inquire_parm");
976
977 set_error_locus (&block, var, &code->loc);
978 p = code->ext.inquire;
979
980 /* Sanity check. */
981 if (p->unit && p->file)
982 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers.", &code->loc);
983
984 if (p->unit)
985 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
986 else
987 set_parameter_const (&block, var, IOPARM_common_unit, 0);
988
989 if (p->file)
990 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
991 p->file);
992
993 if (p->iomsg)
994 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
995 p->iomsg);
996
997 if (p->iostat)
998 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
999 p->iostat);
1000
1001 if (p->exist)
1002 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1003 p->exist);
1004
1005 if (p->opened)
1006 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1007 p->opened);
1008
1009 if (p->number)
1010 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1011 p->number);
1012
1013 if (p->named)
1014 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1015 p->named);
1016
1017 if (p->name)
1018 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1019 p->name);
1020
1021 if (p->access)
1022 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1023 p->access);
1024
1025 if (p->sequential)
1026 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1027 p->sequential);
1028
1029 if (p->direct)
1030 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1031 p->direct);
1032
1033 if (p->form)
1034 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1035 p->form);
1036
1037 if (p->formatted)
1038 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1039 p->formatted);
1040
1041 if (p->unformatted)
1042 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1043 p->unformatted);
1044
1045 if (p->recl)
1046 mask |= set_parameter_ref (&block, &post_block, var,
1047 IOPARM_inquire_recl_out, p->recl);
1048
1049 if (p->nextrec)
1050 mask |= set_parameter_ref (&block, &post_block, var,
1051 IOPARM_inquire_nextrec, p->nextrec);
1052
1053 if (p->blank)
1054 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1055 p->blank);
1056
1057 if (p->position)
1058 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1059 p->position);
1060
1061 if (p->action)
1062 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1063 p->action);
1064
1065 if (p->read)
1066 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1067 p->read);
1068
1069 if (p->write)
1070 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1071 p->write);
1072
1073 if (p->readwrite)
1074 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1075 p->readwrite);
1076
1077 if (p->delim)
1078 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1079 p->delim);
1080
1081 if (p->pad)
1082 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1083 p->pad);
1084
1085 if (p->err)
1086 mask |= IOPARM_common_err;
1087
1088 if (p->convert)
1089 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1090 p->convert);
1091
1092 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1093
1094 tmp = build_fold_addr_expr (var);
1095 tmp = gfc_chainon_list (NULL_TREE, tmp);
1096 tmp = build_function_call_expr (iocall[IOCALL_INQUIRE], tmp);
1097 gfc_add_expr_to_block (&block, tmp);
1098
1099 gfc_add_block_to_block (&block, &post_block);
1100
1101 io_result (&block, var, p->err, NULL, NULL);
1102
1103 return gfc_finish_block (&block);
1104 }
1105
1106 static gfc_expr *
1107 gfc_new_nml_name_expr (const char * name)
1108 {
1109 gfc_expr * nml_name;
1110
1111 nml_name = gfc_get_expr();
1112 nml_name->ref = NULL;
1113 nml_name->expr_type = EXPR_CONSTANT;
1114 nml_name->ts.kind = gfc_default_character_kind;
1115 nml_name->ts.type = BT_CHARACTER;
1116 nml_name->value.character.length = strlen(name);
1117 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
1118 strcpy (nml_name->value.character.string, name);
1119
1120 return nml_name;
1121 }
1122
1123 /* nml_full_name builds up the fully qualified name of a
1124 derived type component. */
1125
1126 static char*
1127 nml_full_name (const char* var_name, const char* cmp_name)
1128 {
1129 int full_name_length;
1130 char * full_name;
1131
1132 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1133 full_name = (char*)gfc_getmem (full_name_length + 1);
1134 strcpy (full_name, var_name);
1135 full_name = strcat (full_name, "%");
1136 full_name = strcat (full_name, cmp_name);
1137 return full_name;
1138 }
1139
1140 /* nml_get_addr_expr builds an address expression from the
1141 gfc_symbol or gfc_component backend_decl's. An offset is
1142 provided so that the address of an element of an array of
1143 derived types is returned. This is used in the runtime to
1144 determine that span of the derived type. */
1145
1146 static tree
1147 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1148 tree base_addr)
1149 {
1150 tree decl = NULL_TREE;
1151 tree tmp;
1152 tree itmp;
1153 int array_flagged;
1154 int dummy_arg_flagged;
1155
1156 if (sym)
1157 {
1158 sym->attr.referenced = 1;
1159 decl = gfc_get_symbol_decl (sym);
1160 }
1161 else
1162 decl = c->backend_decl;
1163
1164 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1165 || TREE_CODE (decl) == VAR_DECL
1166 || TREE_CODE (decl) == PARM_DECL)
1167 || TREE_CODE (decl) == COMPONENT_REF));
1168
1169 tmp = decl;
1170
1171 /* Build indirect reference, if dummy argument. */
1172
1173 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1174
1175 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1176
1177 /* If an array, set flag and use indirect ref. if built. */
1178
1179 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1180 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1181
1182 if (array_flagged)
1183 tmp = itmp;
1184
1185 /* Treat the component of a derived type, using base_addr for
1186 the derived type. */
1187
1188 if (TREE_CODE (decl) == FIELD_DECL)
1189 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1190 base_addr, tmp, NULL_TREE);
1191
1192 /* If we have a derived type component, a reference to the first
1193 element of the array is built. This is done so that base_addr,
1194 used in the build of the component reference, always points to
1195 a RECORD_TYPE. */
1196
1197 if (array_flagged)
1198 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1199
1200 /* Now build the address expression. */
1201
1202 tmp = build_fold_addr_expr (tmp);
1203
1204 /* If scalar dummy, resolve indirect reference now. */
1205
1206 if (dummy_arg_flagged && !array_flagged)
1207 tmp = build_fold_indirect_ref (tmp);
1208
1209 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1210
1211 return tmp;
1212 }
1213
1214 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1215 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1216 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1217
1218 #define NML_FIRST_ARG(a) args = gfc_chainon_list (NULL_TREE, a)
1219 #define NML_ADD_ARG(a) args = gfc_chainon_list (args, a)
1220 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1221
1222 static void
1223 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1224 gfc_symbol * sym, gfc_component * c,
1225 tree base_addr)
1226 {
1227 gfc_typespec * ts = NULL;
1228 gfc_array_spec * as = NULL;
1229 tree addr_expr = NULL;
1230 tree dt = NULL;
1231 tree string;
1232 tree tmp;
1233 tree args;
1234 tree dtype;
1235 tree dt_parm_addr;
1236 int n_dim;
1237 int itype;
1238 int rank = 0;
1239
1240 gcc_assert (sym || c);
1241
1242 /* Build the namelist object name. */
1243
1244 string = gfc_build_cstring_const (var_name);
1245 string = gfc_build_addr_expr (pchar_type_node, string);
1246
1247 /* Build ts, as and data address using symbol or component. */
1248
1249 ts = (sym) ? &sym->ts : &c->ts;
1250 as = (sym) ? sym->as : c->as;
1251
1252 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1253
1254 if (as)
1255 rank = as->rank;
1256
1257 if (rank)
1258 {
1259 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1260 dtype = gfc_get_dtype (dt);
1261 }
1262 else
1263 {
1264 itype = GFC_DTYPE_UNKNOWN;
1265
1266 switch (ts->type)
1267
1268 {
1269 case BT_INTEGER:
1270 itype = GFC_DTYPE_INTEGER;
1271 break;
1272 case BT_LOGICAL:
1273 itype = GFC_DTYPE_LOGICAL;
1274 break;
1275 case BT_REAL:
1276 itype = GFC_DTYPE_REAL;
1277 break;
1278 case BT_COMPLEX:
1279 itype = GFC_DTYPE_COMPLEX;
1280 break;
1281 case BT_DERIVED:
1282 itype = GFC_DTYPE_DERIVED;
1283 break;
1284 case BT_CHARACTER:
1285 itype = GFC_DTYPE_CHARACTER;
1286 break;
1287 default:
1288 gcc_unreachable ();
1289 }
1290
1291 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1292 }
1293
1294 /* Build up the arguments for the transfer call.
1295 The call for the scalar part transfers:
1296 (address, name, type, kind or string_length, dtype) */
1297
1298 dt_parm_addr = build_fold_addr_expr (dt_parm);
1299 NML_FIRST_ARG (dt_parm_addr);
1300 NML_ADD_ARG (addr_expr);
1301 NML_ADD_ARG (string);
1302 NML_ADD_ARG (IARG (ts->kind));
1303
1304 if (ts->type == BT_CHARACTER)
1305 NML_ADD_ARG (ts->cl->backend_decl);
1306 else
1307 NML_ADD_ARG (convert (gfc_charlen_type_node, integer_zero_node));
1308
1309 NML_ADD_ARG (dtype);
1310 tmp = build_function_call_expr (iocall[IOCALL_SET_NML_VAL], args);
1311 gfc_add_expr_to_block (block, tmp);
1312
1313 /* If the object is an array, transfer rank times:
1314 (null pointer, name, stride, lbound, ubound) */
1315
1316 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1317 {
1318 NML_FIRST_ARG (dt_parm_addr);
1319 NML_ADD_ARG (IARG (n_dim));
1320 NML_ADD_ARG (GFC_TYPE_ARRAY_STRIDE (dt, n_dim));
1321 NML_ADD_ARG (GFC_TYPE_ARRAY_LBOUND (dt, n_dim));
1322 NML_ADD_ARG (GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1323 tmp = build_function_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], args);
1324 gfc_add_expr_to_block (block, tmp);
1325 }
1326
1327 if (ts->type == BT_DERIVED)
1328 {
1329 gfc_component *cmp;
1330
1331 /* Provide the RECORD_TYPE to build component references. */
1332
1333 tree expr = build_fold_indirect_ref (addr_expr);
1334
1335 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1336 {
1337 char *full_name = nml_full_name (var_name, cmp->name);
1338 transfer_namelist_element (block,
1339 full_name,
1340 NULL, cmp, expr);
1341 gfc_free (full_name);
1342 }
1343 }
1344 }
1345
1346 #undef IARG
1347 #undef NML_ADD_ARG
1348 #undef NML_FIRST_ARG
1349
1350 /* Create a data transfer statement. Not all of the fields are valid
1351 for both reading and writing, but improper use has been filtered
1352 out by now. */
1353
1354 static tree
1355 build_dt (tree function, gfc_code * code)
1356 {
1357 stmtblock_t block, post_block, post_end_block;
1358 gfc_dt *dt;
1359 tree tmp, var;
1360 gfc_expr *nmlname;
1361 gfc_namelist *nml;
1362 unsigned int mask = 0;
1363
1364 gfc_start_block (&block);
1365 gfc_init_block (&post_block);
1366 gfc_init_block (&post_end_block);
1367
1368 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1369
1370 set_error_locus (&block, var, &code->loc);
1371
1372 if (last_dt == IOLENGTH)
1373 {
1374 gfc_inquire *inq;
1375
1376 inq = code->ext.inquire;
1377
1378 /* First check that preconditions are met. */
1379 gcc_assert (inq != NULL);
1380 gcc_assert (inq->iolength != NULL);
1381
1382 /* Connect to the iolength variable. */
1383 mask |= set_parameter_ref (&block, &post_end_block, var,
1384 IOPARM_dt_iolength, inq->iolength);
1385 dt = NULL;
1386 }
1387 else
1388 {
1389 dt = code->ext.dt;
1390 gcc_assert (dt != NULL);
1391 }
1392
1393 if (dt && dt->io_unit)
1394 {
1395 if (dt->io_unit->ts.type == BT_CHARACTER)
1396 {
1397 mask |= set_internal_unit (&block, var, dt->io_unit);
1398 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1399 }
1400 else
1401 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1402 }
1403 else
1404 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1405
1406 if (dt)
1407 {
1408 if (dt->rec)
1409 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1410
1411 if (dt->advance)
1412 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1413 dt->advance);
1414
1415 if (dt->format_expr)
1416 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1417 dt->format_expr);
1418
1419 if (dt->format_label)
1420 {
1421 if (dt->format_label == &format_asterisk)
1422 mask |= IOPARM_dt_list_format;
1423 else
1424 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1425 dt->format_label->format);
1426 }
1427
1428 if (dt->iomsg)
1429 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1430 dt->iomsg);
1431
1432 if (dt->iostat)
1433 mask |= set_parameter_ref (&block, &post_end_block, var,
1434 IOPARM_common_iostat, dt->iostat);
1435
1436 if (dt->size)
1437 mask |= set_parameter_ref (&block, &post_end_block, var,
1438 IOPARM_dt_size, dt->size);
1439
1440 if (dt->err)
1441 mask |= IOPARM_common_err;
1442
1443 if (dt->eor)
1444 mask |= IOPARM_common_eor;
1445
1446 if (dt->end)
1447 mask |= IOPARM_common_end;
1448
1449 if (dt->namelist)
1450 {
1451 if (dt->format_expr || dt->format_label)
1452 gfc_internal_error ("build_dt: format with namelist");
1453
1454 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1455
1456 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1457 nmlname);
1458
1459 if (last_dt == READ)
1460 mask |= IOPARM_dt_namelist_read_mode;
1461
1462 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1463
1464 dt_parm = var;
1465
1466 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1467 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1468 NULL, NULL);
1469 }
1470 else
1471 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1472 }
1473 else
1474 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1475
1476 tmp = build_fold_addr_expr (var);
1477 tmp = gfc_chainon_list (NULL_TREE, tmp);
1478 tmp = build_function_call_expr (function, tmp);
1479 gfc_add_expr_to_block (&block, tmp);
1480
1481 gfc_add_block_to_block (&block, &post_block);
1482
1483 dt_parm = var;
1484 dt_post_end_block = &post_end_block;
1485
1486 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1487
1488 dt_parm = NULL;
1489 dt_post_end_block = NULL;
1490
1491 return gfc_finish_block (&block);
1492 }
1493
1494
1495 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1496 this as a third sort of data transfer statement, except that
1497 lengths are summed instead of actually transferring any data. */
1498
1499 tree
1500 gfc_trans_iolength (gfc_code * code)
1501 {
1502 last_dt = IOLENGTH;
1503 return build_dt (iocall[IOCALL_IOLENGTH], code);
1504 }
1505
1506
1507 /* Translate a READ statement. */
1508
1509 tree
1510 gfc_trans_read (gfc_code * code)
1511 {
1512 last_dt = READ;
1513 return build_dt (iocall[IOCALL_READ], code);
1514 }
1515
1516
1517 /* Translate a WRITE statement */
1518
1519 tree
1520 gfc_trans_write (gfc_code * code)
1521 {
1522 last_dt = WRITE;
1523 return build_dt (iocall[IOCALL_WRITE], code);
1524 }
1525
1526
1527 /* Finish a data transfer statement. */
1528
1529 tree
1530 gfc_trans_dt_end (gfc_code * code)
1531 {
1532 tree function, tmp;
1533 stmtblock_t block;
1534
1535 gfc_init_block (&block);
1536
1537 switch (last_dt)
1538 {
1539 case READ:
1540 function = iocall[IOCALL_READ_DONE];
1541 break;
1542
1543 case WRITE:
1544 function = iocall[IOCALL_WRITE_DONE];
1545 break;
1546
1547 case IOLENGTH:
1548 function = iocall[IOCALL_IOLENGTH_DONE];
1549 break;
1550
1551 default:
1552 gcc_unreachable ();
1553 }
1554
1555 tmp = build_fold_addr_expr (dt_parm);
1556 tmp = gfc_chainon_list (NULL_TREE, tmp);
1557 tmp = build_function_call_expr (function, tmp);
1558 gfc_add_expr_to_block (&block, tmp);
1559 gfc_add_block_to_block (&block, dt_post_end_block);
1560 gfc_init_block (dt_post_end_block);
1561
1562 if (last_dt != IOLENGTH)
1563 {
1564 gcc_assert (code->ext.dt != NULL);
1565 io_result (&block, dt_parm, code->ext.dt->err,
1566 code->ext.dt->end, code->ext.dt->eor);
1567 }
1568
1569 return gfc_finish_block (&block);
1570 }
1571
1572 static void
1573 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr);
1574
1575 /* Given an array field in a derived type variable, generate the code
1576 for the loop that iterates over array elements, and the code that
1577 accesses those array elements. Use transfer_expr to generate code
1578 for transferring that element. Because elements may also be
1579 derived types, transfer_expr and transfer_array_component are mutually
1580 recursive. */
1581
1582 static tree
1583 transfer_array_component (tree expr, gfc_component * cm)
1584 {
1585 tree tmp;
1586 stmtblock_t body;
1587 stmtblock_t block;
1588 gfc_loopinfo loop;
1589 int n;
1590 gfc_ss *ss;
1591 gfc_se se;
1592
1593 gfc_start_block (&block);
1594 gfc_init_se (&se, NULL);
1595
1596 /* Create and initialize Scalarization Status. Unlike in
1597 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1598 care of this task, because we don't have a gfc_expr at hand.
1599 Build one manually, as in gfc_trans_subarray_assign. */
1600
1601 ss = gfc_get_ss ();
1602 ss->type = GFC_SS_COMPONENT;
1603 ss->expr = NULL;
1604 ss->shape = gfc_get_shape (cm->as->rank);
1605 ss->next = gfc_ss_terminator;
1606 ss->data.info.dimen = cm->as->rank;
1607 ss->data.info.descriptor = expr;
1608 ss->data.info.data = gfc_conv_array_data (expr);
1609 ss->data.info.offset = gfc_conv_array_offset (expr);
1610 for (n = 0; n < cm->as->rank; n++)
1611 {
1612 ss->data.info.dim[n] = n;
1613 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1614 ss->data.info.stride[n] = gfc_index_one_node;
1615
1616 mpz_init (ss->shape[n]);
1617 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1618 cm->as->lower[n]->value.integer);
1619 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1620 }
1621
1622 /* Once we got ss, we use scalarizer to create the loop. */
1623
1624 gfc_init_loopinfo (&loop);
1625 gfc_add_ss_to_loop (&loop, ss);
1626 gfc_conv_ss_startstride (&loop);
1627 gfc_conv_loop_setup (&loop);
1628 gfc_mark_ss_chain_used (ss, 1);
1629 gfc_start_scalarized_body (&loop, &body);
1630
1631 gfc_copy_loopinfo_to_se (&se, &loop);
1632 se.ss = ss;
1633
1634 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1635 se.expr = expr;
1636 gfc_conv_tmp_array_ref (&se);
1637
1638 /* Now se.expr contains an element of the array. Take the address and pass
1639 it to the IO routines. */
1640 tmp = build_fold_addr_expr (se.expr);
1641 transfer_expr (&se, &cm->ts, tmp);
1642
1643 /* We are done now with the loop body. Wrap up the scalarizer and
1644 return. */
1645
1646 gfc_add_block_to_block (&body, &se.pre);
1647 gfc_add_block_to_block (&body, &se.post);
1648
1649 gfc_trans_scalarizing_loops (&loop, &body);
1650
1651 gfc_add_block_to_block (&block, &loop.pre);
1652 gfc_add_block_to_block (&block, &loop.post);
1653
1654 for (n = 0; n < cm->as->rank; n++)
1655 mpz_clear (ss->shape[n]);
1656 gfc_free (ss->shape);
1657
1658 gfc_cleanup_loop (&loop);
1659
1660 return gfc_finish_block (&block);
1661 }
1662
1663 /* Generate the call for a scalar transfer node. */
1664
1665 static void
1666 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1667 {
1668 tree args, tmp, function, arg2, field, expr;
1669 gfc_component *c;
1670 int kind;
1671
1672 kind = ts->kind;
1673 function = NULL;
1674 arg2 = NULL;
1675
1676 switch (ts->type)
1677 {
1678 case BT_INTEGER:
1679 arg2 = build_int_cst (NULL_TREE, kind);
1680 function = iocall[IOCALL_X_INTEGER];
1681 break;
1682
1683 case BT_REAL:
1684 arg2 = build_int_cst (NULL_TREE, kind);
1685 function = iocall[IOCALL_X_REAL];
1686 break;
1687
1688 case BT_COMPLEX:
1689 arg2 = build_int_cst (NULL_TREE, kind);
1690 function = iocall[IOCALL_X_COMPLEX];
1691 break;
1692
1693 case BT_LOGICAL:
1694 arg2 = build_int_cst (NULL_TREE, kind);
1695 function = iocall[IOCALL_X_LOGICAL];
1696 break;
1697
1698 case BT_CHARACTER:
1699 if (se->string_length)
1700 arg2 = se->string_length;
1701 else
1702 {
1703 tmp = build_fold_indirect_ref (addr_expr);
1704 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1705 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1706 }
1707 function = iocall[IOCALL_X_CHARACTER];
1708 break;
1709
1710 case BT_DERIVED:
1711 /* Recurse into the elements of the derived type. */
1712 expr = gfc_evaluate_now (addr_expr, &se->pre);
1713 expr = build_fold_indirect_ref (expr);
1714
1715 for (c = ts->derived->components; c; c = c->next)
1716 {
1717 field = c->backend_decl;
1718 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1719
1720 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1721 NULL_TREE);
1722
1723 if (c->dimension)
1724 {
1725 tmp = transfer_array_component (tmp, c);
1726 gfc_add_expr_to_block (&se->pre, tmp);
1727 }
1728 else
1729 {
1730 if (!c->pointer)
1731 tmp = build_fold_addr_expr (tmp);
1732 transfer_expr (se, &c->ts, tmp);
1733 }
1734 }
1735 return;
1736
1737 default:
1738 internal_error ("Bad IO basetype (%d)", ts->type);
1739 }
1740
1741 tmp = build_fold_addr_expr (dt_parm);
1742 args = gfc_chainon_list (NULL_TREE, tmp);
1743 args = gfc_chainon_list (args, addr_expr);
1744 args = gfc_chainon_list (args, arg2);
1745
1746 tmp = build_function_call_expr (function, args);
1747 gfc_add_expr_to_block (&se->pre, tmp);
1748 gfc_add_block_to_block (&se->pre, &se->post);
1749
1750 }
1751
1752
1753 /* Generate a call to pass an array descriptor to the IO library. The
1754 array should be of one of the intrinsic types. */
1755
1756 static void
1757 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1758 {
1759 tree args, tmp, charlen_arg, kind_arg;
1760
1761 if (ts->type == BT_CHARACTER)
1762 charlen_arg = se->string_length;
1763 else
1764 charlen_arg = build_int_cstu (NULL_TREE, 0);
1765
1766 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1767
1768 tmp = build_fold_addr_expr (dt_parm);
1769 args = gfc_chainon_list (NULL_TREE, tmp);
1770 args = gfc_chainon_list (args, addr_expr);
1771 args = gfc_chainon_list (args, kind_arg);
1772 args = gfc_chainon_list (args, charlen_arg);
1773 tmp = build_function_call_expr (iocall[IOCALL_X_ARRAY], args);
1774 gfc_add_expr_to_block (&se->pre, tmp);
1775 gfc_add_block_to_block (&se->pre, &se->post);
1776 }
1777
1778
1779 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1780
1781 tree
1782 gfc_trans_transfer (gfc_code * code)
1783 {
1784 stmtblock_t block, body;
1785 gfc_loopinfo loop;
1786 gfc_expr *expr;
1787 gfc_ref *ref;
1788 gfc_ss *ss;
1789 gfc_se se;
1790 tree tmp;
1791
1792 gfc_start_block (&block);
1793 gfc_init_block (&body);
1794
1795 expr = code->expr;
1796 ss = gfc_walk_expr (expr);
1797
1798 ref = NULL;
1799 gfc_init_se (&se, NULL);
1800
1801 if (ss == gfc_ss_terminator)
1802 {
1803 /* Transfer a scalar value. */
1804 gfc_conv_expr_reference (&se, expr);
1805 transfer_expr (&se, &expr->ts, se.expr);
1806 }
1807 else
1808 {
1809 /* Transfer an array. If it is an array of an intrinsic
1810 type, pass the descriptor to the library. Otherwise
1811 scalarize the transfer. */
1812 if (expr->ref)
1813 {
1814 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
1815 ref = ref->next);
1816 gcc_assert (ref->type == REF_ARRAY);
1817 }
1818
1819 if (expr->ts.type != BT_DERIVED && ref && ref->next == NULL)
1820 {
1821 /* Get the descriptor. */
1822 gfc_conv_expr_descriptor (&se, expr, ss);
1823 tmp = build_fold_addr_expr (se.expr);
1824 transfer_array_desc (&se, &expr->ts, tmp);
1825 goto finish_block_label;
1826 }
1827
1828 /* Initialize the scalarizer. */
1829 gfc_init_loopinfo (&loop);
1830 gfc_add_ss_to_loop (&loop, ss);
1831
1832 /* Initialize the loop. */
1833 gfc_conv_ss_startstride (&loop);
1834 gfc_conv_loop_setup (&loop);
1835
1836 /* The main loop body. */
1837 gfc_mark_ss_chain_used (ss, 1);
1838 gfc_start_scalarized_body (&loop, &body);
1839
1840 gfc_copy_loopinfo_to_se (&se, &loop);
1841 se.ss = ss;
1842
1843 gfc_conv_expr_reference (&se, expr);
1844 transfer_expr (&se, &expr->ts, se.expr);
1845 }
1846
1847 finish_block_label:
1848
1849 gfc_add_block_to_block (&body, &se.pre);
1850 gfc_add_block_to_block (&body, &se.post);
1851
1852 if (se.ss == NULL)
1853 tmp = gfc_finish_block (&body);
1854 else
1855 {
1856 gcc_assert (se.ss == gfc_ss_terminator);
1857 gfc_trans_scalarizing_loops (&loop, &body);
1858
1859 gfc_add_block_to_block (&loop.pre, &loop.post);
1860 tmp = gfc_finish_block (&loop.pre);
1861 gfc_cleanup_loop (&loop);
1862 }
1863
1864 gfc_add_expr_to_block (&block, tmp);
1865
1866 return gfc_finish_block (&block);
1867 }
1868
1869 #include "gt-fortran-trans-io.h"
1870