OSDN Git Service

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