]> gcc.gnu.org Git - gcc.git/blob - gcc/fortran/trans-io.c
re PR fortran/31675 (Fortran front-end and libgfortran should have a common header...
[gcc.git] / gcc / fortran / trans-io.c
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
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>. */
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 /* Members of the ioparm structure. */
39
40 enum ioparam_type
41 {
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
49 };
50
51 enum iofield_type
52 {
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
64 };
65
66 typedef struct gfc_st_parameter_field GTY(())
67 {
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;
74 }
75 gfc_st_parameter_field;
76
77 typedef struct gfc_st_parameter GTY(())
78 {
79 const char *name;
80 tree type;
81 }
82 gfc_st_parameter;
83
84 enum iofield
85 {
86 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
87 #include "ioparm.def"
88 #undef IOPARM
89 IOPARM_field_num
90 };
91
92 static GTY(()) gfc_st_parameter st_parameter[] =
93 {
94 { "common", NULL },
95 { "open", NULL },
96 { "close", NULL },
97 { "filepos", NULL },
98 { "inquire", NULL },
99 { "dt", NULL }
100 };
101
102 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
103 {
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 }
109 };
110
111 /* Library I/O subroutines */
112
113 enum iocall
114 {
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
137 };
138
139 static GTY(()) tree iocall[IOCALL_NUM];
140
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;
145
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;
150
151 static void
152 gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
153 {
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);
159
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);
166
167 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
168 if (p->param_type == ptype)
169 switch (p->type)
170 {
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 ();
208 }
209
210 gfc_finish_type (t);
211 st_parameter[ptype].type = t;
212 }
213
214
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. */
221
222 void
223 gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
224 const char * msgid, stmtblock_t * pblock)
225 {
226 stmtblock_t block;
227 tree body;
228 tree tmp;
229 tree arg1, arg2, arg3;
230 char *message;
231
232 if (integer_zerop (cond))
233 return;
234
235 /* The code to generate the error. */
236 gfc_start_block (&block);
237
238 arg1 = build_fold_addr_expr (var);
239
240 arg2 = build_int_cst (integer_type_node, error_code),
241
242 asprintf (&message, "%s", _(msgid));
243 arg3 = gfc_build_addr_expr (pchar_type_node, gfc_build_cstring_const(message));
244 gfc_free(message);
245
246 tmp = build_call_expr (gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
247
248 gfc_add_expr_to_block (&block, tmp);
249
250 body = gfc_finish_block (&block);
251
252 if (integer_onep (cond))
253 {
254 gfc_add_expr_to_block (pblock, body);
255 }
256 else
257 {
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);
263
264 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
265 gfc_add_expr_to_block (pblock, tmp);
266 }
267 }
268
269
270 /* Create function decls for IO library functions. */
271
272 void
273 gfc_build_io_library_fndecls (void)
274 {
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;
280
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);
293
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)));
300
301 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
302 gfc_build_st_parameter (ptype, types);
303
304 /* Define the transfer functions. */
305
306 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
307
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);
313
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);
319
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);
325
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);
330
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);
336
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);
343
344 /* Library entry points */
345
346 iocall[IOCALL_READ] =
347 gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
348 void_type_node, 1, dt_parm_type);
349
350 iocall[IOCALL_WRITE] =
351 gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
352 void_type_node, 1, dt_parm_type);
353
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);
358
359
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);
364
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);
369
370 iocall[IOCALL_IOLENGTH] =
371 gfc_build_library_function_decl(get_identifier (PREFIX("st_iolength")),
372 void_type_node, 1, dt_parm_type);
373
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);
378
379 iocall[IOCALL_BACKSPACE] =
380 gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
381 gfc_int4_type_node, 1, parm_type);
382
383 iocall[IOCALL_ENDFILE] =
384 gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
385 gfc_int4_type_node, 1, parm_type);
386
387 iocall[IOCALL_FLUSH] =
388 gfc_build_library_function_decl (get_identifier (PREFIX("st_flush")),
389 gfc_int4_type_node, 1, parm_type);
390
391 /* Library helpers */
392
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);
396
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);
400
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);
404
405
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);
412
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);
418 }
419
420
421 /* Generate code to store an integer constant into the
422 st_parameter_XXX structure. */
423
424 static unsigned int
425 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
426 unsigned int val)
427 {
428 tree tmp;
429 gfc_st_parameter_field *p = &st_parameter_field[type];
430
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;
438 }
439
440
441 /* Generate code to store a non-string I/O parameter into the
442 st_parameter_XXX structure. This is a pass by value. */
443
444 static unsigned int
445 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
446 gfc_expr *e)
447 {
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);
452
453 gfc_init_se (&se, NULL);
454 gfc_conv_expr_val (&se, e);
455
456 /* If we're storing a UNIT number, we need to check it first. */
457 if (type == IOPARM_common_unit && e->ts.kind != 4)
458 {
459 tree cond, max;
460 int i;
461
462 /* Don't evaluate the UNIT number multiple times. */
463 se.expr = gfc_evaluate_now (se.expr, &se.pre);
464
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);
471
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);
480
481 }
482
483 se.expr = convert (dest_type, se.expr);
484 gfc_add_block_to_block (block, &se.pre);
485
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);
489
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;
493 }
494
495
496 /* Generate code to store a non-string I/O parameter into the
497 st_parameter_XXX structure. This is pass by reference. */
498
499 static unsigned int
500 set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
501 tree var, enum iofield type, gfc_expr *e)
502 {
503 gfc_se se;
504 tree tmp, addr;
505 gfc_st_parameter_field *p = &st_parameter_field[type];
506
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);
510
511 gfc_add_block_to_block (block, &se.pre);
512
513 if (TYPE_MODE (TREE_TYPE (se.expr))
514 == TYPE_MODE (TREE_TYPE (TREE_TYPE (p->field))))
515 {
516 addr = convert (TREE_TYPE (p->field), build_fold_addr_expr (se.expr));
517
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));
523 }
524 else
525 {
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);
531
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));
537
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);
542 }
543
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;
551 }
552
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.
558 */
559
560 static void
561 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
562 {
563 tree tmp;
564 tree array;
565 tree type;
566 tree size;
567 int rank;
568 gfc_symbol *sym;
569
570 sym = e->symtree->n.sym;
571 rank = sym->as->rank - 1;
572
573 if (e->ref->u.ar.type == AR_FULL)
574 {
575 se->expr = gfc_get_symbol_decl (sym);
576 se->expr = gfc_conv_array_data (se->expr);
577 }
578 else
579 {
580 gfc_conv_expr (se, e);
581 }
582
583 array = sym->backend_decl;
584 type = TREE_TYPE (array);
585
586 if (GFC_ARRAY_TYPE_P (type))
587 size = GFC_TYPE_ARRAY_SIZE (type);
588 else
589 {
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);
598 }
599
600 gcc_assert (size);
601
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)
604 {
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);
608 }
609
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));
613
614 se->string_length = fold_convert (gfc_charlen_type_node, size);
615 }
616
617
618 /* Generate code to store a string and its length into the
619 st_parameter_XXX structure. */
620
621 static unsigned int
622 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
623 enum iofield type, gfc_expr * e)
624 {
625 gfc_se se;
626 tree tmp;
627 tree io;
628 tree len;
629 gfc_st_parameter_field *p = &st_parameter_field[type];
630
631 gfc_init_se (&se, NULL);
632
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);
640
641 /* Integer variable assigned a format label. */
642 if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
643 {
644 char * msg;
645 tree cond;
646
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));
651
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);
657
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));
661 }
662 else
663 {
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 ();
672
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);
676 }
677
678 gfc_add_block_to_block (block, &se.pre);
679 gfc_add_block_to_block (postblock, &se.post);
680 return p->mask;
681 }
682
683
684 /* Generate code to store the character (array) and the character length
685 for an internal unit. */
686
687 static unsigned int
688 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
689 tree var, gfc_expr * e)
690 {
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;
698
699 gfc_init_se (&se, NULL);
700
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);
710
711 gcc_assert (e->ts.type == BT_CHARACTER);
712
713 /* Character scalars. */
714 if (e->rank == 0)
715 {
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);
720 }
721
722 /* Character array. */
723 else if (e->rank > 0)
724 {
725 se.ss = gfc_walk_expr (e);
726
727 if (is_aliased_array (e))
728 {
729 /* Use a temporary for components of arrays of derived types
730 or substring array references. */
731 gfc_conv_aliased_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);
736 }
737 else
738 {
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);
743 }
744 }
745 else
746 gcc_unreachable ();
747
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);
754
755 gfc_add_block_to_block (block, &se.pre);
756 gfc_add_block_to_block (post_block, &se.post);
757 return mask;
758 }
759
760 /* Add a case to a IO-result switch. */
761
762 static void
763 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
764 {
765 tree tmp, value;
766
767 if (label == NULL)
768 return; /* No label, no case */
769
770 value = build_int_cst (NULL_TREE, label_value);
771
772 /* Make a backend label for this case. */
773 tmp = gfc_build_label_decl (NULL_TREE);
774
775 /* And the case itself. */
776 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
777 gfc_add_expr_to_block (body, tmp);
778
779 /* Jump to the label. */
780 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
781 gfc_add_expr_to_block (body, tmp);
782 }
783
784
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. */
790
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)
794 {
795 stmtblock_t body;
796 tree tmp, rc;
797 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
798
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;
805
806 /* Build a switch statement. */
807 gfc_start_block (&body);
808
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);
814
815 tmp = gfc_finish_block (&body);
816
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));
823
824 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
825
826 gfc_add_expr_to_block (block, tmp);
827 }
828
829
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. */
832
833 static void
834 set_error_locus (stmtblock_t * block, tree var, locus * where)
835 {
836 gfc_file *f;
837 tree str, locus_file;
838 int line;
839 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
840
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);
847
848 str = gfc_build_addr_expr (pchar_type_node, str);
849 gfc_add_modify_expr (block, locus_file, str);
850
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);
857 }
858
859
860 /* Translate an OPEN statement. */
861
862 tree
863 gfc_trans_open (gfc_code * code)
864 {
865 stmtblock_t block, post_block;
866 gfc_open *p;
867 tree tmp, var;
868 unsigned int mask = 0;
869
870 gfc_start_block (&block);
871 gfc_init_block (&post_block);
872
873 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
874
875 set_error_locus (&block, var, &code->loc);
876 p = code->ext.open;
877
878 if (p->iomsg)
879 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
880 p->iomsg);
881
882 if (p->iostat)
883 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
884 p->iostat);
885
886 if (p->err)
887 mask |= IOPARM_common_err;
888
889 if (p->file)
890 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
891
892 if (p->status)
893 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
894 p->status);
895
896 if (p->access)
897 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
898 p->access);
899
900 if (p->form)
901 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
902
903 if (p->recl)
904 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
905
906 if (p->blank)
907 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
908 p->blank);
909
910 if (p->position)
911 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
912 p->position);
913
914 if (p->action)
915 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
916 p->action);
917
918 if (p->delim)
919 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
920 p->delim);
921
922 if (p->pad)
923 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
924
925 if (p->convert)
926 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
927 p->convert);
928
929 set_parameter_const (&block, var, IOPARM_common_flags, mask);
930
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);
935
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);
939
940 gfc_add_block_to_block (&block, &post_block);
941
942 io_result (&block, var, p->err, NULL, NULL);
943
944 return gfc_finish_block (&block);
945 }
946
947
948 /* Translate a CLOSE statement. */
949
950 tree
951 gfc_trans_close (gfc_code * code)
952 {
953 stmtblock_t block, post_block;
954 gfc_close *p;
955 tree tmp, var;
956 unsigned int mask = 0;
957
958 gfc_start_block (&block);
959 gfc_init_block (&post_block);
960
961 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
962
963 set_error_locus (&block, var, &code->loc);
964 p = code->ext.close;
965
966 if (p->iomsg)
967 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
968 p->iomsg);
969
970 if (p->iostat)
971 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
972 p->iostat);
973
974 if (p->err)
975 mask |= IOPARM_common_err;
976
977 if (p->status)
978 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
979 p->status);
980
981 set_parameter_const (&block, var, IOPARM_common_flags, mask);
982
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);
987
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);
991
992 gfc_add_block_to_block (&block, &post_block);
993
994 io_result (&block, var, p->err, NULL, NULL);
995
996 return gfc_finish_block (&block);
997 }
998
999
1000 /* Common subroutine for building a file positioning statement. */
1001
1002 static tree
1003 build_filepos (tree function, gfc_code * code)
1004 {
1005 stmtblock_t block, post_block;
1006 gfc_filepos *p;
1007 tree tmp, var;
1008 unsigned int mask = 0;
1009
1010 p = code->ext.filepos;
1011
1012 gfc_start_block (&block);
1013 gfc_init_block (&post_block);
1014
1015 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
1016 "filepos_parm");
1017
1018 set_error_locus (&block, var, &code->loc);
1019
1020 if (p->iomsg)
1021 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1022 p->iomsg);
1023
1024 if (p->iostat)
1025 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1026 p->iostat);
1027
1028 if (p->err)
1029 mask |= IOPARM_common_err;
1030
1031 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1032
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);
1037
1038 tmp = build_fold_addr_expr (var);
1039 tmp = build_call_expr (function, 1, tmp);
1040 gfc_add_expr_to_block (&block, tmp);
1041
1042 gfc_add_block_to_block (&block, &post_block);
1043
1044 io_result (&block, var, p->err, NULL, NULL);
1045
1046 return gfc_finish_block (&block);
1047 }
1048
1049
1050 /* Translate a BACKSPACE statement. */
1051
1052 tree
1053 gfc_trans_backspace (gfc_code * code)
1054 {
1055 return build_filepos (iocall[IOCALL_BACKSPACE], code);
1056 }
1057
1058
1059 /* Translate an ENDFILE statement. */
1060
1061 tree
1062 gfc_trans_endfile (gfc_code * code)
1063 {
1064 return build_filepos (iocall[IOCALL_ENDFILE], code);
1065 }
1066
1067
1068 /* Translate a REWIND statement. */
1069
1070 tree
1071 gfc_trans_rewind (gfc_code * code)
1072 {
1073 return build_filepos (iocall[IOCALL_REWIND], code);
1074 }
1075
1076
1077 /* Translate a FLUSH statement. */
1078
1079 tree
1080 gfc_trans_flush (gfc_code * code)
1081 {
1082 return build_filepos (iocall[IOCALL_FLUSH], code);
1083 }
1084
1085
1086 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
1087
1088 tree
1089 gfc_trans_inquire (gfc_code * code)
1090 {
1091 stmtblock_t block, post_block;
1092 gfc_inquire *p;
1093 tree tmp, var;
1094 unsigned int mask = 0;
1095
1096 gfc_start_block (&block);
1097 gfc_init_block (&post_block);
1098
1099 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1100 "inquire_parm");
1101
1102 set_error_locus (&block, var, &code->loc);
1103 p = code->ext.inquire;
1104
1105 if (p->iomsg)
1106 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1107 p->iomsg);
1108
1109 if (p->iostat)
1110 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1111 p->iostat);
1112
1113 if (p->err)
1114 mask |= IOPARM_common_err;
1115
1116 /* Sanity check. */
1117 if (p->unit && p->file)
1118 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1119
1120 if (p->file)
1121 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1122 p->file);
1123
1124 if (p->exist)
1125 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1126 p->exist);
1127
1128 if (p->opened)
1129 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1130 p->opened);
1131
1132 if (p->number)
1133 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1134 p->number);
1135
1136 if (p->named)
1137 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1138 p->named);
1139
1140 if (p->name)
1141 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1142 p->name);
1143
1144 if (p->access)
1145 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1146 p->access);
1147
1148 if (p->sequential)
1149 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1150 p->sequential);
1151
1152 if (p->direct)
1153 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1154 p->direct);
1155
1156 if (p->form)
1157 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1158 p->form);
1159
1160 if (p->formatted)
1161 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1162 p->formatted);
1163
1164 if (p->unformatted)
1165 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1166 p->unformatted);
1167
1168 if (p->recl)
1169 mask |= set_parameter_ref (&block, &post_block, var,
1170 IOPARM_inquire_recl_out, p->recl);
1171
1172 if (p->nextrec)
1173 mask |= set_parameter_ref (&block, &post_block, var,
1174 IOPARM_inquire_nextrec, p->nextrec);
1175
1176 if (p->blank)
1177 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1178 p->blank);
1179
1180 if (p->position)
1181 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1182 p->position);
1183
1184 if (p->action)
1185 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1186 p->action);
1187
1188 if (p->read)
1189 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1190 p->read);
1191
1192 if (p->write)
1193 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1194 p->write);
1195
1196 if (p->readwrite)
1197 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1198 p->readwrite);
1199
1200 if (p->delim)
1201 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1202 p->delim);
1203
1204 if (p->pad)
1205 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1206 p->pad);
1207
1208 if (p->convert)
1209 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1210 p->convert);
1211
1212 if (p->strm_pos)
1213 mask |= set_parameter_ref (&block, &post_block, var,
1214 IOPARM_inquire_strm_pos_out, p->strm_pos);
1215
1216 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1217
1218 if (p->unit)
1219 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1220 else
1221 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1222
1223 tmp = build_fold_addr_expr (var);
1224 tmp = build_call_expr (iocall[IOCALL_INQUIRE], 1, tmp);
1225 gfc_add_expr_to_block (&block, tmp);
1226
1227 gfc_add_block_to_block (&block, &post_block);
1228
1229 io_result (&block, var, p->err, NULL, NULL);
1230
1231 return gfc_finish_block (&block);
1232 }
1233
1234 static gfc_expr *
1235 gfc_new_nml_name_expr (const char * name)
1236 {
1237 gfc_expr * nml_name;
1238
1239 nml_name = gfc_get_expr();
1240 nml_name->ref = NULL;
1241 nml_name->expr_type = EXPR_CONSTANT;
1242 nml_name->ts.kind = gfc_default_character_kind;
1243 nml_name->ts.type = BT_CHARACTER;
1244 nml_name->value.character.length = strlen(name);
1245 nml_name->value.character.string = gfc_getmem (strlen (name) + 1);
1246 strcpy (nml_name->value.character.string, name);
1247
1248 return nml_name;
1249 }
1250
1251 /* nml_full_name builds up the fully qualified name of a
1252 derived type component. */
1253
1254 static char*
1255 nml_full_name (const char* var_name, const char* cmp_name)
1256 {
1257 int full_name_length;
1258 char * full_name;
1259
1260 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1261 full_name = (char*)gfc_getmem (full_name_length + 1);
1262 strcpy (full_name, var_name);
1263 full_name = strcat (full_name, "%");
1264 full_name = strcat (full_name, cmp_name);
1265 return full_name;
1266 }
1267
1268 /* nml_get_addr_expr builds an address expression from the
1269 gfc_symbol or gfc_component backend_decl's. An offset is
1270 provided so that the address of an element of an array of
1271 derived types is returned. This is used in the runtime to
1272 determine that span of the derived type. */
1273
1274 static tree
1275 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1276 tree base_addr)
1277 {
1278 tree decl = NULL_TREE;
1279 tree tmp;
1280 tree itmp;
1281 int array_flagged;
1282 int dummy_arg_flagged;
1283
1284 if (sym)
1285 {
1286 sym->attr.referenced = 1;
1287 decl = gfc_get_symbol_decl (sym);
1288
1289 /* If this is the enclosing function declaration, use
1290 the fake result instead. */
1291 if (decl == current_function_decl)
1292 decl = gfc_get_fake_result_decl (sym, 0);
1293 else if (decl == DECL_CONTEXT (current_function_decl))
1294 decl = gfc_get_fake_result_decl (sym, 1);
1295 }
1296 else
1297 decl = c->backend_decl;
1298
1299 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1300 || TREE_CODE (decl) == VAR_DECL
1301 || TREE_CODE (decl) == PARM_DECL)
1302 || TREE_CODE (decl) == COMPONENT_REF));
1303
1304 tmp = decl;
1305
1306 /* Build indirect reference, if dummy argument. */
1307
1308 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1309
1310 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref (tmp) : tmp;
1311
1312 /* If an array, set flag and use indirect ref. if built. */
1313
1314 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1315 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1316
1317 if (array_flagged)
1318 tmp = itmp;
1319
1320 /* Treat the component of a derived type, using base_addr for
1321 the derived type. */
1322
1323 if (TREE_CODE (decl) == FIELD_DECL)
1324 tmp = build3 (COMPONENT_REF, TREE_TYPE (tmp),
1325 base_addr, tmp, NULL_TREE);
1326
1327 /* If we have a derived type component, a reference to the first
1328 element of the array is built. This is done so that base_addr,
1329 used in the build of the component reference, always points to
1330 a RECORD_TYPE. */
1331
1332 if (array_flagged)
1333 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node);
1334
1335 /* Now build the address expression. */
1336
1337 tmp = build_fold_addr_expr (tmp);
1338
1339 /* If scalar dummy, resolve indirect reference now. */
1340
1341 if (dummy_arg_flagged && !array_flagged)
1342 tmp = build_fold_indirect_ref (tmp);
1343
1344 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1345
1346 return tmp;
1347 }
1348
1349 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1350 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1351 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1352
1353 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1354
1355 static void
1356 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1357 gfc_symbol * sym, gfc_component * c,
1358 tree base_addr)
1359 {
1360 gfc_typespec * ts = NULL;
1361 gfc_array_spec * as = NULL;
1362 tree addr_expr = NULL;
1363 tree dt = NULL;
1364 tree string;
1365 tree tmp;
1366 tree dtype;
1367 tree dt_parm_addr;
1368 int n_dim;
1369 int itype;
1370 int rank = 0;
1371
1372 gcc_assert (sym || c);
1373
1374 /* Build the namelist object name. */
1375
1376 string = gfc_build_cstring_const (var_name);
1377 string = gfc_build_addr_expr (pchar_type_node, string);
1378
1379 /* Build ts, as and data address using symbol or component. */
1380
1381 ts = (sym) ? &sym->ts : &c->ts;
1382 as = (sym) ? sym->as : c->as;
1383
1384 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1385
1386 if (as)
1387 rank = as->rank;
1388
1389 if (rank)
1390 {
1391 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1392 dtype = gfc_get_dtype (dt);
1393 }
1394 else
1395 {
1396 itype = GFC_DTYPE_UNKNOWN;
1397
1398 switch (ts->type)
1399
1400 {
1401 case BT_INTEGER:
1402 itype = GFC_DTYPE_INTEGER;
1403 break;
1404 case BT_LOGICAL:
1405 itype = GFC_DTYPE_LOGICAL;
1406 break;
1407 case BT_REAL:
1408 itype = GFC_DTYPE_REAL;
1409 break;
1410 case BT_COMPLEX:
1411 itype = GFC_DTYPE_COMPLEX;
1412 break;
1413 case BT_DERIVED:
1414 itype = GFC_DTYPE_DERIVED;
1415 break;
1416 case BT_CHARACTER:
1417 itype = GFC_DTYPE_CHARACTER;
1418 break;
1419 default:
1420 gcc_unreachable ();
1421 }
1422
1423 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1424 }
1425
1426 /* Build up the arguments for the transfer call.
1427 The call for the scalar part transfers:
1428 (address, name, type, kind or string_length, dtype) */
1429
1430 dt_parm_addr = build_fold_addr_expr (dt_parm);
1431
1432 if (ts->type == BT_CHARACTER)
1433 tmp = ts->cl->backend_decl;
1434 else
1435 tmp = build_int_cst (gfc_charlen_type_node, 0);
1436 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL], 6,
1437 dt_parm_addr, addr_expr, string,
1438 IARG (ts->kind), tmp, dtype);
1439 gfc_add_expr_to_block (block, tmp);
1440
1441 /* If the object is an array, transfer rank times:
1442 (null pointer, name, stride, lbound, ubound) */
1443
1444 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1445 {
1446 tmp = build_call_expr (iocall[IOCALL_SET_NML_VAL_DIM], 5,
1447 dt_parm_addr,
1448 IARG (n_dim),
1449 GFC_TYPE_ARRAY_STRIDE (dt, n_dim),
1450 GFC_TYPE_ARRAY_LBOUND (dt, n_dim),
1451 GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1452 gfc_add_expr_to_block (block, tmp);
1453 }
1454
1455 if (ts->type == BT_DERIVED)
1456 {
1457 gfc_component *cmp;
1458
1459 /* Provide the RECORD_TYPE to build component references. */
1460
1461 tree expr = build_fold_indirect_ref (addr_expr);
1462
1463 for (cmp = ts->derived->components; cmp; cmp = cmp->next)
1464 {
1465 char *full_name = nml_full_name (var_name, cmp->name);
1466 transfer_namelist_element (block,
1467 full_name,
1468 NULL, cmp, expr);
1469 gfc_free (full_name);
1470 }
1471 }
1472 }
1473
1474 #undef IARG
1475
1476 /* Create a data transfer statement. Not all of the fields are valid
1477 for both reading and writing, but improper use has been filtered
1478 out by now. */
1479
1480 static tree
1481 build_dt (tree function, gfc_code * code)
1482 {
1483 stmtblock_t block, post_block, post_end_block, post_iu_block;
1484 gfc_dt *dt;
1485 tree tmp, var;
1486 gfc_expr *nmlname;
1487 gfc_namelist *nml;
1488 unsigned int mask = 0;
1489
1490 gfc_start_block (&block);
1491 gfc_init_block (&post_block);
1492 gfc_init_block (&post_end_block);
1493 gfc_init_block (&post_iu_block);
1494
1495 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1496
1497 set_error_locus (&block, var, &code->loc);
1498
1499 if (last_dt == IOLENGTH)
1500 {
1501 gfc_inquire *inq;
1502
1503 inq = code->ext.inquire;
1504
1505 /* First check that preconditions are met. */
1506 gcc_assert (inq != NULL);
1507 gcc_assert (inq->iolength != NULL);
1508
1509 /* Connect to the iolength variable. */
1510 mask |= set_parameter_ref (&block, &post_end_block, var,
1511 IOPARM_dt_iolength, inq->iolength);
1512 dt = NULL;
1513 }
1514 else
1515 {
1516 dt = code->ext.dt;
1517 gcc_assert (dt != NULL);
1518 }
1519
1520 if (dt && dt->io_unit)
1521 {
1522 if (dt->io_unit->ts.type == BT_CHARACTER)
1523 {
1524 mask |= set_internal_unit (&block, &post_iu_block,
1525 var, dt->io_unit);
1526 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1527 }
1528 }
1529 else
1530 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1531
1532 if (dt)
1533 {
1534 if (dt->iomsg)
1535 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1536 dt->iomsg);
1537
1538 if (dt->iostat)
1539 mask |= set_parameter_ref (&block, &post_end_block, var,
1540 IOPARM_common_iostat, dt->iostat);
1541
1542 if (dt->err)
1543 mask |= IOPARM_common_err;
1544
1545 if (dt->eor)
1546 mask |= IOPARM_common_eor;
1547
1548 if (dt->end)
1549 mask |= IOPARM_common_end;
1550
1551 if (dt->rec)
1552 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1553
1554 if (dt->advance)
1555 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1556 dt->advance);
1557
1558 if (dt->format_expr)
1559 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1560 dt->format_expr);
1561
1562 if (dt->format_label)
1563 {
1564 if (dt->format_label == &format_asterisk)
1565 mask |= IOPARM_dt_list_format;
1566 else
1567 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1568 dt->format_label->format);
1569 }
1570
1571 if (dt->size)
1572 mask |= set_parameter_ref (&block, &post_end_block, var,
1573 IOPARM_dt_size, dt->size);
1574
1575 if (dt->namelist)
1576 {
1577 if (dt->format_expr || dt->format_label)
1578 gfc_internal_error ("build_dt: format with namelist");
1579
1580 nmlname = gfc_new_nml_name_expr (dt->namelist->name);
1581
1582 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1583 nmlname);
1584
1585 if (last_dt == READ)
1586 mask |= IOPARM_dt_namelist_read_mode;
1587
1588 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1589
1590 dt_parm = var;
1591
1592 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1593 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1594 NULL, NULL);
1595 }
1596 else
1597 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1598
1599 if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER)
1600 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1601 }
1602 else
1603 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1604
1605 tmp = build_fold_addr_expr (var);
1606 tmp = build_call_expr (function, 1, tmp);
1607 gfc_add_expr_to_block (&block, tmp);
1608
1609 gfc_add_block_to_block (&block, &post_block);
1610
1611 dt_parm = var;
1612 dt_post_end_block = &post_end_block;
1613
1614 gfc_add_expr_to_block (&block, gfc_trans_code (code->block->next));
1615
1616 gfc_add_block_to_block (&block, &post_iu_block);
1617
1618 dt_parm = NULL;
1619 dt_post_end_block = NULL;
1620
1621 return gfc_finish_block (&block);
1622 }
1623
1624
1625 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1626 this as a third sort of data transfer statement, except that
1627 lengths are summed instead of actually transferring any data. */
1628
1629 tree
1630 gfc_trans_iolength (gfc_code * code)
1631 {
1632 last_dt = IOLENGTH;
1633 return build_dt (iocall[IOCALL_IOLENGTH], code);
1634 }
1635
1636
1637 /* Translate a READ statement. */
1638
1639 tree
1640 gfc_trans_read (gfc_code * code)
1641 {
1642 last_dt = READ;
1643 return build_dt (iocall[IOCALL_READ], code);
1644 }
1645
1646
1647 /* Translate a WRITE statement */
1648
1649 tree
1650 gfc_trans_write (gfc_code * code)
1651 {
1652 last_dt = WRITE;
1653 return build_dt (iocall[IOCALL_WRITE], code);
1654 }
1655
1656
1657 /* Finish a data transfer statement. */
1658
1659 tree
1660 gfc_trans_dt_end (gfc_code * code)
1661 {
1662 tree function, tmp;
1663 stmtblock_t block;
1664
1665 gfc_init_block (&block);
1666
1667 switch (last_dt)
1668 {
1669 case READ:
1670 function = iocall[IOCALL_READ_DONE];
1671 break;
1672
1673 case WRITE:
1674 function = iocall[IOCALL_WRITE_DONE];
1675 break;
1676
1677 case IOLENGTH:
1678 function = iocall[IOCALL_IOLENGTH_DONE];
1679 break;
1680
1681 default:
1682 gcc_unreachable ();
1683 }
1684
1685 tmp = build_fold_addr_expr (dt_parm);
1686 tmp = build_call_expr (function, 1, tmp);
1687 gfc_add_expr_to_block (&block, tmp);
1688 gfc_add_block_to_block (&block, dt_post_end_block);
1689 gfc_init_block (dt_post_end_block);
1690
1691 if (last_dt != IOLENGTH)
1692 {
1693 gcc_assert (code->ext.dt != NULL);
1694 io_result (&block, dt_parm, code->ext.dt->err,
1695 code->ext.dt->end, code->ext.dt->eor);
1696 }
1697
1698 return gfc_finish_block (&block);
1699 }
1700
1701 static void
1702 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code);
1703
1704 /* Given an array field in a derived type variable, generate the code
1705 for the loop that iterates over array elements, and the code that
1706 accesses those array elements. Use transfer_expr to generate code
1707 for transferring that element. Because elements may also be
1708 derived types, transfer_expr and transfer_array_component are mutually
1709 recursive. */
1710
1711 static tree
1712 transfer_array_component (tree expr, gfc_component * cm)
1713 {
1714 tree tmp;
1715 stmtblock_t body;
1716 stmtblock_t block;
1717 gfc_loopinfo loop;
1718 int n;
1719 gfc_ss *ss;
1720 gfc_se se;
1721
1722 gfc_start_block (&block);
1723 gfc_init_se (&se, NULL);
1724
1725 /* Create and initialize Scalarization Status. Unlike in
1726 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1727 care of this task, because we don't have a gfc_expr at hand.
1728 Build one manually, as in gfc_trans_subarray_assign. */
1729
1730 ss = gfc_get_ss ();
1731 ss->type = GFC_SS_COMPONENT;
1732 ss->expr = NULL;
1733 ss->shape = gfc_get_shape (cm->as->rank);
1734 ss->next = gfc_ss_terminator;
1735 ss->data.info.dimen = cm->as->rank;
1736 ss->data.info.descriptor = expr;
1737 ss->data.info.data = gfc_conv_array_data (expr);
1738 ss->data.info.offset = gfc_conv_array_offset (expr);
1739 for (n = 0; n < cm->as->rank; n++)
1740 {
1741 ss->data.info.dim[n] = n;
1742 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1743 ss->data.info.stride[n] = gfc_index_one_node;
1744
1745 mpz_init (ss->shape[n]);
1746 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1747 cm->as->lower[n]->value.integer);
1748 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1749 }
1750
1751 /* Once we got ss, we use scalarizer to create the loop. */
1752
1753 gfc_init_loopinfo (&loop);
1754 gfc_add_ss_to_loop (&loop, ss);
1755 gfc_conv_ss_startstride (&loop);
1756 gfc_conv_loop_setup (&loop);
1757 gfc_mark_ss_chain_used (ss, 1);
1758 gfc_start_scalarized_body (&loop, &body);
1759
1760 gfc_copy_loopinfo_to_se (&se, &loop);
1761 se.ss = ss;
1762
1763 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1764 se.expr = expr;
1765 gfc_conv_tmp_array_ref (&se);
1766
1767 /* Now se.expr contains an element of the array. Take the address and pass
1768 it to the IO routines. */
1769 tmp = build_fold_addr_expr (se.expr);
1770 transfer_expr (&se, &cm->ts, tmp, NULL);
1771
1772 /* We are done now with the loop body. Wrap up the scalarizer and
1773 return. */
1774
1775 gfc_add_block_to_block (&body, &se.pre);
1776 gfc_add_block_to_block (&body, &se.post);
1777
1778 gfc_trans_scalarizing_loops (&loop, &body);
1779
1780 gfc_add_block_to_block (&block, &loop.pre);
1781 gfc_add_block_to_block (&block, &loop.post);
1782
1783 for (n = 0; n < cm->as->rank; n++)
1784 mpz_clear (ss->shape[n]);
1785 gfc_free (ss->shape);
1786
1787 gfc_cleanup_loop (&loop);
1788
1789 return gfc_finish_block (&block);
1790 }
1791
1792 /* Generate the call for a scalar transfer node. */
1793
1794 static void
1795 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
1796 {
1797 tree tmp, function, arg2, field, expr;
1798 gfc_component *c;
1799 int kind;
1800
1801 /* It is possible to get a C_NULL_PTR or C_NULL_FUNPTR expression here if
1802 the user says something like: print *, 'c_null_ptr: ', c_null_ptr
1803 We need to translate the expression to a constant if it's either
1804 C_NULL_PTR or C_NULL_FUNPTR. We could also get a user variable of
1805 type C_PTR or C_FUNPTR, in which case the ts->type may no longer be
1806 BT_DERIVED (could have been changed by gfc_conv_expr). */
1807 if ((ts->type == BT_DERIVED && ts->is_iso_c == 1 && ts->derived != NULL)
1808 || (ts->derived != NULL && ts->derived->ts.is_iso_c == 1))
1809 {
1810 /* C_PTR and C_FUNPTR have private components which means they can not
1811 be printed. However, if -std=gnu and not -pedantic, allow
1812 the component to be printed to help debugging. */
1813 if (gfc_notification_std (GFC_STD_GNU) != SILENT)
1814 {
1815 gfc_error_now ("Derived type '%s' at %L has PRIVATE components",
1816 ts->derived->name, code != NULL ? &(code->loc) :
1817 &gfc_current_locus);
1818 return;
1819 }
1820
1821 ts->type = ts->derived->ts.type;
1822 ts->kind = ts->derived->ts.kind;
1823 ts->f90_type = ts->derived->ts.f90_type;
1824 }
1825
1826 kind = ts->kind;
1827 function = NULL;
1828 arg2 = NULL;
1829
1830 switch (ts->type)
1831 {
1832 case BT_INTEGER:
1833 arg2 = build_int_cst (NULL_TREE, kind);
1834 function = iocall[IOCALL_X_INTEGER];
1835 break;
1836
1837 case BT_REAL:
1838 arg2 = build_int_cst (NULL_TREE, kind);
1839 function = iocall[IOCALL_X_REAL];
1840 break;
1841
1842 case BT_COMPLEX:
1843 arg2 = build_int_cst (NULL_TREE, kind);
1844 function = iocall[IOCALL_X_COMPLEX];
1845 break;
1846
1847 case BT_LOGICAL:
1848 arg2 = build_int_cst (NULL_TREE, kind);
1849 function = iocall[IOCALL_X_LOGICAL];
1850 break;
1851
1852 case BT_CHARACTER:
1853 case BT_HOLLERITH:
1854 if (se->string_length)
1855 arg2 = se->string_length;
1856 else
1857 {
1858 tmp = build_fold_indirect_ref (addr_expr);
1859 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
1860 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
1861 }
1862 function = iocall[IOCALL_X_CHARACTER];
1863 break;
1864
1865 case BT_DERIVED:
1866 /* Recurse into the elements of the derived type. */
1867 expr = gfc_evaluate_now (addr_expr, &se->pre);
1868 expr = build_fold_indirect_ref (expr);
1869
1870 for (c = ts->derived->components; c; c = c->next)
1871 {
1872 field = c->backend_decl;
1873 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
1874
1875 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), expr, field,
1876 NULL_TREE);
1877
1878 if (c->dimension)
1879 {
1880 tmp = transfer_array_component (tmp, c);
1881 gfc_add_expr_to_block (&se->pre, tmp);
1882 }
1883 else
1884 {
1885 if (!c->pointer)
1886 tmp = build_fold_addr_expr (tmp);
1887 transfer_expr (se, &c->ts, tmp, code);
1888 }
1889 }
1890 return;
1891
1892 default:
1893 internal_error ("Bad IO basetype (%d)", ts->type);
1894 }
1895
1896 tmp = build_fold_addr_expr (dt_parm);
1897 tmp = build_call_expr (function, 3, tmp, addr_expr, arg2);
1898 gfc_add_expr_to_block (&se->pre, tmp);
1899 gfc_add_block_to_block (&se->pre, &se->post);
1900
1901 }
1902
1903
1904 /* Generate a call to pass an array descriptor to the IO library. The
1905 array should be of one of the intrinsic types. */
1906
1907 static void
1908 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
1909 {
1910 tree tmp, charlen_arg, kind_arg;
1911
1912 if (ts->type == BT_CHARACTER)
1913 charlen_arg = se->string_length;
1914 else
1915 charlen_arg = build_int_cst (NULL_TREE, 0);
1916
1917 kind_arg = build_int_cst (NULL_TREE, ts->kind);
1918
1919 tmp = build_fold_addr_expr (dt_parm);
1920 tmp = build_call_expr (iocall[IOCALL_X_ARRAY], 4,
1921 tmp, addr_expr, kind_arg, charlen_arg);
1922 gfc_add_expr_to_block (&se->pre, tmp);
1923 gfc_add_block_to_block (&se->pre, &se->post);
1924 }
1925
1926
1927 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
1928
1929 tree
1930 gfc_trans_transfer (gfc_code * code)
1931 {
1932 stmtblock_t block, body;
1933 gfc_loopinfo loop;
1934 gfc_expr *expr;
1935 gfc_ref *ref;
1936 gfc_ss *ss;
1937 gfc_se se;
1938 tree tmp;
1939
1940 gfc_start_block (&block);
1941 gfc_init_block (&body);
1942
1943 expr = code->expr;
1944 ss = gfc_walk_expr (expr);
1945
1946 ref = NULL;
1947 gfc_init_se (&se, NULL);
1948
1949 if (ss == gfc_ss_terminator)
1950 {
1951 /* Transfer a scalar value. */
1952 gfc_conv_expr_reference (&se, expr);
1953 transfer_expr (&se, &expr->ts, se.expr, code);
1954 }
1955 else
1956 {
1957 /* Transfer an array. If it is an array of an intrinsic
1958 type, pass the descriptor to the library. Otherwise
1959 scalarize the transfer. */
1960 if (expr->ref)
1961 {
1962 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
1963 ref = ref->next);
1964 gcc_assert (ref->type == REF_ARRAY);
1965 }
1966
1967 if (expr->ts.type != BT_DERIVED && ref && ref->next == NULL)
1968 {
1969 /* Get the descriptor. */
1970 gfc_conv_expr_descriptor (&se, expr, ss);
1971 tmp = build_fold_addr_expr (se.expr);
1972 transfer_array_desc (&se, &expr->ts, tmp);
1973 goto finish_block_label;
1974 }
1975
1976 /* Initialize the scalarizer. */
1977 gfc_init_loopinfo (&loop);
1978 gfc_add_ss_to_loop (&loop, ss);
1979
1980 /* Initialize the loop. */
1981 gfc_conv_ss_startstride (&loop);
1982 gfc_conv_loop_setup (&loop);
1983
1984 /* The main loop body. */
1985 gfc_mark_ss_chain_used (ss, 1);
1986 gfc_start_scalarized_body (&loop, &body);
1987
1988 gfc_copy_loopinfo_to_se (&se, &loop);
1989 se.ss = ss;
1990
1991 gfc_conv_expr_reference (&se, expr);
1992 transfer_expr (&se, &expr->ts, se.expr, code);
1993 }
1994
1995 finish_block_label:
1996
1997 gfc_add_block_to_block (&body, &se.pre);
1998 gfc_add_block_to_block (&body, &se.post);
1999
2000 if (se.ss == NULL)
2001 tmp = gfc_finish_block (&body);
2002 else
2003 {
2004 gcc_assert (se.ss == gfc_ss_terminator);
2005 gfc_trans_scalarizing_loops (&loop, &body);
2006
2007 gfc_add_block_to_block (&loop.pre, &loop.post);
2008 tmp = gfc_finish_block (&loop.pre);
2009 gfc_cleanup_loop (&loop);
2010 }
2011
2012 gfc_add_expr_to_block (&block, tmp);
2013
2014 return gfc_finish_block (&block);
2015 }
2016
2017 #include "gt-fortran-trans-io.h"
2018
This page took 0.129198 seconds and 5 git commands to generate.