trans-io.c (gfc_build_io_library_fndecls): Fix return value of some libgfortran funct...
[gcc.git] / gcc / fortran / trans-io.c
1 /* IO Code translation/library interface
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software 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 "ggc.h"
28 #include "diagnostic-core.h" /* For internal_error. */
29 #include "gfortran.h"
30 #include "trans.h"
31 #include "trans-stmt.h"
32 #include "trans-array.h"
33 #include "trans-types.h"
34 #include "trans-const.h"
35
36 /* Members of the ioparm structure. */
37
38 enum ioparam_type
39 {
40 IOPARM_ptype_common,
41 IOPARM_ptype_open,
42 IOPARM_ptype_close,
43 IOPARM_ptype_filepos,
44 IOPARM_ptype_inquire,
45 IOPARM_ptype_dt,
46 IOPARM_ptype_wait,
47 IOPARM_ptype_num
48 };
49
50 enum iofield_type
51 {
52 IOPARM_type_int4,
53 IOPARM_type_intio,
54 IOPARM_type_pint4,
55 IOPARM_type_pintio,
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 GTY(()) gfc_st_parameter_field {
66 const char *name;
67 unsigned int mask;
68 enum ioparam_type param_type;
69 enum iofield_type type;
70 tree field;
71 tree field_len;
72 }
73 gfc_st_parameter_field;
74
75 typedef struct GTY(()) gfc_st_parameter {
76 const char *name;
77 tree type;
78 }
79 gfc_st_parameter;
80
81 enum iofield
82 {
83 #define IOPARM(param_type, name, mask, type) IOPARM_##param_type##_##name,
84 #include "ioparm.def"
85 #undef IOPARM
86 IOPARM_field_num
87 };
88
89 static GTY(()) gfc_st_parameter st_parameter[] =
90 {
91 { "common", NULL },
92 { "open", NULL },
93 { "close", NULL },
94 { "filepos", NULL },
95 { "inquire", NULL },
96 { "dt", NULL },
97 { "wait", NULL }
98 };
99
100 static GTY(()) gfc_st_parameter_field st_parameter_field[] =
101 {
102 #define IOPARM(param_type, name, mask, type) \
103 { #name, mask, IOPARM_ptype_##param_type, IOPARM_type_##type, NULL, NULL },
104 #include "ioparm.def"
105 #undef IOPARM
106 { NULL, 0, (enum ioparam_type) 0, (enum iofield_type) 0, NULL, NULL }
107 };
108
109 /* Library I/O subroutines */
110
111 enum iocall
112 {
113 IOCALL_READ,
114 IOCALL_READ_DONE,
115 IOCALL_WRITE,
116 IOCALL_WRITE_DONE,
117 IOCALL_X_INTEGER,
118 IOCALL_X_LOGICAL,
119 IOCALL_X_CHARACTER,
120 IOCALL_X_CHARACTER_WIDE,
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_WAIT,
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 unsigned int type;
155 gfc_st_parameter_field *p;
156 char name[64];
157 size_t len;
158 tree t = make_node (RECORD_TYPE);
159 tree *chain = NULL;
160
161 len = strlen (st_parameter[ptype].name);
162 gcc_assert (len <= sizeof (name) - sizeof ("__st_parameter_"));
163 memcpy (name, "__st_parameter_", sizeof ("__st_parameter_"));
164 memcpy (name + sizeof ("__st_parameter_") - 1, st_parameter[ptype].name,
165 len + 1);
166 TYPE_NAME (t) = get_identifier (name);
167
168 for (type = 0, p = st_parameter_field; type < IOPARM_field_num; type++, p++)
169 if (p->param_type == ptype)
170 switch (p->type)
171 {
172 case IOPARM_type_int4:
173 case IOPARM_type_intio:
174 case IOPARM_type_pint4:
175 case IOPARM_type_pintio:
176 case IOPARM_type_parray:
177 case IOPARM_type_pchar:
178 case IOPARM_type_pad:
179 p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
180 types[p->type], &chain);
181 break;
182 case IOPARM_type_char1:
183 p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
184 pchar_type_node, &chain);
185 /* FALLTHROUGH */
186 case IOPARM_type_char2:
187 len = strlen (p->name);
188 gcc_assert (len <= sizeof (name) - sizeof ("_len"));
189 memcpy (name, p->name, len);
190 memcpy (name + len, "_len", sizeof ("_len"));
191 p->field_len = gfc_add_field_to_struct (t, get_identifier (name),
192 gfc_charlen_type_node,
193 &chain);
194 if (p->type == IOPARM_type_char2)
195 p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
196 pchar_type_node, &chain);
197 break;
198 case IOPARM_type_common:
199 p->field
200 = gfc_add_field_to_struct (t,
201 get_identifier (p->name),
202 st_parameter[IOPARM_ptype_common].type,
203 &chain);
204 break;
205 case IOPARM_type_num:
206 gcc_unreachable ();
207 }
208
209 gfc_finish_type (t);
210 st_parameter[ptype].type = t;
211 }
212
213
214 /* Build code to test an error condition and call generate_error if needed.
215 Note: This builds calls to generate_error in the runtime library function.
216 The function generate_error is dependent on certain parameters in the
217 st_parameter_common flags to be set. (See libgfortran/runtime/error.c)
218 Therefore, the code to set these flags must be generated before
219 this function is used. */
220
221 void
222 gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
223 const char * msgid, stmtblock_t * pblock)
224 {
225 stmtblock_t block;
226 tree body;
227 tree tmp;
228 tree arg1, arg2, arg3;
229 char *message;
230
231 if (integer_zerop (cond))
232 return;
233
234 /* The code to generate the error. */
235 gfc_start_block (&block);
236
237 arg1 = gfc_build_addr_expr (NULL_TREE, var);
238
239 arg2 = build_int_cst (integer_type_node, error_code),
240
241 asprintf (&message, "%s", _(msgid));
242 arg3 = gfc_build_addr_expr (pchar_type_node,
243 gfc_build_localized_cstring_const (message));
244 gfc_free(message);
245
246 tmp = build_call_expr_loc (input_location,
247 gfor_fndecl_generate_error, 3, arg1, arg2, arg3);
248
249 gfc_add_expr_to_block (&block, tmp);
250
251 body = gfc_finish_block (&block);
252
253 if (integer_onep (cond))
254 {
255 gfc_add_expr_to_block (pblock, body);
256 }
257 else
258 {
259 /* Tell the compiler that this isn't likely. */
260 cond = fold_convert (long_integer_type_node, cond);
261 tmp = build_int_cst (long_integer_type_node, 0);
262 cond = build_call_expr_loc (input_location,
263 built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
264 cond = fold_convert (boolean_type_node, cond);
265
266 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location));
267 gfc_add_expr_to_block (pblock, tmp);
268 }
269 }
270
271
272 /* Create function decls for IO library functions. */
273
274 void
275 gfc_build_io_library_fndecls (void)
276 {
277 tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
278 tree gfc_intio_type_node;
279 tree parm_type, dt_parm_type;
280 HOST_WIDE_INT pad_size;
281 unsigned int ptype;
282
283 types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
284 types[IOPARM_type_intio] = gfc_intio_type_node
285 = gfc_get_int_type (gfc_intio_kind);
286 types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
287 types[IOPARM_type_pintio]
288 = build_pointer_type (gfc_intio_type_node);
289 types[IOPARM_type_parray] = pchar_type_node;
290 types[IOPARM_type_pchar] = pchar_type_node;
291 pad_size = 16 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (pchar_type_node));
292 pad_size += 32 * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (integer_type_node));
293 pad_idx = build_index_type (build_int_cst (NULL_TREE, pad_size - 1));
294 types[IOPARM_type_pad] = build_array_type (char_type_node, pad_idx);
295
296 /* pad actually contains pointers and integers so it needs to have an
297 alignment that is at least as large as the needed alignment for those
298 types. See the st_parameter_dt structure in libgfortran/io/io.h for
299 what really goes into this space. */
300 TYPE_ALIGN (types[IOPARM_type_pad]) = MAX (TYPE_ALIGN (pchar_type_node),
301 TYPE_ALIGN (gfc_get_int_type (gfc_intio_kind)));
302
303 for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
304 gfc_build_st_parameter ((enum ioparam_type) ptype, types);
305
306 /* Define the transfer functions.
307 TODO: Split them between READ and WRITE to allow further
308 optimizations, e.g. by using aliases? */
309
310 dt_parm_type = build_pointer_type (st_parameter[IOPARM_ptype_dt].type);
311
312 iocall[IOCALL_X_INTEGER] = gfc_build_library_function_decl_with_spec (
313 get_identifier (PREFIX("transfer_integer")), ".wW",
314 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
315
316 iocall[IOCALL_X_LOGICAL] = gfc_build_library_function_decl_with_spec (
317 get_identifier (PREFIX("transfer_logical")), ".wW",
318 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
319
320 iocall[IOCALL_X_CHARACTER] = gfc_build_library_function_decl_with_spec (
321 get_identifier (PREFIX("transfer_character")), ".wW",
322 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
323
324 iocall[IOCALL_X_CHARACTER_WIDE] = gfc_build_library_function_decl_with_spec (
325 get_identifier (PREFIX("transfer_character_wide")), ".wW",
326 void_type_node, 4, dt_parm_type, pvoid_type_node,
327 gfc_charlen_type_node, gfc_int4_type_node);
328
329 iocall[IOCALL_X_REAL] = gfc_build_library_function_decl_with_spec (
330 get_identifier (PREFIX("transfer_real")), ".wW",
331 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
332
333 iocall[IOCALL_X_COMPLEX] = gfc_build_library_function_decl_with_spec (
334 get_identifier (PREFIX("transfer_complex")), ".wW",
335 void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node);
336
337 iocall[IOCALL_X_ARRAY] = gfc_build_library_function_decl_with_spec (
338 get_identifier (PREFIX("transfer_array")), ".wW",
339 void_type_node, 4, dt_parm_type, pvoid_type_node,
340 integer_type_node, gfc_charlen_type_node);
341
342 /* Library entry points */
343
344 iocall[IOCALL_READ] = gfc_build_library_function_decl_with_spec (
345 get_identifier (PREFIX("st_read")), ".w",
346 void_type_node, 1, dt_parm_type);
347
348 iocall[IOCALL_WRITE] = gfc_build_library_function_decl_with_spec (
349 get_identifier (PREFIX("st_write")), ".w",
350 void_type_node, 1, dt_parm_type);
351
352 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_open].type);
353 iocall[IOCALL_OPEN] = gfc_build_library_function_decl_with_spec (
354 get_identifier (PREFIX("st_open")), ".w",
355 void_type_node, 1, parm_type);
356
357 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_close].type);
358 iocall[IOCALL_CLOSE] = gfc_build_library_function_decl_with_spec (
359 get_identifier (PREFIX("st_close")), ".w",
360 void_type_node, 1, parm_type);
361
362 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_inquire].type);
363 iocall[IOCALL_INQUIRE] = gfc_build_library_function_decl_with_spec (
364 get_identifier (PREFIX("st_inquire")), ".w",
365 void_type_node, 1, parm_type);
366
367 iocall[IOCALL_IOLENGTH] = gfc_build_library_function_decl_with_spec(
368 get_identifier (PREFIX("st_iolength")), ".w",
369 void_type_node, 1, dt_parm_type);
370
371 /* TODO: Change when asynchronous I/O is implemented. */
372 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_wait].type);
373 iocall[IOCALL_WAIT] = gfc_build_library_function_decl_with_spec (
374 get_identifier (PREFIX("st_wait")), ".X",
375 void_type_node, 1, parm_type);
376
377 parm_type = build_pointer_type (st_parameter[IOPARM_ptype_filepos].type);
378 iocall[IOCALL_REWIND] = gfc_build_library_function_decl_with_spec (
379 get_identifier (PREFIX("st_rewind")), ".w",
380 void_type_node, 1, parm_type);
381
382 iocall[IOCALL_BACKSPACE] = gfc_build_library_function_decl_with_spec (
383 get_identifier (PREFIX("st_backspace")), ".w",
384 void_type_node, 1, parm_type);
385
386 iocall[IOCALL_ENDFILE] = gfc_build_library_function_decl_with_spec (
387 get_identifier (PREFIX("st_endfile")), ".w",
388 void_type_node, 1, parm_type);
389
390 iocall[IOCALL_FLUSH] = gfc_build_library_function_decl_with_spec (
391 get_identifier (PREFIX("st_flush")), ".w",
392 void_type_node, 1, parm_type);
393
394 /* Library helpers */
395
396 iocall[IOCALL_READ_DONE] = gfc_build_library_function_decl_with_spec (
397 get_identifier (PREFIX("st_read_done")), ".w",
398 void_type_node, 1, dt_parm_type);
399
400 iocall[IOCALL_WRITE_DONE] = gfc_build_library_function_decl_with_spec (
401 get_identifier (PREFIX("st_write_done")), ".w",
402 void_type_node, 1, dt_parm_type);
403
404 iocall[IOCALL_IOLENGTH_DONE] = gfc_build_library_function_decl_with_spec (
405 get_identifier (PREFIX("st_iolength_done")), ".w",
406 void_type_node, 1, dt_parm_type);
407
408 iocall[IOCALL_SET_NML_VAL] = gfc_build_library_function_decl_with_spec (
409 get_identifier (PREFIX("st_set_nml_var")), ".w.R",
410 void_type_node, 6, dt_parm_type, pvoid_type_node, pvoid_type_node,
411 void_type_node, gfc_charlen_type_node, gfc_int4_type_node);
412
413 iocall[IOCALL_SET_NML_VAL_DIM] = gfc_build_library_function_decl_with_spec (
414 get_identifier (PREFIX("st_set_nml_var_dim")), ".w",
415 void_type_node, 5, dt_parm_type, gfc_int4_type_node,
416 gfc_array_index_type, gfc_array_index_type, gfc_array_index_type);
417 }
418
419
420 /* Generate code to store an integer constant into the
421 st_parameter_XXX structure. */
422
423 static unsigned int
424 set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
425 unsigned int val)
426 {
427 tree tmp;
428 gfc_st_parameter_field *p = &st_parameter_field[type];
429
430 if (p->param_type == IOPARM_ptype_common)
431 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
432 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
433 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
434 NULL_TREE);
435 gfc_add_modify (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
436 return p->mask;
437 }
438
439
440 /* Generate code to store a non-string I/O parameter into the
441 st_parameter_XXX structure. This is a pass by value. */
442
443 static unsigned int
444 set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
445 gfc_expr *e)
446 {
447 gfc_se se;
448 tree tmp;
449 gfc_st_parameter_field *p = &st_parameter_field[type];
450 tree dest_type = TREE_TYPE (p->field);
451
452 gfc_init_se (&se, NULL);
453 gfc_conv_expr_val (&se, e);
454
455 /* If we're storing a UNIT number, we need to check it first. */
456 if (type == IOPARM_common_unit && e->ts.kind > 4)
457 {
458 tree cond, val;
459 int i;
460
461 /* Don't evaluate the UNIT number multiple times. */
462 se.expr = gfc_evaluate_now (se.expr, &se.pre);
463
464 /* UNIT numbers should be greater than the min. */
465 i = gfc_validate_kind (BT_INTEGER, 4, false);
466 val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].pedantic_min_int, 4);
467 cond = fold_build2 (LT_EXPR, boolean_type_node, se.expr,
468 fold_convert (TREE_TYPE (se.expr), val));
469 gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
470 "Unit number in I/O statement too small",
471 &se.pre);
472
473 /* UNIT numbers should be less than the max. */
474 val = 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), val));
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 = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
488 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
489
490 tmp = fold_build3 (COMPONENT_REF, dest_type, var, p->field, NULL_TREE);
491 gfc_add_modify (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), gfc_build_addr_expr (NULL_TREE, 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 (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 (block, tmpvar,
536 build_int_cst (TREE_TYPE (tmpvar), LIBERROR_OK));
537
538 addr = gfc_build_addr_expr (NULL_TREE, 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 (postblock, se.expr, tmp);
542 }
543
544 if (p->param_type == IOPARM_ptype_common)
545 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
546 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
547 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
548 var, p->field, NULL_TREE);
549 gfc_add_modify (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 static void
560 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
561 {
562 tree size;
563
564 if (e->rank == 0)
565 {
566 tree type, array, tmp;
567 gfc_symbol *sym;
568 int rank;
569
570 /* If it is an element, we need its address and size of the rest. */
571 gcc_assert (e->expr_type == EXPR_VARIABLE);
572 gcc_assert (e->ref->u.ar.type == AR_ELEMENT);
573 sym = e->symtree->n.sym;
574 rank = sym->as->rank - 1;
575 gfc_conv_expr (se, e);
576
577 array = sym->backend_decl;
578 type = TREE_TYPE (array);
579
580 if (GFC_ARRAY_TYPE_P (type))
581 size = GFC_TYPE_ARRAY_SIZE (type);
582 else
583 {
584 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
585 size = gfc_conv_array_stride (array, rank);
586 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
587 gfc_conv_array_ubound (array, rank),
588 gfc_conv_array_lbound (array, rank));
589 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
590 gfc_index_one_node);
591 size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
592 }
593 gcc_assert (size);
594
595 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
596 TREE_OPERAND (se->expr, 1));
597 se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
598 tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
599 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
600 fold_convert (gfc_array_index_type, tmp));
601 se->string_length = fold_convert (gfc_charlen_type_node, size);
602 return;
603 }
604
605 gfc_conv_array_parameter (se, e, gfc_walk_expr (e), true, NULL, NULL, &size);
606 se->string_length = fold_convert (gfc_charlen_type_node, size);
607 }
608
609
610 /* Generate code to store a string and its length into the
611 st_parameter_XXX structure. */
612
613 static unsigned int
614 set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
615 enum iofield type, gfc_expr * e)
616 {
617 gfc_se se;
618 tree tmp;
619 tree io;
620 tree len;
621 gfc_st_parameter_field *p = &st_parameter_field[type];
622
623 gfc_init_se (&se, NULL);
624
625 if (p->param_type == IOPARM_ptype_common)
626 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
627 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
628 io = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
629 var, p->field, NULL_TREE);
630 len = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field_len),
631 var, p->field_len, NULL_TREE);
632
633 /* Integer variable assigned a format label. */
634 if (e->ts.type == BT_INTEGER
635 && e->rank == 0
636 && e->symtree->n.sym->attr.assign == 1)
637 {
638 char * msg;
639 tree cond;
640
641 gfc_conv_label_variable (&se, e);
642 tmp = GFC_DECL_STRING_LEN (se.expr);
643 cond = fold_build2 (LT_EXPR, boolean_type_node,
644 tmp, build_int_cst (TREE_TYPE (tmp), 0));
645
646 asprintf(&msg, "Label assigned to variable '%s' (%%ld) is not a format "
647 "label", e->symtree->name);
648 gfc_trans_runtime_check (true, false, cond, &se.pre, &e->where, msg,
649 fold_convert (long_integer_type_node, tmp));
650 gfc_free (msg);
651
652 gfc_add_modify (&se.pre, io,
653 fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
654 gfc_add_modify (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
655 }
656 else
657 {
658 /* General character. */
659 if (e->ts.type == BT_CHARACTER && e->rank == 0)
660 gfc_conv_expr (&se, e);
661 /* Array assigned Hollerith constant or character array. */
662 else if (e->rank > 0 || (e->symtree && e->symtree->n.sym->as->rank > 0))
663 gfc_convert_array_to_string (&se, e);
664 else
665 gcc_unreachable ();
666
667 gfc_conv_string_parameter (&se);
668 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
669 gfc_add_modify (&se.pre, len, se.string_length);
670 }
671
672 gfc_add_block_to_block (block, &se.pre);
673 gfc_add_block_to_block (postblock, &se.post);
674 return p->mask;
675 }
676
677
678 /* Generate code to store the character (array) and the character length
679 for an internal unit. */
680
681 static unsigned int
682 set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
683 tree var, gfc_expr * e)
684 {
685 gfc_se se;
686 tree io;
687 tree len;
688 tree desc;
689 tree tmp;
690 gfc_st_parameter_field *p;
691 unsigned int mask;
692
693 gfc_init_se (&se, NULL);
694
695 p = &st_parameter_field[IOPARM_dt_internal_unit];
696 mask = p->mask;
697 io = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
698 var, p->field, NULL_TREE);
699 len = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field_len),
700 var, p->field_len, NULL_TREE);
701 p = &st_parameter_field[IOPARM_dt_internal_unit_desc];
702 desc = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
703 var, p->field, NULL_TREE);
704
705 gcc_assert (e->ts.type == BT_CHARACTER);
706
707 /* Character scalars. */
708 if (e->rank == 0)
709 {
710 gfc_conv_expr (&se, e);
711 gfc_conv_string_parameter (&se);
712 tmp = se.expr;
713 se.expr = build_int_cst (pchar_type_node, 0);
714 }
715
716 /* Character array. */
717 else if (e->rank > 0)
718 {
719 se.ss = gfc_walk_expr (e);
720
721 if (is_subref_array (e))
722 {
723 /* Use a temporary for components of arrays of derived types
724 or substring array references. */
725 gfc_conv_subref_array_arg (&se, e, 0,
726 last_dt == READ ? INTENT_IN : INTENT_OUT, false);
727 tmp = build_fold_indirect_ref_loc (input_location,
728 se.expr);
729 se.expr = gfc_build_addr_expr (pchar_type_node, tmp);
730 tmp = gfc_conv_descriptor_data_get (tmp);
731 }
732 else
733 {
734 /* Return the data pointer and rank from the descriptor. */
735 gfc_conv_expr_descriptor (&se, e, se.ss);
736 tmp = gfc_conv_descriptor_data_get (se.expr);
737 se.expr = gfc_build_addr_expr (pchar_type_node, se.expr);
738 }
739 }
740 else
741 gcc_unreachable ();
742
743 /* The cast is needed for character substrings and the descriptor
744 data. */
745 gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
746 gfc_add_modify (&se.pre, len,
747 fold_convert (TREE_TYPE (len), se.string_length));
748 gfc_add_modify (&se.pre, desc, se.expr);
749
750 gfc_add_block_to_block (block, &se.pre);
751 gfc_add_block_to_block (post_block, &se.post);
752 return mask;
753 }
754
755 /* Add a case to a IO-result switch. */
756
757 static void
758 add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
759 {
760 tree tmp, value;
761
762 if (label == NULL)
763 return; /* No label, no case */
764
765 value = build_int_cst (NULL_TREE, label_value);
766
767 /* Make a backend label for this case. */
768 tmp = gfc_build_label_decl (NULL_TREE);
769
770 /* And the case itself. */
771 tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
772 gfc_add_expr_to_block (body, tmp);
773
774 /* Jump to the label. */
775 tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
776 gfc_add_expr_to_block (body, tmp);
777 }
778
779
780 /* Generate a switch statement that branches to the correct I/O
781 result label. The last statement of an I/O call stores the
782 result into a variable because there is often cleanup that
783 must be done before the switch, so a temporary would have to
784 be created anyway. */
785
786 static void
787 io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
788 gfc_st_label * end_label, gfc_st_label * eor_label)
789 {
790 stmtblock_t body;
791 tree tmp, rc;
792 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
793
794 /* If no labels are specified, ignore the result instead
795 of building an empty switch. */
796 if (err_label == NULL
797 && end_label == NULL
798 && eor_label == NULL)
799 return;
800
801 /* Build a switch statement. */
802 gfc_start_block (&body);
803
804 /* The label values here must be the same as the values
805 in the library_return enum in the runtime library */
806 add_case (1, err_label, &body);
807 add_case (2, end_label, &body);
808 add_case (3, eor_label, &body);
809
810 tmp = gfc_finish_block (&body);
811
812 var = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
813 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
814 rc = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
815 var, p->field, NULL_TREE);
816 rc = fold_build2 (BIT_AND_EXPR, TREE_TYPE (rc),
817 rc, build_int_cst (TREE_TYPE (rc),
818 IOPARM_common_libreturn_mask));
819
820 tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
821
822 gfc_add_expr_to_block (block, tmp);
823 }
824
825
826 /* Store the current file and line number to variables so that if a
827 library call goes awry, we can tell the user where the problem is. */
828
829 static void
830 set_error_locus (stmtblock_t * block, tree var, locus * where)
831 {
832 gfc_file *f;
833 tree str, locus_file;
834 int line;
835 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_filename];
836
837 locus_file = fold_build3 (COMPONENT_REF,
838 st_parameter[IOPARM_ptype_common].type,
839 var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
840 locus_file = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
841 locus_file, p->field, NULL_TREE);
842 f = where->lb->file;
843 str = gfc_build_cstring_const (f->filename);
844
845 str = gfc_build_addr_expr (pchar_type_node, str);
846 gfc_add_modify (block, locus_file, str);
847
848 line = LOCATION_LINE (where->lb->location);
849 set_parameter_const (block, var, IOPARM_common_line, line);
850 }
851
852
853 /* Translate an OPEN statement. */
854
855 tree
856 gfc_trans_open (gfc_code * code)
857 {
858 stmtblock_t block, post_block;
859 gfc_open *p;
860 tree tmp, var;
861 unsigned int mask = 0;
862
863 gfc_start_block (&block);
864 gfc_init_block (&post_block);
865
866 var = gfc_create_var (st_parameter[IOPARM_ptype_open].type, "open_parm");
867
868 set_error_locus (&block, var, &code->loc);
869 p = code->ext.open;
870
871 if (p->iomsg)
872 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
873 p->iomsg);
874
875 if (p->iostat)
876 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
877 p->iostat);
878
879 if (p->err)
880 mask |= IOPARM_common_err;
881
882 if (p->file)
883 mask |= set_string (&block, &post_block, var, IOPARM_open_file, p->file);
884
885 if (p->status)
886 mask |= set_string (&block, &post_block, var, IOPARM_open_status,
887 p->status);
888
889 if (p->access)
890 mask |= set_string (&block, &post_block, var, IOPARM_open_access,
891 p->access);
892
893 if (p->form)
894 mask |= set_string (&block, &post_block, var, IOPARM_open_form, p->form);
895
896 if (p->recl)
897 mask |= set_parameter_value (&block, var, IOPARM_open_recl_in, p->recl);
898
899 if (p->blank)
900 mask |= set_string (&block, &post_block, var, IOPARM_open_blank,
901 p->blank);
902
903 if (p->position)
904 mask |= set_string (&block, &post_block, var, IOPARM_open_position,
905 p->position);
906
907 if (p->action)
908 mask |= set_string (&block, &post_block, var, IOPARM_open_action,
909 p->action);
910
911 if (p->delim)
912 mask |= set_string (&block, &post_block, var, IOPARM_open_delim,
913 p->delim);
914
915 if (p->pad)
916 mask |= set_string (&block, &post_block, var, IOPARM_open_pad, p->pad);
917
918 if (p->decimal)
919 mask |= set_string (&block, &post_block, var, IOPARM_open_decimal,
920 p->decimal);
921
922 if (p->encoding)
923 mask |= set_string (&block, &post_block, var, IOPARM_open_encoding,
924 p->encoding);
925
926 if (p->round)
927 mask |= set_string (&block, &post_block, var, IOPARM_open_round, p->round);
928
929 if (p->sign)
930 mask |= set_string (&block, &post_block, var, IOPARM_open_sign, p->sign);
931
932 if (p->asynchronous)
933 mask |= set_string (&block, &post_block, var, IOPARM_open_asynchronous,
934 p->asynchronous);
935
936 if (p->convert)
937 mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
938 p->convert);
939
940 if (p->newunit)
941 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_open_newunit,
942 p->newunit);
943
944 set_parameter_const (&block, var, IOPARM_common_flags, mask);
945
946 if (p->unit)
947 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
948 else
949 set_parameter_const (&block, var, IOPARM_common_unit, 0);
950
951 tmp = gfc_build_addr_expr (NULL_TREE, var);
952 tmp = build_call_expr_loc (input_location,
953 iocall[IOCALL_OPEN], 1, tmp);
954 gfc_add_expr_to_block (&block, tmp);
955
956 gfc_add_block_to_block (&block, &post_block);
957
958 io_result (&block, var, p->err, NULL, NULL);
959
960 return gfc_finish_block (&block);
961 }
962
963
964 /* Translate a CLOSE statement. */
965
966 tree
967 gfc_trans_close (gfc_code * code)
968 {
969 stmtblock_t block, post_block;
970 gfc_close *p;
971 tree tmp, var;
972 unsigned int mask = 0;
973
974 gfc_start_block (&block);
975 gfc_init_block (&post_block);
976
977 var = gfc_create_var (st_parameter[IOPARM_ptype_close].type, "close_parm");
978
979 set_error_locus (&block, var, &code->loc);
980 p = code->ext.close;
981
982 if (p->iomsg)
983 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
984 p->iomsg);
985
986 if (p->iostat)
987 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
988 p->iostat);
989
990 if (p->err)
991 mask |= IOPARM_common_err;
992
993 if (p->status)
994 mask |= set_string (&block, &post_block, var, IOPARM_close_status,
995 p->status);
996
997 set_parameter_const (&block, var, IOPARM_common_flags, mask);
998
999 if (p->unit)
1000 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1001 else
1002 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1003
1004 tmp = gfc_build_addr_expr (NULL_TREE, var);
1005 tmp = build_call_expr_loc (input_location,
1006 iocall[IOCALL_CLOSE], 1, tmp);
1007 gfc_add_expr_to_block (&block, tmp);
1008
1009 gfc_add_block_to_block (&block, &post_block);
1010
1011 io_result (&block, var, p->err, NULL, NULL);
1012
1013 return gfc_finish_block (&block);
1014 }
1015
1016
1017 /* Common subroutine for building a file positioning statement. */
1018
1019 static tree
1020 build_filepos (tree function, gfc_code * code)
1021 {
1022 stmtblock_t block, post_block;
1023 gfc_filepos *p;
1024 tree tmp, var;
1025 unsigned int mask = 0;
1026
1027 p = code->ext.filepos;
1028
1029 gfc_start_block (&block);
1030 gfc_init_block (&post_block);
1031
1032 var = gfc_create_var (st_parameter[IOPARM_ptype_filepos].type,
1033 "filepos_parm");
1034
1035 set_error_locus (&block, var, &code->loc);
1036
1037 if (p->iomsg)
1038 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1039 p->iomsg);
1040
1041 if (p->iostat)
1042 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1043 p->iostat);
1044
1045 if (p->err)
1046 mask |= IOPARM_common_err;
1047
1048 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1049
1050 if (p->unit)
1051 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1052 else
1053 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1054
1055 tmp = gfc_build_addr_expr (NULL_TREE, var);
1056 tmp = build_call_expr_loc (input_location,
1057 function, 1, tmp);
1058 gfc_add_expr_to_block (&block, tmp);
1059
1060 gfc_add_block_to_block (&block, &post_block);
1061
1062 io_result (&block, var, p->err, NULL, NULL);
1063
1064 return gfc_finish_block (&block);
1065 }
1066
1067
1068 /* Translate a BACKSPACE statement. */
1069
1070 tree
1071 gfc_trans_backspace (gfc_code * code)
1072 {
1073 return build_filepos (iocall[IOCALL_BACKSPACE], code);
1074 }
1075
1076
1077 /* Translate an ENDFILE statement. */
1078
1079 tree
1080 gfc_trans_endfile (gfc_code * code)
1081 {
1082 return build_filepos (iocall[IOCALL_ENDFILE], code);
1083 }
1084
1085
1086 /* Translate a REWIND statement. */
1087
1088 tree
1089 gfc_trans_rewind (gfc_code * code)
1090 {
1091 return build_filepos (iocall[IOCALL_REWIND], code);
1092 }
1093
1094
1095 /* Translate a FLUSH statement. */
1096
1097 tree
1098 gfc_trans_flush (gfc_code * code)
1099 {
1100 return build_filepos (iocall[IOCALL_FLUSH], code);
1101 }
1102
1103
1104 /* Create a dummy iostat variable to catch any error due to bad unit. */
1105
1106 static gfc_expr *
1107 create_dummy_iostat (void)
1108 {
1109 gfc_symtree *st;
1110 gfc_expr *e;
1111
1112 gfc_get_ha_sym_tree ("@iostat", &st);
1113 st->n.sym->ts.type = BT_INTEGER;
1114 st->n.sym->ts.kind = gfc_default_integer_kind;
1115 gfc_set_sym_referenced (st->n.sym);
1116 gfc_commit_symbol (st->n.sym);
1117 st->n.sym->backend_decl
1118 = gfc_create_var (gfc_get_int_type (st->n.sym->ts.kind),
1119 st->n.sym->name);
1120
1121 e = gfc_get_expr ();
1122 e->expr_type = EXPR_VARIABLE;
1123 e->symtree = st;
1124 e->ts.type = BT_INTEGER;
1125 e->ts.kind = st->n.sym->ts.kind;
1126
1127 return e;
1128 }
1129
1130
1131 /* Translate the non-IOLENGTH form of an INQUIRE statement. */
1132
1133 tree
1134 gfc_trans_inquire (gfc_code * code)
1135 {
1136 stmtblock_t block, post_block;
1137 gfc_inquire *p;
1138 tree tmp, var;
1139 unsigned int mask = 0, mask2 = 0;
1140
1141 gfc_start_block (&block);
1142 gfc_init_block (&post_block);
1143
1144 var = gfc_create_var (st_parameter[IOPARM_ptype_inquire].type,
1145 "inquire_parm");
1146
1147 set_error_locus (&block, var, &code->loc);
1148 p = code->ext.inquire;
1149
1150 if (p->iomsg)
1151 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1152 p->iomsg);
1153
1154 if (p->iostat)
1155 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1156 p->iostat);
1157
1158 if (p->err)
1159 mask |= IOPARM_common_err;
1160
1161 /* Sanity check. */
1162 if (p->unit && p->file)
1163 gfc_error ("INQUIRE statement at %L cannot contain both FILE and UNIT specifiers", &code->loc);
1164
1165 if (p->file)
1166 mask |= set_string (&block, &post_block, var, IOPARM_inquire_file,
1167 p->file);
1168
1169 if (p->exist)
1170 {
1171 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_exist,
1172 p->exist);
1173
1174 if (p->unit && !p->iostat)
1175 {
1176 p->iostat = create_dummy_iostat ();
1177 mask |= set_parameter_ref (&block, &post_block, var,
1178 IOPARM_common_iostat, p->iostat);
1179 }
1180 }
1181
1182 if (p->opened)
1183 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_opened,
1184 p->opened);
1185
1186 if (p->number)
1187 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_number,
1188 p->number);
1189
1190 if (p->named)
1191 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_named,
1192 p->named);
1193
1194 if (p->name)
1195 mask |= set_string (&block, &post_block, var, IOPARM_inquire_name,
1196 p->name);
1197
1198 if (p->access)
1199 mask |= set_string (&block, &post_block, var, IOPARM_inquire_access,
1200 p->access);
1201
1202 if (p->sequential)
1203 mask |= set_string (&block, &post_block, var, IOPARM_inquire_sequential,
1204 p->sequential);
1205
1206 if (p->direct)
1207 mask |= set_string (&block, &post_block, var, IOPARM_inquire_direct,
1208 p->direct);
1209
1210 if (p->form)
1211 mask |= set_string (&block, &post_block, var, IOPARM_inquire_form,
1212 p->form);
1213
1214 if (p->formatted)
1215 mask |= set_string (&block, &post_block, var, IOPARM_inquire_formatted,
1216 p->formatted);
1217
1218 if (p->unformatted)
1219 mask |= set_string (&block, &post_block, var, IOPARM_inquire_unformatted,
1220 p->unformatted);
1221
1222 if (p->recl)
1223 mask |= set_parameter_ref (&block, &post_block, var,
1224 IOPARM_inquire_recl_out, p->recl);
1225
1226 if (p->nextrec)
1227 mask |= set_parameter_ref (&block, &post_block, var,
1228 IOPARM_inquire_nextrec, p->nextrec);
1229
1230 if (p->blank)
1231 mask |= set_string (&block, &post_block, var, IOPARM_inquire_blank,
1232 p->blank);
1233
1234 if (p->delim)
1235 mask |= set_string (&block, &post_block, var, IOPARM_inquire_delim,
1236 p->delim);
1237
1238 if (p->position)
1239 mask |= set_string (&block, &post_block, var, IOPARM_inquire_position,
1240 p->position);
1241
1242 if (p->action)
1243 mask |= set_string (&block, &post_block, var, IOPARM_inquire_action,
1244 p->action);
1245
1246 if (p->read)
1247 mask |= set_string (&block, &post_block, var, IOPARM_inquire_read,
1248 p->read);
1249
1250 if (p->write)
1251 mask |= set_string (&block, &post_block, var, IOPARM_inquire_write,
1252 p->write);
1253
1254 if (p->readwrite)
1255 mask |= set_string (&block, &post_block, var, IOPARM_inquire_readwrite,
1256 p->readwrite);
1257
1258 if (p->pad)
1259 mask |= set_string (&block, &post_block, var, IOPARM_inquire_pad,
1260 p->pad);
1261
1262 if (p->convert)
1263 mask |= set_string (&block, &post_block, var, IOPARM_inquire_convert,
1264 p->convert);
1265
1266 if (p->strm_pos)
1267 mask |= set_parameter_ref (&block, &post_block, var,
1268 IOPARM_inquire_strm_pos_out, p->strm_pos);
1269
1270 /* The second series of flags. */
1271 if (p->asynchronous)
1272 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_asynchronous,
1273 p->asynchronous);
1274
1275 if (p->decimal)
1276 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_decimal,
1277 p->decimal);
1278
1279 if (p->encoding)
1280 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_encoding,
1281 p->encoding);
1282
1283 if (p->round)
1284 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_round,
1285 p->round);
1286
1287 if (p->sign)
1288 mask2 |= set_string (&block, &post_block, var, IOPARM_inquire_sign,
1289 p->sign);
1290
1291 if (p->pending)
1292 mask2 |= set_parameter_ref (&block, &post_block, var,
1293 IOPARM_inquire_pending, p->pending);
1294
1295 if (p->size)
1296 mask2 |= set_parameter_ref (&block, &post_block, var, IOPARM_inquire_size,
1297 p->size);
1298
1299 if (p->id)
1300 mask2 |= set_parameter_ref (&block, &post_block,var, IOPARM_inquire_id,
1301 p->id);
1302
1303 if (mask2)
1304 mask |= set_parameter_const (&block, var, IOPARM_inquire_flags2, mask2);
1305
1306 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1307
1308 if (p->unit)
1309 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1310 else
1311 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1312
1313 tmp = gfc_build_addr_expr (NULL_TREE, var);
1314 tmp = build_call_expr_loc (input_location,
1315 iocall[IOCALL_INQUIRE], 1, tmp);
1316 gfc_add_expr_to_block (&block, tmp);
1317
1318 gfc_add_block_to_block (&block, &post_block);
1319
1320 io_result (&block, var, p->err, NULL, NULL);
1321
1322 return gfc_finish_block (&block);
1323 }
1324
1325
1326 tree
1327 gfc_trans_wait (gfc_code * code)
1328 {
1329 stmtblock_t block, post_block;
1330 gfc_wait *p;
1331 tree tmp, var;
1332 unsigned int mask = 0;
1333
1334 gfc_start_block (&block);
1335 gfc_init_block (&post_block);
1336
1337 var = gfc_create_var (st_parameter[IOPARM_ptype_wait].type,
1338 "wait_parm");
1339
1340 set_error_locus (&block, var, &code->loc);
1341 p = code->ext.wait;
1342
1343 /* Set parameters here. */
1344 if (p->iomsg)
1345 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1346 p->iomsg);
1347
1348 if (p->iostat)
1349 mask |= set_parameter_ref (&block, &post_block, var, IOPARM_common_iostat,
1350 p->iostat);
1351
1352 if (p->err)
1353 mask |= IOPARM_common_err;
1354
1355 if (p->id)
1356 mask |= set_parameter_value (&block, var, IOPARM_wait_id, p->id);
1357
1358 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1359
1360 if (p->unit)
1361 set_parameter_value (&block, var, IOPARM_common_unit, p->unit);
1362
1363 tmp = gfc_build_addr_expr (NULL_TREE, var);
1364 tmp = build_call_expr_loc (input_location,
1365 iocall[IOCALL_WAIT], 1, tmp);
1366 gfc_add_expr_to_block (&block, tmp);
1367
1368 gfc_add_block_to_block (&block, &post_block);
1369
1370 io_result (&block, var, p->err, NULL, NULL);
1371
1372 return gfc_finish_block (&block);
1373
1374 }
1375
1376
1377 /* nml_full_name builds up the fully qualified name of a
1378 derived type component. */
1379
1380 static char*
1381 nml_full_name (const char* var_name, const char* cmp_name)
1382 {
1383 int full_name_length;
1384 char * full_name;
1385
1386 full_name_length = strlen (var_name) + strlen (cmp_name) + 1;
1387 full_name = (char*)gfc_getmem (full_name_length + 1);
1388 strcpy (full_name, var_name);
1389 full_name = strcat (full_name, "%");
1390 full_name = strcat (full_name, cmp_name);
1391 return full_name;
1392 }
1393
1394 /* nml_get_addr_expr builds an address expression from the
1395 gfc_symbol or gfc_component backend_decl's. An offset is
1396 provided so that the address of an element of an array of
1397 derived types is returned. This is used in the runtime to
1398 determine that span of the derived type. */
1399
1400 static tree
1401 nml_get_addr_expr (gfc_symbol * sym, gfc_component * c,
1402 tree base_addr)
1403 {
1404 tree decl = NULL_TREE;
1405 tree tmp;
1406 tree itmp;
1407 int array_flagged;
1408 int dummy_arg_flagged;
1409
1410 if (sym)
1411 {
1412 sym->attr.referenced = 1;
1413 decl = gfc_get_symbol_decl (sym);
1414
1415 /* If this is the enclosing function declaration, use
1416 the fake result instead. */
1417 if (decl == current_function_decl)
1418 decl = gfc_get_fake_result_decl (sym, 0);
1419 else if (decl == DECL_CONTEXT (current_function_decl))
1420 decl = gfc_get_fake_result_decl (sym, 1);
1421 }
1422 else
1423 decl = c->backend_decl;
1424
1425 gcc_assert (decl && ((TREE_CODE (decl) == FIELD_DECL
1426 || TREE_CODE (decl) == VAR_DECL
1427 || TREE_CODE (decl) == PARM_DECL)
1428 || TREE_CODE (decl) == COMPONENT_REF));
1429
1430 tmp = decl;
1431
1432 /* Build indirect reference, if dummy argument. */
1433
1434 dummy_arg_flagged = POINTER_TYPE_P (TREE_TYPE(tmp));
1435
1436 itmp = (dummy_arg_flagged) ? build_fold_indirect_ref_loc (input_location,
1437 tmp) : tmp;
1438
1439 /* If an array, set flag and use indirect ref. if built. */
1440
1441 array_flagged = (TREE_CODE (TREE_TYPE (itmp)) == ARRAY_TYPE
1442 && !TYPE_STRING_FLAG (TREE_TYPE (itmp)));
1443
1444 if (array_flagged)
1445 tmp = itmp;
1446
1447 /* Treat the component of a derived type, using base_addr for
1448 the derived type. */
1449
1450 if (TREE_CODE (decl) == FIELD_DECL)
1451 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (tmp),
1452 base_addr, tmp, NULL_TREE);
1453
1454 /* If we have a derived type component, a reference to the first
1455 element of the array is built. This is done so that base_addr,
1456 used in the build of the component reference, always points to
1457 a RECORD_TYPE. */
1458
1459 if (array_flagged)
1460 tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL);
1461
1462 /* Now build the address expression. */
1463
1464 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
1465
1466 /* If scalar dummy, resolve indirect reference now. */
1467
1468 if (dummy_arg_flagged && !array_flagged)
1469 tmp = build_fold_indirect_ref_loc (input_location,
1470 tmp);
1471
1472 gcc_assert (tmp && POINTER_TYPE_P (TREE_TYPE (tmp)));
1473
1474 return tmp;
1475 }
1476
1477 /* For an object VAR_NAME whose base address is BASE_ADDR, generate a
1478 call to iocall[IOCALL_SET_NML_VAL]. For derived type variable, recursively
1479 generate calls to iocall[IOCALL_SET_NML_VAL] for each component. */
1480
1481 #define IARG(i) build_int_cst (gfc_array_index_type, i)
1482
1483 static void
1484 transfer_namelist_element (stmtblock_t * block, const char * var_name,
1485 gfc_symbol * sym, gfc_component * c,
1486 tree base_addr)
1487 {
1488 gfc_typespec * ts = NULL;
1489 gfc_array_spec * as = NULL;
1490 tree addr_expr = NULL;
1491 tree dt = NULL;
1492 tree string;
1493 tree tmp;
1494 tree dtype;
1495 tree dt_parm_addr;
1496 int n_dim;
1497 int itype;
1498 int rank = 0;
1499
1500 gcc_assert (sym || c);
1501
1502 /* Build the namelist object name. */
1503
1504 string = gfc_build_cstring_const (var_name);
1505 string = gfc_build_addr_expr (pchar_type_node, string);
1506
1507 /* Build ts, as and data address using symbol or component. */
1508
1509 ts = (sym) ? &sym->ts : &c->ts;
1510 as = (sym) ? sym->as : c->as;
1511
1512 addr_expr = nml_get_addr_expr (sym, c, base_addr);
1513
1514 if (as)
1515 rank = as->rank;
1516
1517 if (rank)
1518 {
1519 dt = TREE_TYPE ((sym) ? sym->backend_decl : c->backend_decl);
1520 dtype = gfc_get_dtype (dt);
1521 }
1522 else
1523 {
1524 itype = GFC_DTYPE_UNKNOWN;
1525
1526 switch (ts->type)
1527
1528 {
1529 case BT_INTEGER:
1530 itype = GFC_DTYPE_INTEGER;
1531 break;
1532 case BT_LOGICAL:
1533 itype = GFC_DTYPE_LOGICAL;
1534 break;
1535 case BT_REAL:
1536 itype = GFC_DTYPE_REAL;
1537 break;
1538 case BT_COMPLEX:
1539 itype = GFC_DTYPE_COMPLEX;
1540 break;
1541 case BT_DERIVED:
1542 itype = GFC_DTYPE_DERIVED;
1543 break;
1544 case BT_CHARACTER:
1545 itype = GFC_DTYPE_CHARACTER;
1546 break;
1547 default:
1548 gcc_unreachable ();
1549 }
1550
1551 dtype = IARG (itype << GFC_DTYPE_TYPE_SHIFT);
1552 }
1553
1554 /* Build up the arguments for the transfer call.
1555 The call for the scalar part transfers:
1556 (address, name, type, kind or string_length, dtype) */
1557
1558 dt_parm_addr = gfc_build_addr_expr (NULL_TREE, dt_parm);
1559
1560 if (ts->type == BT_CHARACTER)
1561 tmp = ts->u.cl->backend_decl;
1562 else
1563 tmp = build_int_cst (gfc_charlen_type_node, 0);
1564 tmp = build_call_expr_loc (input_location,
1565 iocall[IOCALL_SET_NML_VAL], 6,
1566 dt_parm_addr, addr_expr, string,
1567 IARG (ts->kind), tmp, dtype);
1568 gfc_add_expr_to_block (block, tmp);
1569
1570 /* If the object is an array, transfer rank times:
1571 (null pointer, name, stride, lbound, ubound) */
1572
1573 for ( n_dim = 0 ; n_dim < rank ; n_dim++ )
1574 {
1575 tmp = build_call_expr_loc (input_location,
1576 iocall[IOCALL_SET_NML_VAL_DIM], 5,
1577 dt_parm_addr,
1578 IARG (n_dim),
1579 GFC_TYPE_ARRAY_STRIDE (dt, n_dim),
1580 GFC_TYPE_ARRAY_LBOUND (dt, n_dim),
1581 GFC_TYPE_ARRAY_UBOUND (dt, n_dim));
1582 gfc_add_expr_to_block (block, tmp);
1583 }
1584
1585 if (ts->type == BT_DERIVED)
1586 {
1587 gfc_component *cmp;
1588
1589 /* Provide the RECORD_TYPE to build component references. */
1590
1591 tree expr = build_fold_indirect_ref_loc (input_location,
1592 addr_expr);
1593
1594 for (cmp = ts->u.derived->components; cmp; cmp = cmp->next)
1595 {
1596 char *full_name = nml_full_name (var_name, cmp->name);
1597 transfer_namelist_element (block,
1598 full_name,
1599 NULL, cmp, expr);
1600 gfc_free (full_name);
1601 }
1602 }
1603 }
1604
1605 #undef IARG
1606
1607 /* Create a data transfer statement. Not all of the fields are valid
1608 for both reading and writing, but improper use has been filtered
1609 out by now. */
1610
1611 static tree
1612 build_dt (tree function, gfc_code * code)
1613 {
1614 stmtblock_t block, post_block, post_end_block, post_iu_block;
1615 gfc_dt *dt;
1616 tree tmp, var;
1617 gfc_expr *nmlname;
1618 gfc_namelist *nml;
1619 unsigned int mask = 0;
1620
1621 gfc_start_block (&block);
1622 gfc_init_block (&post_block);
1623 gfc_init_block (&post_end_block);
1624 gfc_init_block (&post_iu_block);
1625
1626 var = gfc_create_var (st_parameter[IOPARM_ptype_dt].type, "dt_parm");
1627
1628 set_error_locus (&block, var, &code->loc);
1629
1630 if (last_dt == IOLENGTH)
1631 {
1632 gfc_inquire *inq;
1633
1634 inq = code->ext.inquire;
1635
1636 /* First check that preconditions are met. */
1637 gcc_assert (inq != NULL);
1638 gcc_assert (inq->iolength != NULL);
1639
1640 /* Connect to the iolength variable. */
1641 mask |= set_parameter_ref (&block, &post_end_block, var,
1642 IOPARM_dt_iolength, inq->iolength);
1643 dt = NULL;
1644 }
1645 else
1646 {
1647 dt = code->ext.dt;
1648 gcc_assert (dt != NULL);
1649 }
1650
1651 if (dt && dt->io_unit)
1652 {
1653 if (dt->io_unit->ts.type == BT_CHARACTER)
1654 {
1655 mask |= set_internal_unit (&block, &post_iu_block,
1656 var, dt->io_unit);
1657 set_parameter_const (&block, var, IOPARM_common_unit,
1658 dt->io_unit->ts.kind == 1 ? 0 : -1);
1659 }
1660 }
1661 else
1662 set_parameter_const (&block, var, IOPARM_common_unit, 0);
1663
1664 if (dt)
1665 {
1666 if (dt->iomsg)
1667 mask |= set_string (&block, &post_block, var, IOPARM_common_iomsg,
1668 dt->iomsg);
1669
1670 if (dt->iostat)
1671 mask |= set_parameter_ref (&block, &post_end_block, var,
1672 IOPARM_common_iostat, dt->iostat);
1673
1674 if (dt->err)
1675 mask |= IOPARM_common_err;
1676
1677 if (dt->eor)
1678 mask |= IOPARM_common_eor;
1679
1680 if (dt->end)
1681 mask |= IOPARM_common_end;
1682
1683 if (dt->id)
1684 mask |= set_parameter_ref (&block, &post_end_block, var,
1685 IOPARM_dt_id, dt->id);
1686
1687 if (dt->pos)
1688 mask |= set_parameter_value (&block, var, IOPARM_dt_pos, dt->pos);
1689
1690 if (dt->asynchronous)
1691 mask |= set_string (&block, &post_block, var, IOPARM_dt_asynchronous,
1692 dt->asynchronous);
1693
1694 if (dt->blank)
1695 mask |= set_string (&block, &post_block, var, IOPARM_dt_blank,
1696 dt->blank);
1697
1698 if (dt->decimal)
1699 mask |= set_string (&block, &post_block, var, IOPARM_dt_decimal,
1700 dt->decimal);
1701
1702 if (dt->delim)
1703 mask |= set_string (&block, &post_block, var, IOPARM_dt_delim,
1704 dt->delim);
1705
1706 if (dt->pad)
1707 mask |= set_string (&block, &post_block, var, IOPARM_dt_pad,
1708 dt->pad);
1709
1710 if (dt->round)
1711 mask |= set_string (&block, &post_block, var, IOPARM_dt_round,
1712 dt->round);
1713
1714 if (dt->sign)
1715 mask |= set_string (&block, &post_block, var, IOPARM_dt_sign,
1716 dt->sign);
1717
1718 if (dt->rec)
1719 mask |= set_parameter_value (&block, var, IOPARM_dt_rec, dt->rec);
1720
1721 if (dt->advance)
1722 mask |= set_string (&block, &post_block, var, IOPARM_dt_advance,
1723 dt->advance);
1724
1725 if (dt->format_expr)
1726 mask |= set_string (&block, &post_end_block, var, IOPARM_dt_format,
1727 dt->format_expr);
1728
1729 if (dt->format_label)
1730 {
1731 if (dt->format_label == &format_asterisk)
1732 mask |= IOPARM_dt_list_format;
1733 else
1734 mask |= set_string (&block, &post_block, var, IOPARM_dt_format,
1735 dt->format_label->format);
1736 }
1737
1738 if (dt->size)
1739 mask |= set_parameter_ref (&block, &post_end_block, var,
1740 IOPARM_dt_size, dt->size);
1741
1742 if (dt->namelist)
1743 {
1744 if (dt->format_expr || dt->format_label)
1745 gfc_internal_error ("build_dt: format with namelist");
1746
1747 nmlname = gfc_get_character_expr (gfc_default_character_kind, NULL,
1748 dt->namelist->name,
1749 strlen (dt->namelist->name));
1750
1751 mask |= set_string (&block, &post_block, var, IOPARM_dt_namelist_name,
1752 nmlname);
1753
1754 if (last_dt == READ)
1755 mask |= IOPARM_dt_namelist_read_mode;
1756
1757 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1758
1759 dt_parm = var;
1760
1761 for (nml = dt->namelist->namelist; nml; nml = nml->next)
1762 transfer_namelist_element (&block, nml->sym->name, nml->sym,
1763 NULL, NULL_TREE);
1764 }
1765 else
1766 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1767
1768 if (dt->io_unit && dt->io_unit->ts.type == BT_INTEGER)
1769 set_parameter_value (&block, var, IOPARM_common_unit, dt->io_unit);
1770 }
1771 else
1772 set_parameter_const (&block, var, IOPARM_common_flags, mask);
1773
1774 tmp = gfc_build_addr_expr (NULL_TREE, var);
1775 tmp = build_call_expr_loc (UNKNOWN_LOCATION,
1776 function, 1, tmp);
1777 gfc_add_expr_to_block (&block, tmp);
1778
1779 gfc_add_block_to_block (&block, &post_block);
1780
1781 dt_parm = var;
1782 dt_post_end_block = &post_end_block;
1783
1784 /* Set implied do loop exit condition. */
1785 if (last_dt == READ || last_dt == WRITE)
1786 {
1787 gfc_st_parameter_field *p = &st_parameter_field[IOPARM_common_flags];
1788
1789 tmp = fold_build3 (COMPONENT_REF, st_parameter[IOPARM_ptype_common].type,
1790 dt_parm, TYPE_FIELDS (TREE_TYPE (dt_parm)), NULL_TREE);
1791 tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
1792 tmp, p->field, NULL_TREE);
1793 tmp = fold_build2 (BIT_AND_EXPR, TREE_TYPE (tmp),
1794 tmp, build_int_cst (TREE_TYPE (tmp),
1795 IOPARM_common_libreturn_mask));
1796 }
1797 else /* IOLENGTH */
1798 tmp = NULL_TREE;
1799
1800 gfc_add_expr_to_block (&block, gfc_trans_code_cond (code->block->next, tmp));
1801
1802 gfc_add_block_to_block (&block, &post_iu_block);
1803
1804 dt_parm = NULL;
1805 dt_post_end_block = NULL;
1806
1807 return gfc_finish_block (&block);
1808 }
1809
1810
1811 /* Translate the IOLENGTH form of an INQUIRE statement. We treat
1812 this as a third sort of data transfer statement, except that
1813 lengths are summed instead of actually transferring any data. */
1814
1815 tree
1816 gfc_trans_iolength (gfc_code * code)
1817 {
1818 last_dt = IOLENGTH;
1819 return build_dt (iocall[IOCALL_IOLENGTH], code);
1820 }
1821
1822
1823 /* Translate a READ statement. */
1824
1825 tree
1826 gfc_trans_read (gfc_code * code)
1827 {
1828 last_dt = READ;
1829 return build_dt (iocall[IOCALL_READ], code);
1830 }
1831
1832
1833 /* Translate a WRITE statement */
1834
1835 tree
1836 gfc_trans_write (gfc_code * code)
1837 {
1838 last_dt = WRITE;
1839 return build_dt (iocall[IOCALL_WRITE], code);
1840 }
1841
1842
1843 /* Finish a data transfer statement. */
1844
1845 tree
1846 gfc_trans_dt_end (gfc_code * code)
1847 {
1848 tree function, tmp;
1849 stmtblock_t block;
1850
1851 gfc_init_block (&block);
1852
1853 switch (last_dt)
1854 {
1855 case READ:
1856 function = iocall[IOCALL_READ_DONE];
1857 break;
1858
1859 case WRITE:
1860 function = iocall[IOCALL_WRITE_DONE];
1861 break;
1862
1863 case IOLENGTH:
1864 function = iocall[IOCALL_IOLENGTH_DONE];
1865 break;
1866
1867 default:
1868 gcc_unreachable ();
1869 }
1870
1871 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
1872 tmp = build_call_expr_loc (input_location,
1873 function, 1, tmp);
1874 gfc_add_expr_to_block (&block, tmp);
1875 gfc_add_block_to_block (&block, dt_post_end_block);
1876 gfc_init_block (dt_post_end_block);
1877
1878 if (last_dt != IOLENGTH)
1879 {
1880 gcc_assert (code->ext.dt != NULL);
1881 io_result (&block, dt_parm, code->ext.dt->err,
1882 code->ext.dt->end, code->ext.dt->eor);
1883 }
1884
1885 return gfc_finish_block (&block);
1886 }
1887
1888 static void
1889 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code);
1890
1891 /* Given an array field in a derived type variable, generate the code
1892 for the loop that iterates over array elements, and the code that
1893 accesses those array elements. Use transfer_expr to generate code
1894 for transferring that element. Because elements may also be
1895 derived types, transfer_expr and transfer_array_component are mutually
1896 recursive. */
1897
1898 static tree
1899 transfer_array_component (tree expr, gfc_component * cm, locus * where)
1900 {
1901 tree tmp;
1902 stmtblock_t body;
1903 stmtblock_t block;
1904 gfc_loopinfo loop;
1905 int n;
1906 gfc_ss *ss;
1907 gfc_se se;
1908
1909 gfc_start_block (&block);
1910 gfc_init_se (&se, NULL);
1911
1912 /* Create and initialize Scalarization Status. Unlike in
1913 gfc_trans_transfer, we can't simply use gfc_walk_expr to take
1914 care of this task, because we don't have a gfc_expr at hand.
1915 Build one manually, as in gfc_trans_subarray_assign. */
1916
1917 ss = gfc_get_ss ();
1918 ss->type = GFC_SS_COMPONENT;
1919 ss->expr = NULL;
1920 ss->shape = gfc_get_shape (cm->as->rank);
1921 ss->next = gfc_ss_terminator;
1922 ss->data.info.dimen = cm->as->rank;
1923 ss->data.info.descriptor = expr;
1924 ss->data.info.data = gfc_conv_array_data (expr);
1925 ss->data.info.offset = gfc_conv_array_offset (expr);
1926 for (n = 0; n < cm->as->rank; n++)
1927 {
1928 ss->data.info.dim[n] = n;
1929 ss->data.info.start[n] = gfc_conv_array_lbound (expr, n);
1930 ss->data.info.stride[n] = gfc_index_one_node;
1931
1932 mpz_init (ss->shape[n]);
1933 mpz_sub (ss->shape[n], cm->as->upper[n]->value.integer,
1934 cm->as->lower[n]->value.integer);
1935 mpz_add_ui (ss->shape[n], ss->shape[n], 1);
1936 }
1937
1938 /* Once we got ss, we use scalarizer to create the loop. */
1939
1940 gfc_init_loopinfo (&loop);
1941 gfc_add_ss_to_loop (&loop, ss);
1942 gfc_conv_ss_startstride (&loop);
1943 gfc_conv_loop_setup (&loop, where);
1944 gfc_mark_ss_chain_used (ss, 1);
1945 gfc_start_scalarized_body (&loop, &body);
1946
1947 gfc_copy_loopinfo_to_se (&se, &loop);
1948 se.ss = ss;
1949
1950 /* gfc_conv_tmp_array_ref assumes that se.expr contains the array. */
1951 se.expr = expr;
1952 gfc_conv_tmp_array_ref (&se);
1953
1954 /* Now se.expr contains an element of the array. Take the address and pass
1955 it to the IO routines. */
1956 tmp = gfc_build_addr_expr (NULL_TREE, se.expr);
1957 transfer_expr (&se, &cm->ts, tmp, NULL);
1958
1959 /* We are done now with the loop body. Wrap up the scalarizer and
1960 return. */
1961
1962 gfc_add_block_to_block (&body, &se.pre);
1963 gfc_add_block_to_block (&body, &se.post);
1964
1965 gfc_trans_scalarizing_loops (&loop, &body);
1966
1967 gfc_add_block_to_block (&block, &loop.pre);
1968 gfc_add_block_to_block (&block, &loop.post);
1969
1970 for (n = 0; n < cm->as->rank; n++)
1971 mpz_clear (ss->shape[n]);
1972 gfc_free (ss->shape);
1973
1974 gfc_cleanup_loop (&loop);
1975
1976 return gfc_finish_block (&block);
1977 }
1978
1979 /* Generate the call for a scalar transfer node. */
1980
1981 static void
1982 transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
1983 {
1984 tree tmp, function, arg2, arg3, field, expr;
1985 gfc_component *c;
1986 int kind;
1987
1988 /* It is possible to get a C_NULL_PTR or C_NULL_FUNPTR expression here if
1989 the user says something like: print *, 'c_null_ptr: ', c_null_ptr
1990 We need to translate the expression to a constant if it's either
1991 C_NULL_PTR or C_NULL_FUNPTR. We could also get a user variable of
1992 type C_PTR or C_FUNPTR, in which case the ts->type may no longer be
1993 BT_DERIVED (could have been changed by gfc_conv_expr). */
1994 if ((ts->type == BT_DERIVED || ts->type == BT_INTEGER)
1995 && ts->u.derived != NULL
1996 && (ts->is_iso_c == 1 || ts->u.derived->ts.is_iso_c == 1))
1997 {
1998 /* C_PTR and C_FUNPTR have private components which means they can not
1999 be printed. However, if -std=gnu and not -pedantic, allow
2000 the component to be printed to help debugging. */
2001 if (gfc_notification_std (GFC_STD_GNU) != SILENT)
2002 {
2003 gfc_error_now ("Derived type '%s' at %L has PRIVATE components",
2004 ts->u.derived->name, code != NULL ? &(code->loc) :
2005 &gfc_current_locus);
2006 return;
2007 }
2008
2009 ts->type = ts->u.derived->ts.type;
2010 ts->kind = ts->u.derived->ts.kind;
2011 ts->f90_type = ts->u.derived->ts.f90_type;
2012 }
2013
2014 kind = ts->kind;
2015 function = NULL;
2016 arg2 = NULL;
2017 arg3 = NULL;
2018
2019 switch (ts->type)
2020 {
2021 case BT_INTEGER:
2022 arg2 = build_int_cst (NULL_TREE, kind);
2023 function = iocall[IOCALL_X_INTEGER];
2024 break;
2025
2026 case BT_REAL:
2027 arg2 = build_int_cst (NULL_TREE, kind);
2028 function = iocall[IOCALL_X_REAL];
2029 break;
2030
2031 case BT_COMPLEX:
2032 arg2 = build_int_cst (NULL_TREE, kind);
2033 function = iocall[IOCALL_X_COMPLEX];
2034 break;
2035
2036 case BT_LOGICAL:
2037 arg2 = build_int_cst (NULL_TREE, kind);
2038 function = iocall[IOCALL_X_LOGICAL];
2039 break;
2040
2041 case BT_CHARACTER:
2042 if (kind == 4)
2043 {
2044 if (se->string_length)
2045 arg2 = se->string_length;
2046 else
2047 {
2048 tmp = build_fold_indirect_ref_loc (input_location,
2049 addr_expr);
2050 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2051 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2052 arg2 = fold_convert (gfc_charlen_type_node, arg2);
2053 }
2054 arg3 = build_int_cst (NULL_TREE, kind);
2055 function = iocall[IOCALL_X_CHARACTER_WIDE];
2056 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2057 tmp = build_call_expr_loc (input_location,
2058 function, 4, tmp, addr_expr, arg2, arg3);
2059 gfc_add_expr_to_block (&se->pre, tmp);
2060 gfc_add_block_to_block (&se->pre, &se->post);
2061 return;
2062 }
2063 /* Fall through. */
2064 case BT_HOLLERITH:
2065 if (se->string_length)
2066 arg2 = se->string_length;
2067 else
2068 {
2069 tmp = build_fold_indirect_ref_loc (input_location,
2070 addr_expr);
2071 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
2072 arg2 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
2073 }
2074 function = iocall[IOCALL_X_CHARACTER];
2075 break;
2076
2077 case BT_DERIVED:
2078 /* Recurse into the elements of the derived type. */
2079 expr = gfc_evaluate_now (addr_expr, &se->pre);
2080 expr = build_fold_indirect_ref_loc (input_location,
2081 expr);
2082
2083 for (c = ts->u.derived->components; c; c = c->next)
2084 {
2085 field = c->backend_decl;
2086 gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
2087
2088 tmp = fold_build3_loc (UNKNOWN_LOCATION,
2089 COMPONENT_REF, TREE_TYPE (field),
2090 expr, field, NULL_TREE);
2091
2092 if (c->attr.dimension)
2093 {
2094 tmp = transfer_array_component (tmp, c, & code->loc);
2095 gfc_add_expr_to_block (&se->pre, tmp);
2096 }
2097 else
2098 {
2099 if (!c->attr.pointer)
2100 tmp = gfc_build_addr_expr (NULL_TREE, tmp);
2101 transfer_expr (se, &c->ts, tmp, code);
2102 }
2103 }
2104 return;
2105
2106 default:
2107 internal_error ("Bad IO basetype (%d)", ts->type);
2108 }
2109
2110 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2111 tmp = build_call_expr_loc (input_location,
2112 function, 3, tmp, addr_expr, arg2);
2113 gfc_add_expr_to_block (&se->pre, tmp);
2114 gfc_add_block_to_block (&se->pre, &se->post);
2115
2116 }
2117
2118
2119 /* Generate a call to pass an array descriptor to the IO library. The
2120 array should be of one of the intrinsic types. */
2121
2122 static void
2123 transfer_array_desc (gfc_se * se, gfc_typespec * ts, tree addr_expr)
2124 {
2125 tree tmp, charlen_arg, kind_arg;
2126
2127 if (ts->type == BT_CHARACTER)
2128 charlen_arg = se->string_length;
2129 else
2130 charlen_arg = build_int_cst (NULL_TREE, 0);
2131
2132 kind_arg = build_int_cst (NULL_TREE, ts->kind);
2133
2134 tmp = gfc_build_addr_expr (NULL_TREE, dt_parm);
2135 tmp = build_call_expr_loc (UNKNOWN_LOCATION,
2136 iocall[IOCALL_X_ARRAY], 4,
2137 tmp, addr_expr, kind_arg, charlen_arg);
2138 gfc_add_expr_to_block (&se->pre, tmp);
2139 gfc_add_block_to_block (&se->pre, &se->post);
2140 }
2141
2142
2143 /* gfc_trans_transfer()-- Translate a TRANSFER code node */
2144
2145 tree
2146 gfc_trans_transfer (gfc_code * code)
2147 {
2148 stmtblock_t block, body;
2149 gfc_loopinfo loop;
2150 gfc_expr *expr;
2151 gfc_ref *ref;
2152 gfc_ss *ss;
2153 gfc_se se;
2154 tree tmp;
2155 int n;
2156
2157 gfc_start_block (&block);
2158 gfc_init_block (&body);
2159
2160 expr = code->expr1;
2161 ss = gfc_walk_expr (expr);
2162
2163 ref = NULL;
2164 gfc_init_se (&se, NULL);
2165
2166 if (ss == gfc_ss_terminator)
2167 {
2168 /* Transfer a scalar value. */
2169 gfc_conv_expr_reference (&se, expr);
2170 transfer_expr (&se, &expr->ts, se.expr, code);
2171 }
2172 else
2173 {
2174 /* Transfer an array. If it is an array of an intrinsic
2175 type, pass the descriptor to the library. Otherwise
2176 scalarize the transfer. */
2177 if (expr->ref && !gfc_is_proc_ptr_comp (expr, NULL))
2178 {
2179 for (ref = expr->ref; ref && ref->type != REF_ARRAY;
2180 ref = ref->next);
2181 gcc_assert (ref->type == REF_ARRAY);
2182 }
2183
2184 if (expr->ts.type != BT_DERIVED
2185 && ref && ref->next == NULL
2186 && !is_subref_array (expr))
2187 {
2188 bool seen_vector = false;
2189
2190 if (ref && ref->u.ar.type == AR_SECTION)
2191 {
2192 for (n = 0; n < ref->u.ar.dimen; n++)
2193 if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
2194 seen_vector = true;
2195 }
2196
2197 if (seen_vector && last_dt == READ)
2198 {
2199 /* Create a temp, read to that and copy it back. */
2200 gfc_conv_subref_array_arg (&se, expr, 0, INTENT_OUT, false);
2201 tmp = se.expr;
2202 }
2203 else
2204 {
2205 /* Get the descriptor. */
2206 gfc_conv_expr_descriptor (&se, expr, ss);
2207 tmp = gfc_build_addr_expr (NULL_TREE, se.expr);
2208 }
2209
2210 transfer_array_desc (&se, &expr->ts, tmp);
2211 goto finish_block_label;
2212 }
2213
2214 /* Initialize the scalarizer. */
2215 gfc_init_loopinfo (&loop);
2216 gfc_add_ss_to_loop (&loop, ss);
2217
2218 /* Initialize the loop. */
2219 gfc_conv_ss_startstride (&loop);
2220 gfc_conv_loop_setup (&loop, &code->expr1->where);
2221
2222 /* The main loop body. */
2223 gfc_mark_ss_chain_used (ss, 1);
2224 gfc_start_scalarized_body (&loop, &body);
2225
2226 gfc_copy_loopinfo_to_se (&se, &loop);
2227 se.ss = ss;
2228
2229 gfc_conv_expr_reference (&se, expr);
2230 transfer_expr (&se, &expr->ts, se.expr, code);
2231 }
2232
2233 finish_block_label:
2234
2235 gfc_add_block_to_block (&body, &se.pre);
2236 gfc_add_block_to_block (&body, &se.post);
2237
2238 if (se.ss == NULL)
2239 tmp = gfc_finish_block (&body);
2240 else
2241 {
2242 gcc_assert (se.ss == gfc_ss_terminator);
2243 gfc_trans_scalarizing_loops (&loop, &body);
2244
2245 gfc_add_block_to_block (&loop.pre, &loop.post);
2246 tmp = gfc_finish_block (&loop.pre);
2247 gfc_cleanup_loop (&loop);
2248 }
2249
2250 gfc_add_expr_to_block (&block, tmp);
2251
2252 return gfc_finish_block (&block);
2253 }
2254
2255 #include "gt-fortran-trans-io.h"