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