]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans.c
cfgloop.c (verify_loop_structure): Use %' in diagnostics.
[thirdparty/gcc.git] / gcc / fortran / trans.c
CommitLineData
6de9cd9a 1/* Code translation -- generate GCC trees from gfc_code.
fa502cb2
PT
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
6de9cd9a
DN
4 Contributed by Paul Brook
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
d234d788 10Software Foundation; either version 3, or (at your option) any later
9fc4d79b 11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
d234d788
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tree.h"
a48ba7e1 26#include "gimple.h" /* For create_tmp_var_raw. */
726a989a 27#include "tree-iterator.h"
c829d016 28#include "diagnostic-core.h" /* For internal_error. */
6de9cd9a 29#include "defaults.h"
1529b8d9 30#include "flags.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/* Naming convention for backend interface code:
39
40 gfc_trans_* translate gfc_code into STMT trees.
41
42 gfc_conv_* expression conversion
43
44 gfc_get_* get a backend tree representation of a decl or type */
45
46static gfc_file *gfc_current_backend_file;
47
7e49f965
TS
48const char gfc_msg_fault[] = N_("Array reference out of bounds");
49const char gfc_msg_wrong_return[] = N_("Incorrect function return value");
dd18a33b 50
6de9cd9a
DN
51
52/* Advance along TREE_CHAIN n times. */
53
54tree
55gfc_advance_chain (tree t, int n)
56{
57 for (; n > 0; n--)
58 {
6e45f57b 59 gcc_assert (t != NULL_TREE);
910ad8de 60 t = DECL_CHAIN (t);
6de9cd9a
DN
61 }
62 return t;
63}
64
65
66/* Wrap a node in a TREE_LIST node and add it to the end of a list. */
67
68tree
69gfc_chainon_list (tree list, tree add)
70{
71 tree l;
72
73 l = tree_cons (NULL_TREE, add, NULL_TREE);
74
75 return chainon (list, l);
76}
77
78
79/* Strip off a legitimate source ending from the input
80 string NAME of length LEN. */
81
82static inline void
83remove_suffix (char *name, int len)
84{
85 int i;
86
87 for (i = 2; i < 8 && len > i; i++)
88 {
89 if (name[len - i] == '.')
90 {
91 name[len - i] = '\0';
92 break;
93 }
94 }
95}
96
97
98/* Creates a variable declaration with a given TYPE. */
99
100tree
101gfc_create_var_np (tree type, const char *prefix)
102{
049e4fb0
FXC
103 tree t;
104
105 t = create_tmp_var_raw (type, prefix);
106
107 /* No warnings for anonymous variables. */
108 if (prefix == NULL)
109 TREE_NO_WARNING (t) = 1;
110
111 return t;
6de9cd9a
DN
112}
113
114
115/* Like above, but also adds it to the current scope. */
116
117tree
118gfc_create_var (tree type, const char *prefix)
119{
120 tree tmp;
121
122 tmp = gfc_create_var_np (type, prefix);
123
124 pushdecl (tmp);
125
126 return tmp;
127}
128
129
df2fba9e 130/* If the expression is not constant, evaluate it now. We assign the
6de9cd9a
DN
131 result of the expression to an artificially created variable VAR, and
132 return a pointer to the VAR_DECL node for this variable. */
133
134tree
55bd9c35 135gfc_evaluate_now_loc (location_t loc, tree expr, stmtblock_t * pblock)
6de9cd9a
DN
136{
137 tree var;
138
6615c446 139 if (CONSTANT_CLASS_P (expr))
6de9cd9a
DN
140 return expr;
141
142 var = gfc_create_var (TREE_TYPE (expr), NULL);
55bd9c35 143 gfc_add_modify_loc (loc, pblock, var, expr);
6de9cd9a
DN
144
145 return var;
146}
147
148
55bd9c35
TB
149tree
150gfc_evaluate_now (tree expr, stmtblock_t * pblock)
151{
152 return gfc_evaluate_now_loc (input_location, expr, pblock);
153}
154
155
726a989a
RB
156/* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
157 A MODIFY_EXPR is an assignment:
07beea0d 158 LHS <- RHS. */
6de9cd9a
DN
159
160void
55bd9c35 161gfc_add_modify_loc (location_t loc, stmtblock_t * pblock, tree lhs, tree rhs)
6de9cd9a
DN
162{
163 tree tmp;
164
7ab92584 165#ifdef ENABLE_CHECKING
10174ddf
MM
166 tree t1, t2;
167 t1 = TREE_TYPE (rhs);
168 t2 = TREE_TYPE (lhs);
7ab92584
SB
169 /* Make sure that the types of the rhs and the lhs are the same
170 for scalar assignments. We should probably have something
171 similar for aggregates, but right now removing that check just
172 breaks everything. */
10174ddf 173 gcc_assert (t1 == t2
6e45f57b 174 || AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
7ab92584
SB
175#endif
176
55bd9c35 177 tmp = fold_build2_loc (loc, MODIFY_EXPR, void_type_node, lhs,
65a9ca82 178 rhs);
6de9cd9a
DN
179 gfc_add_expr_to_block (pblock, tmp);
180}
181
182
55bd9c35
TB
183void
184gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
185{
186 gfc_add_modify_loc (input_location, pblock, lhs, rhs);
187}
188
189
6de9cd9a 190/* Create a new scope/binding level and initialize a block. Care must be
1f2959f0 191 taken when translating expressions as any temporaries will be placed in
6de9cd9a
DN
192 the innermost scope. */
193
194void
195gfc_start_block (stmtblock_t * block)
196{
197 /* Start a new binding level. */
198 pushlevel (0);
199 block->has_scope = 1;
200
201 /* The block is empty. */
202 block->head = NULL_TREE;
203}
204
205
206/* Initialize a block without creating a new scope. */
207
208void
209gfc_init_block (stmtblock_t * block)
210{
211 block->head = NULL_TREE;
212 block->has_scope = 0;
213}
214
215
216/* Sometimes we create a scope but it turns out that we don't actually
217 need it. This function merges the scope of BLOCK with its parent.
218 Only variable decls will be merged, you still need to add the code. */
219
220void
221gfc_merge_block_scope (stmtblock_t * block)
222{
223 tree decl;
224 tree next;
225
6e45f57b 226 gcc_assert (block->has_scope);
6de9cd9a
DN
227 block->has_scope = 0;
228
229 /* Remember the decls in this scope. */
230 decl = getdecls ();
231 poplevel (0, 0, 0);
232
233 /* Add them to the parent scope. */
234 while (decl != NULL_TREE)
235 {
910ad8de
NF
236 next = DECL_CHAIN (decl);
237 DECL_CHAIN (decl) = NULL_TREE;
6de9cd9a
DN
238
239 pushdecl (decl);
240 decl = next;
241 }
242}
243
244
245/* Finish a scope containing a block of statements. */
246
247tree
248gfc_finish_block (stmtblock_t * stmtblock)
249{
250 tree decl;
251 tree expr;
252 tree block;
253
7c87eac6
PB
254 expr = stmtblock->head;
255 if (!expr)
c2255bc4 256 expr = build_empty_stmt (input_location);
7c87eac6 257
6de9cd9a
DN
258 stmtblock->head = NULL_TREE;
259
260 if (stmtblock->has_scope)
261 {
262 decl = getdecls ();
263
264 if (decl)
265 {
266 block = poplevel (1, 0, 0);
923ab88c 267 expr = build3_v (BIND_EXPR, decl, expr, block);
6de9cd9a
DN
268 }
269 else
270 poplevel (0, 0, 0);
271 }
272
273 return expr;
274}
275
276
277/* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
278 natural type is used. */
279
280tree
281gfc_build_addr_expr (tree type, tree t)
282{
283 tree base_type = TREE_TYPE (t);
284 tree natural_type;
285
286 if (type && POINTER_TYPE_P (type)
287 && TREE_CODE (base_type) == ARRAY_TYPE
288 && TYPE_MAIN_VARIANT (TREE_TYPE (type))
289 == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
543535a3
AP
290 {
291 tree min_val = size_zero_node;
292 tree type_domain = TYPE_DOMAIN (base_type);
293 if (type_domain && TYPE_MIN_VALUE (type_domain))
294 min_val = TYPE_MIN_VALUE (type_domain);
5d44e5c8
TB
295 t = fold (build4_loc (input_location, ARRAY_REF, TREE_TYPE (type),
296 t, min_val, NULL_TREE, NULL_TREE));
543535a3
AP
297 natural_type = type;
298 }
6de9cd9a
DN
299 else
300 natural_type = build_pointer_type (base_type);
301
302 if (TREE_CODE (t) == INDIRECT_REF)
303 {
304 if (!type)
305 type = natural_type;
306 t = TREE_OPERAND (t, 0);
307 natural_type = TREE_TYPE (t);
308 }
309 else
310 {
628c189e
RG
311 tree base = get_base_address (t);
312 if (base && DECL_P (base))
313 TREE_ADDRESSABLE (base) = 1;
65a9ca82 314 t = fold_build1_loc (input_location, ADDR_EXPR, natural_type, t);
6de9cd9a
DN
315 }
316
317 if (type && natural_type != type)
318 t = convert (type, t);
319
320 return t;
321}
322
323
6de9cd9a
DN
324/* Build an ARRAY_REF with its natural type. */
325
326tree
1d6b7f39 327gfc_build_array_ref (tree base, tree offset, tree decl)
6de9cd9a
DN
328{
329 tree type = TREE_TYPE (base);
1d6b7f39
PT
330 tree tmp;
331
6e45f57b 332 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
6de9cd9a
DN
333 type = TREE_TYPE (type);
334
335 if (DECL_P (base))
336 TREE_ADDRESSABLE (base) = 1;
337
31120e8f
RS
338 /* Strip NON_LVALUE_EXPR nodes. */
339 STRIP_TYPE_NOPS (offset);
340
1d6b7f39
PT
341 /* If the array reference is to a pointer, whose target contains a
342 subreference, use the span that is stored with the backend decl
343 and reference the element with pointer arithmetic. */
344 if (decl && (TREE_CODE (decl) == FIELD_DECL
345 || TREE_CODE (decl) == VAR_DECL
346 || TREE_CODE (decl) == PARM_DECL)
347 && GFC_DECL_SUBREF_ARRAY_P (decl)
348 && !integer_zerop (GFC_DECL_SPAN(decl)))
349 {
65a9ca82
TB
350 offset = fold_build2_loc (input_location, MULT_EXPR,
351 gfc_array_index_type,
352 offset, GFC_DECL_SPAN(decl));
1d6b7f39 353 tmp = gfc_build_addr_expr (pvoid_type_node, base);
65a9ca82
TB
354 tmp = fold_build2_loc (input_location, POINTER_PLUS_EXPR,
355 pvoid_type_node, tmp,
356 fold_convert (sizetype, offset));
1d6b7f39
PT
357 tmp = fold_convert (build_pointer_type (type), tmp);
358 if (!TYPE_STRING_FLAG (type))
db3927fb 359 tmp = build_fold_indirect_ref_loc (input_location, tmp);
1d6b7f39
PT
360 return tmp;
361 }
362 else
363 /* Otherwise use a straightforward array reference. */
5d44e5c8
TB
364 return build4_loc (input_location, ARRAY_REF, type, base, offset,
365 NULL_TREE, NULL_TREE);
6de9cd9a
DN
366}
367
368
f25a62a5
DK
369/* Generate a call to print a runtime error possibly including multiple
370 arguments and a locus. */
6de9cd9a 371
55bd9c35
TB
372static tree
373trans_runtime_error_vararg (bool error, locus* where, const char* msgid,
374 va_list ap)
f25a62a5 375{
6de9cd9a 376 stmtblock_t block;
6de9cd9a 377 tree tmp;
f96d606f 378 tree arg, arg2;
c8fe94c7
FXC
379 tree *argarray;
380 tree fntype;
f96d606f 381 char *message;
c8fe94c7
FXC
382 const char *p;
383 int line, nargs, i;
55bd9c35 384 location_t loc;
6de9cd9a 385
c8fe94c7
FXC
386 /* Compute the number of extra arguments from the format string. */
387 for (p = msgid, nargs = 0; *p; p++)
388 if (*p == '%')
389 {
390 p++;
391 if (*p != '%')
392 nargs++;
393 }
394
6de9cd9a
DN
395 /* The code to generate the error. */
396 gfc_start_block (&block);
397
dd18a33b
FXC
398 if (where)
399 {
dd18a33b 400 line = LOCATION_LINE (where->lb->location);
f96d606f
JD
401 asprintf (&message, "At line %d of file %s", line,
402 where->lb->file->filename);
dd18a33b
FXC
403 }
404 else
f96d606f 405 asprintf (&message, "In file '%s', around line %d",
dd18a33b 406 gfc_source_file, input_line + 1);
6de9cd9a 407
ee37d2f5
FXC
408 arg = gfc_build_addr_expr (pchar_type_node,
409 gfc_build_localized_cstring_const (message));
dd18a33b 410 gfc_free(message);
f96d606f
JD
411
412 asprintf (&message, "%s", _(msgid));
ee37d2f5
FXC
413 arg2 = gfc_build_addr_expr (pchar_type_node,
414 gfc_build_localized_cstring_const (message));
f96d606f 415 gfc_free(message);
6de9cd9a 416
c8fe94c7 417 /* Build the argument array. */
1145e690 418 argarray = XALLOCAVEC (tree, nargs + 2);
c8fe94c7
FXC
419 argarray[0] = arg;
420 argarray[1] = arg2;
c8fe94c7 421 for (i = 0; i < nargs; i++)
f25a62a5 422 argarray[2 + i] = va_arg (ap, tree);
c8fe94c7 423
0d52899f 424 /* Build the function call to runtime_(warning,error)_at; because of the
db3927fb
AH
425 variable number of arguments, we can't use build_call_expr_loc dinput_location,
426 irectly. */
0d52899f
TB
427 if (error)
428 fntype = TREE_TYPE (gfor_fndecl_runtime_error_at);
429 else
430 fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at);
431
55bd9c35
TB
432 loc = where ? where->lb->location : input_location;
433 tmp = fold_builtin_call_array (loc, TREE_TYPE (fntype),
434 fold_build1_loc (loc, ADDR_EXPR,
65a9ca82
TB
435 build_pointer_type (fntype),
436 error
437 ? gfor_fndecl_runtime_error_at
438 : gfor_fndecl_runtime_warning_at),
c8fe94c7 439 nargs + 2, argarray);
6de9cd9a
DN
440 gfc_add_expr_to_block (&block, tmp);
441
f25a62a5
DK
442 return gfc_finish_block (&block);
443}
444
445
55bd9c35
TB
446tree
447gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
448{
449 va_list ap;
450 tree result;
451
452 va_start (ap, msgid);
453 result = trans_runtime_error_vararg (error, where, msgid, ap);
454 va_end (ap);
455 return result;
456}
457
458
f25a62a5
DK
459/* Generate a runtime error if COND is true. */
460
461void
462gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
463 locus * where, const char * msgid, ...)
464{
465 va_list ap;
466 stmtblock_t block;
467 tree body;
468 tree tmp;
469 tree tmpvar = NULL;
470
471 if (integer_zerop (cond))
472 return;
473
474 if (once)
475 {
476 tmpvar = gfc_create_var (boolean_type_node, "print_warning");
477 TREE_STATIC (tmpvar) = 1;
478 DECL_INITIAL (tmpvar) = boolean_true_node;
479 gfc_add_expr_to_block (pblock, tmpvar);
480 }
481
482 gfc_start_block (&block);
483
484 /* The code to generate the error. */
485 va_start (ap, msgid);
486 gfc_add_expr_to_block (&block,
55bd9c35
TB
487 trans_runtime_error_vararg (error, where,
488 msgid, ap));
f25a62a5 489
0d52899f 490 if (once)
726a989a 491 gfc_add_modify (&block, tmpvar, boolean_false_node);
0d52899f 492
6de9cd9a
DN
493 body = gfc_finish_block (&block);
494
495 if (integer_onep (cond))
496 {
497 gfc_add_expr_to_block (pblock, body);
498 }
499 else
500 {
472ca416 501 /* Tell the compiler that this isn't likely. */
0d52899f 502 if (once)
55bd9c35 503 cond = fold_build2_loc (where->lb->location, TRUTH_AND_EXPR,
65a9ca82 504 long_integer_type_node, tmpvar, cond);
0d52899f
TB
505 else
506 cond = fold_convert (long_integer_type_node, cond);
507
5039610b 508 tmp = build_int_cst (long_integer_type_node, 0);
55bd9c35 509 cond = build_call_expr_loc (where->lb->location,
db3927fb 510 built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
240c7c02 511 cond = fold_convert (boolean_type_node, cond);
6de9cd9a 512
55bd9c35
TB
513 tmp = fold_build3_loc (where->lb->location, COND_EXPR, void_type_node,
514 cond, body,
515 build_empty_stmt (where->lb->location));
6de9cd9a
DN
516 gfc_add_expr_to_block (pblock, tmp);
517 }
518}
519
520
1529b8d9 521/* Call malloc to allocate size bytes of memory, with special conditions:
22bdbb0f 522 + if size <= 0, return a malloced area of size 1,
1529b8d9
FXC
523 + if malloc returns NULL, issue a runtime error. */
524tree
525gfc_call_malloc (stmtblock_t * block, tree type, tree size)
526{
22bdbb0f 527 tree tmp, msg, malloc_result, null_result, res;
1529b8d9
FXC
528 stmtblock_t block2;
529
530 size = gfc_evaluate_now (size, block);
531
532 if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
533 size = fold_convert (size_type_node, size);
534
535 /* Create a variable to hold the result. */
10174ddf 536 res = gfc_create_var (prvoid_type_node, NULL);
1529b8d9 537
22bdbb0f 538 /* Call malloc. */
1529b8d9 539 gfc_start_block (&block2);
8f0aaee5 540
65a9ca82
TB
541 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node, size,
542 build_int_cst (size_type_node, 1));
8f0aaee5 543
726a989a 544 gfc_add_modify (&block2, res,
10174ddf
MM
545 fold_convert (prvoid_type_node,
546 build_call_expr_loc (input_location,
547 built_in_decls[BUILT_IN_MALLOC], 1, size)));
22bdbb0f
TB
548
549 /* Optionally check whether malloc was successful. */
550 if (gfc_option.rtcheck & GFC_RTCHECK_MEM)
551 {
65a9ca82
TB
552 null_result = fold_build2_loc (input_location, EQ_EXPR,
553 boolean_type_node, res,
554 build_int_cst (pvoid_type_node, 0));
22bdbb0f
TB
555 msg = gfc_build_addr_expr (pchar_type_node,
556 gfc_build_localized_cstring_const ("Memory allocation failed"));
65a9ca82
TB
557 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
558 null_result,
22bdbb0f
TB
559 build_call_expr_loc (input_location,
560 gfor_fndecl_os_error, 1, msg),
561 build_empty_stmt (input_location));
562 gfc_add_expr_to_block (&block2, tmp);
563 }
564
1529b8d9
FXC
565 malloc_result = gfc_finish_block (&block2);
566
8f0aaee5 567 gfc_add_expr_to_block (block, malloc_result);
1529b8d9
FXC
568
569 if (type != NULL)
570 res = fold_convert (type, res);
571 return res;
572}
573
22bdbb0f 574
4376b7cf
FXC
575/* Allocate memory, using an optional status argument.
576
577 This function follows the following pseudo-code:
578
579 void *
580 allocate (size_t size, integer_type* stat)
581 {
582 void *newmem;
583
584 if (stat)
f25a62a5 585 *stat = 0;
4376b7cf
FXC
586
587 // The only time this can happen is the size wraps around.
588 if (size < 0)
589 {
f25a62a5
DK
590 if (stat)
591 {
592 *stat = LIBERROR_ALLOCATION;
593 newmem = NULL;
594 }
595 else
596 runtime_error ("Attempt to allocate negative amount of memory. "
597 "Possible integer overflow");
4376b7cf
FXC
598 }
599 else
600 {
f25a62a5
DK
601 newmem = malloc (MAX (size, 1));
602 if (newmem == NULL)
603 {
604 if (stat)
605 *stat = LIBERROR_ALLOCATION;
606 else
607 runtime_error ("Out of memory");
608 }
4376b7cf
FXC
609 }
610
611 return newmem;
612 } */
613tree
614gfc_allocate_with_status (stmtblock_t * block, tree size, tree status)
615{
616 stmtblock_t alloc_block;
617 tree res, tmp, error, msg, cond;
618 tree status_type = status ? TREE_TYPE (TREE_TYPE (status)) : NULL_TREE;
619
620 /* Evaluate size only once, and make sure it has the right type. */
621 size = gfc_evaluate_now (size, block);
622 if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
623 size = fold_convert (size_type_node, size);
624
625 /* Create a variable to hold the result. */
10174ddf 626 res = gfc_create_var (prvoid_type_node, NULL);
4376b7cf
FXC
627
628 /* Set the optional status variable to zero. */
629 if (status != NULL_TREE && !integer_zerop (status))
630 {
65a9ca82
TB
631 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
632 fold_build1_loc (input_location, INDIRECT_REF,
633 status_type, status),
634 build_int_cst (status_type, 0));
635 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
636 fold_build2_loc (input_location, NE_EXPR,
637 boolean_type_node, status,
638 build_int_cst (TREE_TYPE (status), 0)),
639 tmp, build_empty_stmt (input_location));
4376b7cf
FXC
640 gfc_add_expr_to_block (block, tmp);
641 }
642
643 /* Generate the block of code handling (size < 0). */
ee37d2f5 644 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
4376b7cf
FXC
645 ("Attempt to allocate negative amount of memory. "
646 "Possible integer overflow"));
db3927fb
AH
647 error = build_call_expr_loc (input_location,
648 gfor_fndecl_runtime_error, 1, msg);
4376b7cf
FXC
649
650 if (status != NULL_TREE && !integer_zerop (status))
651 {
652 /* Set the status variable if it's present. */
653 stmtblock_t set_status_block;
654
655 gfc_start_block (&set_status_block);
726a989a 656 gfc_add_modify (&set_status_block,
65a9ca82
TB
657 fold_build1_loc (input_location, INDIRECT_REF,
658 status_type, status),
d74b97cc 659 build_int_cst (status_type, LIBERROR_ALLOCATION));
726a989a 660 gfc_add_modify (&set_status_block, res,
10174ddf 661 build_int_cst (prvoid_type_node, 0));
4376b7cf 662
65a9ca82
TB
663 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
664 status, build_int_cst (TREE_TYPE (status), 0));
665 error = fold_build3_loc (input_location, COND_EXPR, void_type_node, tmp,
666 error, gfc_finish_block (&set_status_block));
4376b7cf
FXC
667 }
668
669 /* The allocation itself. */
670 gfc_start_block (&alloc_block);
726a989a 671 gfc_add_modify (&alloc_block, res,
10174ddf
MM
672 fold_convert (prvoid_type_node,
673 build_call_expr_loc (input_location,
db3927fb 674 built_in_decls[BUILT_IN_MALLOC], 1,
65a9ca82
TB
675 fold_build2_loc (input_location,
676 MAX_EXPR, size_type_node, size,
677 build_int_cst (size_type_node,
678 1)))));
4376b7cf 679
ee37d2f5
FXC
680 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
681 ("Out of memory"));
db3927fb
AH
682 tmp = build_call_expr_loc (input_location,
683 gfor_fndecl_os_error, 1, msg);
4376b7cf
FXC
684
685 if (status != NULL_TREE && !integer_zerop (status))
686 {
687 /* Set the status variable if it's present. */
688 tree tmp2;
689
65a9ca82
TB
690 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
691 status, build_int_cst (TREE_TYPE (status), 0));
692 tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
693 fold_build1_loc (input_location, INDIRECT_REF,
694 status_type, status),
695 build_int_cst (status_type, LIBERROR_ALLOCATION));
696 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
697 tmp, tmp2);
4376b7cf
FXC
698 }
699
65a9ca82
TB
700 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
701 fold_build2_loc (input_location, EQ_EXPR,
702 boolean_type_node, res,
703 build_int_cst (prvoid_type_node, 0)),
704 tmp, build_empty_stmt (input_location));
4376b7cf
FXC
705 gfc_add_expr_to_block (&alloc_block, tmp);
706
65a9ca82
TB
707 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, size,
708 build_int_cst (TREE_TYPE (size), 0));
709 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, error,
710 gfc_finish_block (&alloc_block));
4376b7cf
FXC
711 gfc_add_expr_to_block (block, tmp);
712
713 return res;
714}
715
716
717/* Generate code for an ALLOCATE statement when the argument is an
718 allocatable array. If the array is currently allocated, it is an
719 error to allocate it again.
720
721 This function follows the following pseudo-code:
722
723 void *
724 allocate_array (void *mem, size_t size, integer_type *stat)
725 {
726 if (mem == NULL)
727 return allocate (size, stat);
728 else
729 {
730 if (stat)
731 {
732 free (mem);
733 mem = allocate (size, stat);
d74b97cc 734 *stat = LIBERROR_ALLOCATION;
4376b7cf
FXC
735 return mem;
736 }
737 else
f8dde8af 738 runtime_error ("Attempting to allocate already allocated variable");
5b130807 739 }
f25a62a5
DK
740 }
741
742 expr must be set to the original expression being allocated for its locus
743 and variable name in case a runtime error has to be printed. */
4376b7cf
FXC
744tree
745gfc_allocate_array_with_status (stmtblock_t * block, tree mem, tree size,
f25a62a5 746 tree status, gfc_expr* expr)
4376b7cf
FXC
747{
748 stmtblock_t alloc_block;
f25a62a5 749 tree res, tmp, null_mem, alloc, error;
4376b7cf
FXC
750 tree type = TREE_TYPE (mem);
751
752 if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
753 size = fold_convert (size_type_node, size);
754
755 /* Create a variable to hold the result. */
10174ddf 756 res = gfc_create_var (type, NULL);
65a9ca82
TB
757 null_mem = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, mem,
758 build_int_cst (type, 0));
4376b7cf
FXC
759
760 /* If mem is NULL, we call gfc_allocate_with_status. */
761 gfc_start_block (&alloc_block);
762 tmp = gfc_allocate_with_status (&alloc_block, size, status);
726a989a 763 gfc_add_modify (&alloc_block, res, fold_convert (type, tmp));
4376b7cf
FXC
764 alloc = gfc_finish_block (&alloc_block);
765
766 /* Otherwise, we issue a runtime error or set the status variable. */
f25a62a5
DK
767 if (expr)
768 {
769 tree varname;
770
771 gcc_assert (expr->expr_type == EXPR_VARIABLE && expr->symtree);
772 varname = gfc_build_cstring_const (expr->symtree->name);
773 varname = gfc_build_addr_expr (pchar_type_node, varname);
774
775 error = gfc_trans_runtime_error (true, &expr->where,
776 "Attempting to allocate already"
f8dde8af 777 " allocated variable '%s'",
f25a62a5
DK
778 varname);
779 }
780 else
781 error = gfc_trans_runtime_error (true, NULL,
782 "Attempting to allocate already allocated"
d8a07487 783 " variable");
4376b7cf
FXC
784
785 if (status != NULL_TREE && !integer_zerop (status))
786 {
787 tree status_type = TREE_TYPE (TREE_TYPE (status));
788 stmtblock_t set_status_block;
789
790 gfc_start_block (&set_status_block);
db3927fb
AH
791 tmp = build_call_expr_loc (input_location,
792 built_in_decls[BUILT_IN_FREE], 1,
4376b7cf
FXC
793 fold_convert (pvoid_type_node, mem));
794 gfc_add_expr_to_block (&set_status_block, tmp);
795
796 tmp = gfc_allocate_with_status (&set_status_block, size, status);
726a989a 797 gfc_add_modify (&set_status_block, res, fold_convert (type, tmp));
4376b7cf 798
726a989a 799 gfc_add_modify (&set_status_block,
65a9ca82
TB
800 fold_build1_loc (input_location, INDIRECT_REF,
801 status_type, status),
d74b97cc 802 build_int_cst (status_type, LIBERROR_ALLOCATION));
4376b7cf 803
65a9ca82
TB
804 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
805 status, build_int_cst (status_type, 0));
806 error = fold_build3_loc (input_location, COND_EXPR, void_type_node, tmp,
807 error, gfc_finish_block (&set_status_block));
4376b7cf
FXC
808 }
809
65a9ca82
TB
810 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, null_mem,
811 alloc, error);
4376b7cf
FXC
812 gfc_add_expr_to_block (block, tmp);
813
814 return res;
815}
816
1529b8d9
FXC
817
818/* Free a given variable, if it's not NULL. */
819tree
820gfc_call_free (tree var)
821{
822 stmtblock_t block;
823 tree tmp, cond, call;
824
825 if (TREE_TYPE (var) != TREE_TYPE (pvoid_type_node))
826 var = fold_convert (pvoid_type_node, var);
827
828 gfc_start_block (&block);
829 var = gfc_evaluate_now (var, &block);
65a9ca82
TB
830 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, var,
831 build_int_cst (pvoid_type_node, 0));
db3927fb 832 call = build_call_expr_loc (input_location,
65a9ca82
TB
833 built_in_decls[BUILT_IN_FREE], 1, var);
834 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, call,
835 build_empty_stmt (input_location));
1529b8d9
FXC
836 gfc_add_expr_to_block (&block, tmp);
837
838 return gfc_finish_block (&block);
839}
840
841
4376b7cf
FXC
842
843/* User-deallocate; we emit the code directly from the front-end, and the
844 logic is the same as the previous library function:
845
846 void
847 deallocate (void *pointer, GFC_INTEGER_4 * stat)
848 {
849 if (!pointer)
850 {
851 if (stat)
852 *stat = 1;
853 else
854 runtime_error ("Attempt to DEALLOCATE unallocated memory.");
855 }
856 else
857 {
858 free (pointer);
859 if (stat)
860 *stat = 0;
861 }
862 }
863
864 In this front-end version, status doesn't have to be GFC_INTEGER_4.
865 Moreover, if CAN_FAIL is true, then we will not emit a runtime error,
866 even when no status variable is passed to us (this is used for
867 unconditional deallocation generated by the front-end at end of
f25a62a5
DK
868 each procedure).
869
870 If a runtime-message is possible, `expr' must point to the original
871 expression being deallocated for its locus and variable name. */
4376b7cf 872tree
f25a62a5
DK
873gfc_deallocate_with_status (tree pointer, tree status, bool can_fail,
874 gfc_expr* expr)
4376b7cf
FXC
875{
876 stmtblock_t null, non_null;
f25a62a5 877 tree cond, tmp, error;
4376b7cf 878
65a9ca82
TB
879 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer,
880 build_int_cst (TREE_TYPE (pointer), 0));
4376b7cf
FXC
881
882 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
883 we emit a runtime error. */
884 gfc_start_block (&null);
885 if (!can_fail)
886 {
f25a62a5
DK
887 tree varname;
888
889 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
890
891 varname = gfc_build_cstring_const (expr->symtree->name);
892 varname = gfc_build_addr_expr (pchar_type_node, varname);
893
894 error = gfc_trans_runtime_error (true, &expr->where,
895 "Attempt to DEALLOCATE unallocated '%s'",
896 varname);
4376b7cf
FXC
897 }
898 else
c2255bc4 899 error = build_empty_stmt (input_location);
4376b7cf
FXC
900
901 if (status != NULL_TREE && !integer_zerop (status))
902 {
903 tree status_type = TREE_TYPE (TREE_TYPE (status));
904 tree cond2;
905
65a9ca82
TB
906 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
907 status, build_int_cst (TREE_TYPE (status), 0));
908 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
909 fold_build1_loc (input_location, INDIRECT_REF,
910 status_type, status),
911 build_int_cst (status_type, 1));
912 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
913 cond2, tmp, error);
4376b7cf
FXC
914 }
915
916 gfc_add_expr_to_block (&null, error);
917
918 /* When POINTER is not NULL, we free it. */
919 gfc_start_block (&non_null);
2c807128
JW
920 tmp = build_call_expr_loc (input_location,
921 built_in_decls[BUILT_IN_FREE], 1,
922 fold_convert (pvoid_type_node, pointer));
923 gfc_add_expr_to_block (&non_null, tmp);
924
925 if (status != NULL_TREE && !integer_zerop (status))
926 {
927 /* We set STATUS to zero if it is present. */
928 tree status_type = TREE_TYPE (TREE_TYPE (status));
929 tree cond2;
930
931 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
932 status, build_int_cst (TREE_TYPE (status), 0));
933 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
934 fold_build1_loc (input_location, INDIRECT_REF,
935 status_type, status),
936 build_int_cst (status_type, 0));
937 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
938 tmp, build_empty_stmt (input_location));
939 gfc_add_expr_to_block (&non_null, tmp);
940 }
941
942 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
943 gfc_finish_block (&null),
944 gfc_finish_block (&non_null));
945}
946
947
948/* Generate code for deallocation of allocatable scalars (variables or
949 components). Before the object itself is freed, any allocatable
950 subcomponents are being deallocated. */
951
952tree
953gfc_deallocate_scalar_with_status (tree pointer, tree status, bool can_fail,
954 gfc_expr* expr, gfc_typespec ts)
955{
956 stmtblock_t null, non_null;
957 tree cond, tmp, error;
958
959 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pointer,
960 build_int_cst (TREE_TYPE (pointer), 0));
961
962 /* When POINTER is NULL, we set STATUS to 1 if it's present, otherwise
963 we emit a runtime error. */
964 gfc_start_block (&null);
965 if (!can_fail)
966 {
967 tree varname;
968
969 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree);
970
971 varname = gfc_build_cstring_const (expr->symtree->name);
972 varname = gfc_build_addr_expr (pchar_type_node, varname);
973
974 error = gfc_trans_runtime_error (true, &expr->where,
975 "Attempt to DEALLOCATE unallocated '%s'",
976 varname);
977 }
978 else
979 error = build_empty_stmt (input_location);
980
981 if (status != NULL_TREE && !integer_zerop (status))
982 {
983 tree status_type = TREE_TYPE (TREE_TYPE (status));
984 tree cond2;
985
986 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
987 status, build_int_cst (TREE_TYPE (status), 0));
988 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
989 fold_build1_loc (input_location, INDIRECT_REF,
990 status_type, status),
991 build_int_cst (status_type, 1));
992 error = fold_build3_loc (input_location, COND_EXPR, void_type_node,
993 cond2, tmp, error);
994 }
995
996 gfc_add_expr_to_block (&null, error);
997
998 /* When POINTER is not NULL, we free it. */
999 gfc_start_block (&non_null);
1000
1001 /* Free allocatable components. */
1002 if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
1003 {
1004 tmp = build_fold_indirect_ref_loc (input_location, pointer);
1005 tmp = gfc_deallocate_alloc_comp (ts.u.derived, tmp, 0);
1006 gfc_add_expr_to_block (&non_null, tmp);
1007 }
1008 else if (ts.type == BT_CLASS
1009 && ts.u.derived->components->ts.u.derived->attr.alloc_comp)
1010 {
1011 tmp = build_fold_indirect_ref_loc (input_location, pointer);
1012 tmp = gfc_deallocate_alloc_comp (ts.u.derived->components->ts.u.derived,
1013 tmp, 0);
1014 gfc_add_expr_to_block (&non_null, tmp);
1015 }
1016
db3927fb
AH
1017 tmp = build_call_expr_loc (input_location,
1018 built_in_decls[BUILT_IN_FREE], 1,
4376b7cf
FXC
1019 fold_convert (pvoid_type_node, pointer));
1020 gfc_add_expr_to_block (&non_null, tmp);
1021
1022 if (status != NULL_TREE && !integer_zerop (status))
1023 {
1024 /* We set STATUS to zero if it is present. */
1025 tree status_type = TREE_TYPE (TREE_TYPE (status));
1026 tree cond2;
1027
65a9ca82
TB
1028 cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1029 status, build_int_cst (TREE_TYPE (status), 0));
1030 tmp = fold_build2_loc (input_location, MODIFY_EXPR, status_type,
1031 fold_build1_loc (input_location, INDIRECT_REF,
1032 status_type, status),
1033 build_int_cst (status_type, 0));
1034 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond2,
1035 tmp, build_empty_stmt (input_location));
4376b7cf
FXC
1036 gfc_add_expr_to_block (&non_null, tmp);
1037 }
1038
65a9ca82
TB
1039 return fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
1040 gfc_finish_block (&null),
1041 gfc_finish_block (&non_null));
4376b7cf
FXC
1042}
1043
1044
1045/* Reallocate MEM so it has SIZE bytes of data. This behaves like the
1046 following pseudo-code:
1047
1048void *
1049internal_realloc (void *mem, size_t size)
1050{
1051 if (size < 0)
1052 runtime_error ("Attempt to allocate a negative amount of memory.");
28762eb0
FXC
1053 res = realloc (mem, size);
1054 if (!res && size != 0)
4376b7cf
FXC
1055 _gfortran_os_error ("Out of memory");
1056
1057 if (size == 0)
1058 return NULL;
1059
28762eb0 1060 return res;
4376b7cf
FXC
1061} */
1062tree
1063gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
1064{
28762eb0 1065 tree msg, res, negative, nonzero, zero, null_result, tmp;
4376b7cf
FXC
1066 tree type = TREE_TYPE (mem);
1067
1068 size = gfc_evaluate_now (size, block);
1069
1070 if (TREE_TYPE (size) != TREE_TYPE (size_type_node))
1071 size = fold_convert (size_type_node, size);
1072
1073 /* Create a variable to hold the result. */
1074 res = gfc_create_var (type, NULL);
1075
1076 /* size < 0 ? */
65a9ca82
TB
1077 negative = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, size,
1078 build_int_cst (size_type_node, 0));
ee37d2f5 1079 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
4376b7cf 1080 ("Attempt to allocate a negative amount of memory."));
65a9ca82
TB
1081 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, negative,
1082 build_call_expr_loc (input_location,
1083 gfor_fndecl_runtime_error, 1, msg),
1084 build_empty_stmt (input_location));
4376b7cf
FXC
1085 gfc_add_expr_to_block (block, tmp);
1086
1087 /* Call realloc and check the result. */
db3927fb
AH
1088 tmp = build_call_expr_loc (input_location,
1089 built_in_decls[BUILT_IN_REALLOC], 2,
4376b7cf 1090 fold_convert (pvoid_type_node, mem), size);
726a989a 1091 gfc_add_modify (block, res, fold_convert (type, tmp));
65a9ca82
TB
1092 null_result = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1093 res, build_int_cst (pvoid_type_node, 0));
1094 nonzero = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, size,
1095 build_int_cst (size_type_node, 0));
1096 null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node,
1097 null_result, nonzero);
ee37d2f5
FXC
1098 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
1099 ("Out of memory"));
65a9ca82
TB
1100 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1101 null_result,
1102 build_call_expr_loc (input_location,
1103 gfor_fndecl_os_error, 1, msg),
1104 build_empty_stmt (input_location));
4376b7cf
FXC
1105 gfc_add_expr_to_block (block, tmp);
1106
1107 /* if (size == 0) then the result is NULL. */
65a9ca82
TB
1108 tmp = fold_build2_loc (input_location, MODIFY_EXPR, type, res,
1109 build_int_cst (type, 0));
1110 zero = fold_build1_loc (input_location, TRUTH_NOT_EXPR, boolean_type_node,
1111 nonzero);
1112 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, zero, tmp,
1113 build_empty_stmt (input_location));
4376b7cf
FXC
1114 gfc_add_expr_to_block (block, tmp);
1115
1116 return res;
1117}
1118
6de9cd9a 1119
0019d498 1120/* Add an expression to another one, either at the front or the back. */
6de9cd9a 1121
0019d498
DK
1122static void
1123add_expr_to_chain (tree* chain, tree expr, bool front)
1124{
6de9cd9a
DN
1125 if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
1126 return;
1127
0019d498 1128 if (*chain)
7c87eac6 1129 {
0019d498 1130 if (TREE_CODE (*chain) != STATEMENT_LIST)
7c87eac6
PB
1131 {
1132 tree tmp;
1133
0019d498
DK
1134 tmp = *chain;
1135 *chain = NULL_TREE;
1136 append_to_statement_list (tmp, chain);
7c87eac6 1137 }
0019d498
DK
1138
1139 if (front)
1140 {
1141 tree_stmt_iterator i;
1142
1143 i = tsi_start (*chain);
1144 tsi_link_before (&i, expr, TSI_CONTINUE_LINKING);
1145 }
1146 else
1147 append_to_statement_list (expr, chain);
7c87eac6 1148 }
6de9cd9a 1149 else
0019d498
DK
1150 *chain = expr;
1151}
1152
1153/* Add a statement to a block. */
1154
1155void
1156gfc_add_expr_to_block (stmtblock_t * block, tree expr)
1157{
1158 gcc_assert (block);
1159 add_expr_to_chain (&block->head, expr, false);
6de9cd9a
DN
1160}
1161
1162
1163/* Add a block the end of a block. */
1164
1165void
1166gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
1167{
6e45f57b
PB
1168 gcc_assert (append);
1169 gcc_assert (!append->has_scope);
6de9cd9a
DN
1170
1171 gfc_add_expr_to_block (block, append->head);
1172 append->head = NULL_TREE;
1173}
1174
1175
363aab21
MM
1176/* Save the current locus. The structure may not be complete, and should
1177 only be used with gfc_restore_backend_locus. */
6de9cd9a
DN
1178
1179void
363aab21 1180gfc_save_backend_locus (locus * loc)
6de9cd9a 1181{
ece3f663 1182 loc->lb = XCNEW (gfc_linebuf);
8e400578 1183 loc->lb->location = input_location;
d4fa05b9 1184 loc->lb->file = gfc_current_backend_file;
6de9cd9a
DN
1185}
1186
1187
1188/* Set the current locus. */
1189
1190void
1191gfc_set_backend_locus (locus * loc)
1192{
d4fa05b9 1193 gfc_current_backend_file = loc->lb->file;
c8cc8542 1194 input_location = loc->lb->location;
6de9cd9a
DN
1195}
1196
1197
363aab21
MM
1198/* Restore the saved locus. Only used in conjonction with
1199 gfc_save_backend_locus, to free the memory when we are done. */
1200
1201void
1202gfc_restore_backend_locus (locus * loc)
1203{
1204 gfc_set_backend_locus (loc);
1205 gfc_free (loc->lb);
1206}
1207
1208
bc51e726
JD
1209/* Translate an executable statement. The tree cond is used by gfc_trans_do.
1210 This static function is wrapped by gfc_trans_code_cond and
1211 gfc_trans_code. */
6de9cd9a 1212
bc51e726
JD
1213static tree
1214trans_code (gfc_code * code, tree cond)
6de9cd9a
DN
1215{
1216 stmtblock_t block;
1217 tree res;
1218
1219 if (!code)
c2255bc4 1220 return build_empty_stmt (input_location);
6de9cd9a
DN
1221
1222 gfc_start_block (&block);
1223
726a989a 1224 /* Translate statements one by one into GENERIC trees until we reach
6de9cd9a
DN
1225 the end of this gfc_code branch. */
1226 for (; code; code = code->next)
1227 {
6de9cd9a
DN
1228 if (code->here != 0)
1229 {
1230 res = gfc_trans_label_here (code);
1231 gfc_add_expr_to_block (&block, res);
1232 }
1233
88e09c79
JJ
1234 gfc_set_backend_locus (&code->loc);
1235
6de9cd9a
DN
1236 switch (code->op)
1237 {
1238 case EXEC_NOP:
d80c695f 1239 case EXEC_END_BLOCK:
5c71a5e0 1240 case EXEC_END_PROCEDURE:
6de9cd9a
DN
1241 res = NULL_TREE;
1242 break;
1243
1244 case EXEC_ASSIGN:
f43085aa 1245 if (code->expr1->ts.type == BT_CLASS)
b2a5eb75 1246 res = gfc_trans_class_assign (code->expr1, code->expr2, code->op);
f43085aa
JW
1247 else
1248 res = gfc_trans_assign (code);
6de9cd9a
DN
1249 break;
1250
1251 case EXEC_LABEL_ASSIGN:
1252 res = gfc_trans_label_assign (code);
1253 break;
1254
1255 case EXEC_POINTER_ASSIGN:
f43085aa 1256 if (code->expr1->ts.type == BT_CLASS)
b2a5eb75 1257 res = gfc_trans_class_assign (code->expr1, code->expr2, code->op);
f43085aa
JW
1258 else
1259 res = gfc_trans_pointer_assign (code);
6de9cd9a
DN
1260 break;
1261
6b591ec0 1262 case EXEC_INIT_ASSIGN:
7adac79a 1263 if (code->expr1->ts.type == BT_CLASS)
b2a5eb75 1264 res = gfc_trans_class_init_assign (code);
7adac79a
JW
1265 else
1266 res = gfc_trans_init_assign (code);
6b591ec0
PT
1267 break;
1268
6de9cd9a
DN
1269 case EXEC_CONTINUE:
1270 res = NULL_TREE;
1271 break;
1272
d0a4a61c
TB
1273 case EXEC_CRITICAL:
1274 res = gfc_trans_critical (code);
1275 break;
1276
6de9cd9a
DN
1277 case EXEC_CYCLE:
1278 res = gfc_trans_cycle (code);
1279 break;
1280
1281 case EXEC_EXIT:
1282 res = gfc_trans_exit (code);
1283 break;
1284
1285 case EXEC_GOTO:
1286 res = gfc_trans_goto (code);
1287 break;
1288
3d79abbd
PB
1289 case EXEC_ENTRY:
1290 res = gfc_trans_entry (code);
1291 break;
1292
6de9cd9a
DN
1293 case EXEC_PAUSE:
1294 res = gfc_trans_pause (code);
1295 break;
1296
1297 case EXEC_STOP:
d0a4a61c
TB
1298 case EXEC_ERROR_STOP:
1299 res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP);
6de9cd9a
DN
1300 break;
1301
1302 case EXEC_CALL:
12f681a0
DK
1303 /* For MVBITS we've got the special exception that we need a
1304 dependency check, too. */
1305 {
1306 bool is_mvbits = false;
1307 if (code->resolved_isym
1308 && code->resolved_isym->id == GFC_ISYM_MVBITS)
1309 is_mvbits = true;
b2a5eb75
JW
1310 if (code->resolved_isym
1311 && code->resolved_isym->id == GFC_ISYM_MOVE_ALLOC)
1312 res = gfc_conv_intrinsic_move_alloc (code);
1313 else
1314 res = gfc_trans_call (code, is_mvbits, NULL_TREE,
1315 NULL_TREE, false);
12f681a0 1316 }
476220e7
PT
1317 break;
1318
713485cc 1319 case EXEC_CALL_PPC:
eb74e79b
PT
1320 res = gfc_trans_call (code, false, NULL_TREE,
1321 NULL_TREE, false);
713485cc
JW
1322 break;
1323
476220e7 1324 case EXEC_ASSIGN_CALL:
eb74e79b
PT
1325 res = gfc_trans_call (code, true, NULL_TREE,
1326 NULL_TREE, false);
6de9cd9a
DN
1327 break;
1328
1329 case EXEC_RETURN:
1330 res = gfc_trans_return (code);
1331 break;
1332
1333 case EXEC_IF:
1334 res = gfc_trans_if (code);
1335 break;
1336
1337 case EXEC_ARITHMETIC_IF:
1338 res = gfc_trans_arithmetic_if (code);
9abe5e56
DK
1339 break;
1340
1341 case EXEC_BLOCK:
1342 res = gfc_trans_block_construct (code);
6de9cd9a
DN
1343 break;
1344
1345 case EXEC_DO:
bc51e726 1346 res = gfc_trans_do (code, cond);
6de9cd9a
DN
1347 break;
1348
1349 case EXEC_DO_WHILE:
1350 res = gfc_trans_do_while (code);
1351 break;
1352
1353 case EXEC_SELECT:
1354 res = gfc_trans_select (code);
1355 break;
1356
cf2b3c22
TB
1357 case EXEC_SELECT_TYPE:
1358 /* Do nothing. SELECT TYPE statements should be transformed into
1359 an ordinary SELECT CASE at resolution stage.
1360 TODO: Add an error message here once this is done. */
1361 res = NULL_TREE;
1362 break;
1363
6403ec5f
JB
1364 case EXEC_FLUSH:
1365 res = gfc_trans_flush (code);
1366 break;
1367
d0a4a61c
TB
1368 case EXEC_SYNC_ALL:
1369 case EXEC_SYNC_IMAGES:
1370 case EXEC_SYNC_MEMORY:
1371 res = gfc_trans_sync (code, code->op);
1372 break;
1373
6de9cd9a
DN
1374 case EXEC_FORALL:
1375 res = gfc_trans_forall (code);
1376 break;
1377
1378 case EXEC_WHERE:
1379 res = gfc_trans_where (code);
1380 break;
1381
1382 case EXEC_ALLOCATE:
1383 res = gfc_trans_allocate (code);
1384 break;
1385
1386 case EXEC_DEALLOCATE:
1387 res = gfc_trans_deallocate (code);
1388 break;
1389
1390 case EXEC_OPEN:
1391 res = gfc_trans_open (code);
1392 break;
1393
1394 case EXEC_CLOSE:
1395 res = gfc_trans_close (code);
1396 break;
1397
1398 case EXEC_READ:
1399 res = gfc_trans_read (code);
1400 break;
1401
1402 case EXEC_WRITE:
1403 res = gfc_trans_write (code);
1404 break;
1405
1406 case EXEC_IOLENGTH:
1407 res = gfc_trans_iolength (code);
1408 break;
1409
1410 case EXEC_BACKSPACE:
1411 res = gfc_trans_backspace (code);
1412 break;
1413
1414 case EXEC_ENDFILE:
1415 res = gfc_trans_endfile (code);
1416 break;
1417
1418 case EXEC_INQUIRE:
1419 res = gfc_trans_inquire (code);
1420 break;
1421
6f0f0b2e
JD
1422 case EXEC_WAIT:
1423 res = gfc_trans_wait (code);
1424 break;
1425
6de9cd9a
DN
1426 case EXEC_REWIND:
1427 res = gfc_trans_rewind (code);
1428 break;
1429
1430 case EXEC_TRANSFER:
1431 res = gfc_trans_transfer (code);
1432 break;
1433
1434 case EXEC_DT_END:
1435 res = gfc_trans_dt_end (code);
1436 break;
1437
6c7a4dfd
JJ
1438 case EXEC_OMP_ATOMIC:
1439 case EXEC_OMP_BARRIER:
1440 case EXEC_OMP_CRITICAL:
1441 case EXEC_OMP_DO:
1442 case EXEC_OMP_FLUSH:
1443 case EXEC_OMP_MASTER:
1444 case EXEC_OMP_ORDERED:
1445 case EXEC_OMP_PARALLEL:
1446 case EXEC_OMP_PARALLEL_DO:
1447 case EXEC_OMP_PARALLEL_SECTIONS:
1448 case EXEC_OMP_PARALLEL_WORKSHARE:
1449 case EXEC_OMP_SECTIONS:
1450 case EXEC_OMP_SINGLE:
a68ab351
JJ
1451 case EXEC_OMP_TASK:
1452 case EXEC_OMP_TASKWAIT:
6c7a4dfd
JJ
1453 case EXEC_OMP_WORKSHARE:
1454 res = gfc_trans_omp_directive (code);
1455 break;
1456
6de9cd9a
DN
1457 default:
1458 internal_error ("gfc_trans_code(): Bad statement code");
1459 }
1460
bf737879
TS
1461 gfc_set_backend_locus (&code->loc);
1462
6de9cd9a
DN
1463 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
1464 {
60f5ed26 1465 if (TREE_CODE (res) != STATEMENT_LIST)
c8cc8542 1466 SET_EXPR_LOCATION (res, input_location);
bf737879
TS
1467
1468 /* Add the new statement to the block. */
6de9cd9a
DN
1469 gfc_add_expr_to_block (&block, res);
1470 }
1471 }
1472
1473 /* Return the finished block. */
1474 return gfc_finish_block (&block);
1475}
1476
1477
bc51e726
JD
1478/* Translate an executable statement with condition, cond. The condition is
1479 used by gfc_trans_do to test for IO result conditions inside implied
1480 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */
1481
1482tree
1483gfc_trans_code_cond (gfc_code * code, tree cond)
1484{
1485 return trans_code (code, cond);
1486}
1487
1488/* Translate an executable statement without condition. */
1489
1490tree
1491gfc_trans_code (gfc_code * code)
1492{
1493 return trans_code (code, NULL_TREE);
1494}
1495
1496
6de9cd9a
DN
1497/* This function is called after a complete program unit has been parsed
1498 and resolved. */
1499
1500void
1501gfc_generate_code (gfc_namespace * ns)
1502{
34d01e1d 1503 ompws_flags = 0;
0de4325e
TS
1504 if (ns->is_block_data)
1505 {
1506 gfc_generate_block_data (ns);
1507 return;
1508 }
1509
6de9cd9a
DN
1510 gfc_generate_function_code (ns);
1511}
1512
1513
1514/* This function is called after a complete module has been parsed
1515 and resolved. */
1516
1517void
1518gfc_generate_module_code (gfc_namespace * ns)
1519{
1520 gfc_namespace *n;
a64f5186
JJ
1521 struct module_htab_entry *entry;
1522
1523 gcc_assert (ns->proc_name->backend_decl == NULL);
1524 ns->proc_name->backend_decl
c2255bc4
AH
1525 = build_decl (ns->proc_name->declared_at.lb->location,
1526 NAMESPACE_DECL, get_identifier (ns->proc_name->name),
a64f5186 1527 void_type_node);
a64f5186
JJ
1528 entry = gfc_find_module (ns->proc_name->name);
1529 if (entry->namespace_decl)
1530 /* Buggy sourcecode, using a module before defining it? */
1531 htab_empty (entry->decls);
1532 entry->namespace_decl = ns->proc_name->backend_decl;
6de9cd9a
DN
1533
1534 gfc_generate_module_vars (ns);
1535
1536 /* We need to generate all module function prototypes first, to allow
1537 sibling calls. */
1538 for (n = ns->contained; n; n = n->sibling)
1539 {
a64f5186
JJ
1540 gfc_entry_list *el;
1541
6de9cd9a
DN
1542 if (!n->proc_name)
1543 continue;
1544
fb55ca75 1545 gfc_create_function_decl (n, false);
a64f5186
JJ
1546 DECL_CONTEXT (n->proc_name->backend_decl) = ns->proc_name->backend_decl;
1547 gfc_module_add_decl (entry, n->proc_name->backend_decl);
1548 for (el = ns->entries; el; el = el->next)
1549 {
a64f5186
JJ
1550 DECL_CONTEXT (el->sym->backend_decl) = ns->proc_name->backend_decl;
1551 gfc_module_add_decl (entry, el->sym->backend_decl);
1552 }
6de9cd9a
DN
1553 }
1554
1555 for (n = ns->contained; n; n = n->sibling)
1556 {
1557 if (!n->proc_name)
1558 continue;
1559
1560 gfc_generate_function_code (n);
1561 }
1562}
1563
0019d498
DK
1564
1565/* Initialize an init/cleanup block with existing code. */
1566
1567void
1568gfc_start_wrapped_block (gfc_wrapped_block* block, tree code)
1569{
1570 gcc_assert (block);
1571
1572 block->init = NULL_TREE;
1573 block->code = code;
1574 block->cleanup = NULL_TREE;
1575}
1576
1577
1578/* Add a new pair of initializers/clean-up code. */
1579
1580void
1581gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
1582{
1583 gcc_assert (block);
1584
1585 /* The new pair of init/cleanup should be "wrapped around" the existing
1586 block of code, thus the initialization is added to the front and the
1587 cleanup to the back. */
1588 add_expr_to_chain (&block->init, init, true);
1589 add_expr_to_chain (&block->cleanup, cleanup, false);
1590}
1591
1592
1593/* Finish up a wrapped block by building a corresponding try-finally expr. */
1594
1595tree
1596gfc_finish_wrapped_block (gfc_wrapped_block* block)
1597{
1598 tree result;
1599
1600 gcc_assert (block);
1601
1602 /* Build the final expression. For this, just add init and body together,
1603 and put clean-up with that into a TRY_FINALLY_EXPR. */
1604 result = block->init;
1605 add_expr_to_chain (&result, block->code, false);
1606 if (block->cleanup)
5d44e5c8
TB
1607 result = build2_loc (input_location, TRY_FINALLY_EXPR, void_type_node,
1608 result, block->cleanup);
0019d498
DK
1609
1610 /* Clear the block. */
1611 block->init = NULL_TREE;
1612 block->code = NULL_TREE;
1613 block->cleanup = NULL_TREE;
1614
1615 return result;
1616}