OSDN Git Service

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