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