OSDN Git Service

fortran/
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-array.c
1 /* Array translation routines
2    Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
3    Inc.
4    Contributed by Paul Brook <paul@nowt.org>
5    and Steven Bosscher <s.bosscher@student.tudelft.nl>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.  If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 02110-1301, USA.  */
23
24 /* trans-array.c-- Various array related code, including scalarization,
25                    allocation, initialization and other support routines.  */
26
27 /* How the scalarizer works.
28    In gfortran, array expressions use the same core routines as scalar
29    expressions.
30    First, a Scalarization State (SS) chain is built.  This is done by walking
31    the expression tree, and building a linear list of the terms in the
32    expression.  As the tree is walked, scalar subexpressions are translated.
33
34    The scalarization parameters are stored in a gfc_loopinfo structure.
35    First the start and stride of each term is calculated by
36    gfc_conv_ss_startstride.  During this process the expressions for the array
37    descriptors and data pointers are also translated.
38
39    If the expression is an assignment, we must then resolve any dependencies.
40    In fortran all the rhs values of an assignment must be evaluated before
41    any assignments take place.  This can require a temporary array to store the
42    values.  We also require a temporary when we are passing array expressions
43    or vector subecripts as procedure parameters.
44
45    Array sections are passed without copying to a temporary.  These use the
46    scalarizer to determine the shape of the section.  The flag
47    loop->array_parameter tells the scalarizer that the actual values and loop
48    variables will not be required.
49
50    The function gfc_conv_loop_setup generates the scalarization setup code.
51    It determines the range of the scalarizing loop variables.  If a temporary
52    is required, this is created and initialized.  Code for scalar expressions
53    taken outside the loop is also generated at this time.  Next the offset and
54    scaling required to translate from loop variables to array indices for each
55    term is calculated.
56
57    A call to gfc_start_scalarized_body marks the start of the scalarized
58    expression.  This creates a scope and declares the loop variables.  Before
59    calling this gfc_make_ss_chain_used must be used to indicate which terms
60    will be used inside this loop.
61
62    The scalar gfc_conv_* functions are then used to build the main body of the
63    scalarization loop.  Scalarization loop variables and precalculated scalar
64    values are automatically substituted.  Note that gfc_advance_se_ss_chain
65    must be used, rather than changing the se->ss directly.
66
67    For assignment expressions requiring a temporary two sub loops are
68    generated.  The first stores the result of the expression in the temporary,
69    the second copies it to the result.  A call to
70    gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
71    the start of the copying loop.  The temporary may be less than full rank.
72
73    Finally gfc_trans_scalarizing_loops is called to generate the implicit do
74    loops.  The loops are added to the pre chain of the loopinfo.  The post
75    chain may still contain cleanup code.
76
77    After the loop code has been added into its parent scope gfc_cleanup_loop
78    is called to free all the SS allocated by the scalarizer.  */
79
80 #include "config.h"
81 #include "system.h"
82 #include "coretypes.h"
83 #include "tree.h"
84 #include "tree-gimple.h"
85 #include "ggc.h"
86 #include "toplev.h"
87 #include "real.h"
88 #include "flags.h"
89 #include "gfortran.h"
90 #include "trans.h"
91 #include "trans-stmt.h"
92 #include "trans-types.h"
93 #include "trans-array.h"
94 #include "trans-const.h"
95 #include "dependency.h"
96
97 static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
98 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor *);
99
100 /* The contents of this structure aren't actually used, just the address.  */
101 static gfc_ss gfc_ss_terminator_var;
102 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
103
104
105 static tree
106 gfc_array_dataptr_type (tree desc)
107 {
108   return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
109 }
110
111
112 /* Build expressions to access the members of an array descriptor.
113    It's surprisingly easy to mess up here, so never access
114    an array descriptor by "brute force", always use these
115    functions.  This also avoids problems if we change the format
116    of an array descriptor.
117
118    To understand these magic numbers, look at the comments
119    before gfc_build_array_type() in trans-types.c.
120
121    The code within these defines should be the only code which knows the format
122    of an array descriptor.
123
124    Any code just needing to read obtain the bounds of an array should use
125    gfc_conv_array_* rather than the following functions as these will return
126    know constant values, and work with arrays which do not have descriptors.
127
128    Don't forget to #undef these!  */
129
130 #define DATA_FIELD 0
131 #define OFFSET_FIELD 1
132 #define DTYPE_FIELD 2
133 #define DIMENSION_FIELD 3
134
135 #define STRIDE_SUBFIELD 0
136 #define LBOUND_SUBFIELD 1
137 #define UBOUND_SUBFIELD 2
138
139 /* This provides READ-ONLY access to the data field.  The field itself
140    doesn't have the proper type.  */
141
142 tree
143 gfc_conv_descriptor_data_get (tree desc)
144 {
145   tree field, type, t;
146
147   type = TREE_TYPE (desc);
148   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
149
150   field = TYPE_FIELDS (type);
151   gcc_assert (DATA_FIELD == 0);
152
153   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
154   t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), t);
155
156   return t;
157 }
158
159 /* This provides WRITE access to the data field.  */
160
161 void
162 gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
163 {
164   tree field, type, t;
165
166   type = TREE_TYPE (desc);
167   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
168
169   field = TYPE_FIELDS (type);
170   gcc_assert (DATA_FIELD == 0);
171
172   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
173   gfc_add_modify_expr (block, t, fold_convert (TREE_TYPE (field), value));
174 }
175
176
177 /* This provides address access to the data field.  This should only be
178    used by array allocation, passing this on to the runtime.  */
179
180 tree
181 gfc_conv_descriptor_data_addr (tree desc)
182 {
183   tree field, type, t;
184
185   type = TREE_TYPE (desc);
186   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
187
188   field = TYPE_FIELDS (type);
189   gcc_assert (DATA_FIELD == 0);
190
191   t = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
192   return build_fold_addr_expr (t);
193 }
194
195 tree
196 gfc_conv_descriptor_offset (tree desc)
197 {
198   tree type;
199   tree field;
200
201   type = TREE_TYPE (desc);
202   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
203
204   field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
205   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
206
207   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
208 }
209
210 tree
211 gfc_conv_descriptor_dtype (tree desc)
212 {
213   tree field;
214   tree type;
215
216   type = TREE_TYPE (desc);
217   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
218
219   field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
220   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
221
222   return build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
223 }
224
225 static tree
226 gfc_conv_descriptor_dimension (tree desc, tree dim)
227 {
228   tree field;
229   tree type;
230   tree tmp;
231
232   type = TREE_TYPE (desc);
233   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
234
235   field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
236   gcc_assert (field != NULL_TREE
237           && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
238           && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
239
240   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
241   tmp = gfc_build_array_ref (tmp, dim);
242   return tmp;
243 }
244
245 tree
246 gfc_conv_descriptor_stride (tree desc, tree dim)
247 {
248   tree tmp;
249   tree field;
250
251   tmp = gfc_conv_descriptor_dimension (desc, dim);
252   field = TYPE_FIELDS (TREE_TYPE (tmp));
253   field = gfc_advance_chain (field, STRIDE_SUBFIELD);
254   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
255
256   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
257   return tmp;
258 }
259
260 tree
261 gfc_conv_descriptor_lbound (tree desc, tree dim)
262 {
263   tree tmp;
264   tree field;
265
266   tmp = gfc_conv_descriptor_dimension (desc, dim);
267   field = TYPE_FIELDS (TREE_TYPE (tmp));
268   field = gfc_advance_chain (field, LBOUND_SUBFIELD);
269   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
270
271   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
272   return tmp;
273 }
274
275 tree
276 gfc_conv_descriptor_ubound (tree desc, tree dim)
277 {
278   tree tmp;
279   tree field;
280
281   tmp = gfc_conv_descriptor_dimension (desc, dim);
282   field = TYPE_FIELDS (TREE_TYPE (tmp));
283   field = gfc_advance_chain (field, UBOUND_SUBFIELD);
284   gcc_assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
285
286   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
287   return tmp;
288 }
289
290
291 /* Build a null array descriptor constructor.  */
292
293 tree
294 gfc_build_null_descriptor (tree type)
295 {
296   tree field;
297   tree tmp;
298
299   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
300   gcc_assert (DATA_FIELD == 0);
301   field = TYPE_FIELDS (type);
302
303   /* Set a NULL data pointer.  */
304   tmp = build_constructor_single (type, field, null_pointer_node);
305   TREE_CONSTANT (tmp) = 1;
306   TREE_INVARIANT (tmp) = 1;
307   /* All other fields are ignored.  */
308
309   return tmp;
310 }
311
312
313 /* Cleanup those #defines.  */
314
315 #undef DATA_FIELD
316 #undef OFFSET_FIELD
317 #undef DTYPE_FIELD
318 #undef DIMENSION_FIELD
319 #undef STRIDE_SUBFIELD
320 #undef LBOUND_SUBFIELD
321 #undef UBOUND_SUBFIELD
322
323
324 /* Mark a SS chain as used.  Flags specifies in which loops the SS is used.
325    flags & 1 = Main loop body.
326    flags & 2 = temp copy loop.  */
327
328 void
329 gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
330 {
331   for (; ss != gfc_ss_terminator; ss = ss->next)
332     ss->useflags = flags;
333 }
334
335 static void gfc_free_ss (gfc_ss *);
336
337
338 /* Free a gfc_ss chain.  */
339
340 static void
341 gfc_free_ss_chain (gfc_ss * ss)
342 {
343   gfc_ss *next;
344
345   while (ss != gfc_ss_terminator)
346     {
347       gcc_assert (ss != NULL);
348       next = ss->next;
349       gfc_free_ss (ss);
350       ss = next;
351     }
352 }
353
354
355 /* Free a SS.  */
356
357 static void
358 gfc_free_ss (gfc_ss * ss)
359 {
360   int n;
361
362   switch (ss->type)
363     {
364     case GFC_SS_SECTION:
365       for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
366         {
367           if (ss->data.info.subscript[n])
368             gfc_free_ss_chain (ss->data.info.subscript[n]);
369         }
370       break;
371
372     default:
373       break;
374     }
375
376   gfc_free (ss);
377 }
378
379
380 /* Free all the SS associated with a loop.  */
381
382 void
383 gfc_cleanup_loop (gfc_loopinfo * loop)
384 {
385   gfc_ss *ss;
386   gfc_ss *next;
387
388   ss = loop->ss;
389   while (ss != gfc_ss_terminator)
390     {
391       gcc_assert (ss != NULL);
392       next = ss->loop_chain;
393       gfc_free_ss (ss);
394       ss = next;
395     }
396 }
397
398
399 /* Associate a SS chain with a loop.  */
400
401 void
402 gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
403 {
404   gfc_ss *ss;
405
406   if (head == gfc_ss_terminator)
407     return;
408
409   ss = head;
410   for (; ss && ss != gfc_ss_terminator; ss = ss->next)
411     {
412       if (ss->next == gfc_ss_terminator)
413         ss->loop_chain = loop->ss;
414       else
415         ss->loop_chain = ss->next;
416     }
417   gcc_assert (ss == gfc_ss_terminator);
418   loop->ss = head;
419 }
420
421
422 /* Generate an initializer for a static pointer or allocatable array.  */
423
424 void
425 gfc_trans_static_array_pointer (gfc_symbol * sym)
426 {
427   tree type;
428
429   gcc_assert (TREE_STATIC (sym->backend_decl));
430   /* Just zero the data member.  */
431   type = TREE_TYPE (sym->backend_decl);
432   DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
433 }
434
435
436 /* If the bounds of SE's loop have not yet been set, see if they can be
437    determined from array spec AS, which is the array spec of a called
438    function.  MAPPING maps the callee's dummy arguments to the values
439    that the caller is passing.  Add any initialization and finalization
440    code to SE.  */
441
442 void
443 gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping,
444                                      gfc_se * se, gfc_array_spec * as)
445 {
446   int n, dim;
447   gfc_se tmpse;
448   tree lower;
449   tree upper;
450   tree tmp;
451
452   if (as && as->type == AS_EXPLICIT)
453     for (dim = 0; dim < se->loop->dimen; dim++)
454       {
455         n = se->loop->order[dim];
456         if (se->loop->to[n] == NULL_TREE)
457           {
458             /* Evaluate the lower bound.  */
459             gfc_init_se (&tmpse, NULL);
460             gfc_apply_interface_mapping (mapping, &tmpse, as->lower[dim]);
461             gfc_add_block_to_block (&se->pre, &tmpse.pre);
462             gfc_add_block_to_block (&se->post, &tmpse.post);
463             lower = tmpse.expr;
464
465             /* ...and the upper bound.  */
466             gfc_init_se (&tmpse, NULL);
467             gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]);
468             gfc_add_block_to_block (&se->pre, &tmpse.pre);
469             gfc_add_block_to_block (&se->post, &tmpse.post);
470             upper = tmpse.expr;
471
472             /* Set the upper bound of the loop to UPPER - LOWER.  */
473             tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, upper, lower);
474             tmp = gfc_evaluate_now (tmp, &se->pre);
475             se->loop->to[n] = tmp;
476           }
477       }
478 }
479
480
481 /* Generate code to allocate an array temporary, or create a variable to
482    hold the data.  If size is NULL, zero the descriptor so that the
483    callee will allocate the array.  If DEALLOC is true, also generate code to
484    free the array afterwards.
485
486    Initialization code is added to PRE and finalization code to POST.
487    DYNAMIC is true if the caller may want to extend the array later
488    using realloc.  This prevents us from putting the array on the stack.  */
489
490 static void
491 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
492                                   gfc_ss_info * info, tree size, tree nelem,
493                                   bool dynamic, bool dealloc)
494 {
495   tree tmp;
496   tree args;
497   tree desc;
498   bool onstack;
499
500   desc = info->descriptor;
501   info->offset = gfc_index_zero_node;
502   if (size == NULL_TREE || integer_zerop (size))
503     {
504       /* A callee allocated array.  */
505       gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
506       onstack = FALSE;
507     }
508   else
509     {
510       /* Allocate the temporary.  */
511       onstack = !dynamic && gfc_can_put_var_on_stack (size);
512
513       if (onstack)
514         {
515           /* Make a temporary variable to hold the data.  */
516           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (nelem), nelem,
517                              integer_one_node);
518           tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
519                                   tmp);
520           tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
521                                   tmp);
522           tmp = gfc_create_var (tmp, "A");
523           tmp = build_fold_addr_expr (tmp);
524           gfc_conv_descriptor_data_set (pre, desc, tmp);
525         }
526       else
527         {
528           /* Allocate memory to hold the data.  */
529           args = gfc_chainon_list (NULL_TREE, size);
530
531           if (gfc_index_integer_kind == 4)
532             tmp = gfor_fndecl_internal_malloc;
533           else if (gfc_index_integer_kind == 8)
534             tmp = gfor_fndecl_internal_malloc64;
535           else
536             gcc_unreachable ();
537           tmp = build_function_call_expr (tmp, args);
538           tmp = gfc_evaluate_now (tmp, pre);
539           gfc_conv_descriptor_data_set (pre, desc, tmp);
540         }
541     }
542   info->data = gfc_conv_descriptor_data_get (desc);
543
544   /* The offset is zero because we create temporaries with a zero
545      lower bound.  */
546   tmp = gfc_conv_descriptor_offset (desc);
547   gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
548
549   if (dealloc && !onstack)
550     {
551       /* Free the temporary.  */
552       tmp = gfc_conv_descriptor_data_get (desc);
553       tmp = fold_convert (pvoid_type_node, tmp);
554       tmp = gfc_chainon_list (NULL_TREE, tmp);
555       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
556       gfc_add_expr_to_block (post, tmp);
557     }
558 }
559
560
561 /* Generate code to create and initialize the descriptor for a temporary
562    array.  This is used for both temporaries needed by the scalarizer, and
563    functions returning arrays.  Adjusts the loop variables to be
564    zero-based, and calculates the loop bounds for callee allocated arrays.
565    Allocate the array unless it's callee allocated (we have a callee
566    allocated array if 'callee_alloc' is true, or if loop->to[n] is
567    NULL_TREE for any n).  Also fills in the descriptor, data and offset
568    fields of info if known.  Returns the size of the array, or NULL for a
569    callee allocated array.
570
571    PRE, POST, DYNAMIC and DEALLOC are as for gfc_trans_allocate_array_storage.
572  */
573
574 tree
575 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
576                              gfc_loopinfo * loop, gfc_ss_info * info,
577                              tree eltype, bool dynamic, bool dealloc,
578                              bool callee_alloc)
579 {
580   tree type;
581   tree desc;
582   tree tmp;
583   tree size;
584   tree nelem;
585   int n;
586   int dim;
587
588   gcc_assert (info->dimen > 0);
589   /* Set the lower bound to zero.  */
590   for (dim = 0; dim < info->dimen; dim++)
591     {
592       n = loop->order[dim];
593       if (n < loop->temp_dim)
594         gcc_assert (integer_zerop (loop->from[n]));
595       else
596         {
597           /* Callee allocated arrays may not have a known bound yet.  */
598           if (loop->to[n])
599               loop->to[n] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
600                                          loop->to[n], loop->from[n]);
601           loop->from[n] = gfc_index_zero_node;
602         }
603
604       info->delta[dim] = gfc_index_zero_node;
605       info->start[dim] = gfc_index_zero_node;
606       info->stride[dim] = gfc_index_one_node;
607       info->dim[dim] = dim;
608     }
609
610   /* Initialize the descriptor.  */
611   type =
612     gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
613   desc = gfc_create_var (type, "atmp");
614   GFC_DECL_PACKED_ARRAY (desc) = 1;
615
616   info->descriptor = desc;
617   size = gfc_index_one_node;
618
619   /* Fill in the array dtype.  */
620   tmp = gfc_conv_descriptor_dtype (desc);
621   gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
622
623   /*
624      Fill in the bounds and stride.  This is a packed array, so:
625
626      size = 1;
627      for (n = 0; n < rank; n++)
628        {
629          stride[n] = size
630          delta = ubound[n] + 1 - lbound[n];
631          size = size * delta;
632        }
633      size = size * sizeof(element);
634   */
635
636   for (n = 0; n < info->dimen; n++)
637     {
638       if (loop->to[n] == NULL_TREE)
639         {
640           /* For a callee allocated array express the loop bounds in terms
641              of the descriptor fields.  */
642           tmp = build2 (MINUS_EXPR, gfc_array_index_type,
643                         gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
644                         gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
645           loop->to[n] = tmp;
646           size = NULL_TREE;
647           continue;
648         }
649         
650       /* Store the stride and bound components in the descriptor.  */
651       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
652       gfc_add_modify_expr (pre, tmp, size);
653
654       tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
655       gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
656
657       tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
658       gfc_add_modify_expr (pre, tmp, loop->to[n]);
659
660       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
661                          loop->to[n], gfc_index_one_node);
662
663       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
664       size = gfc_evaluate_now (size, pre);
665     }
666
667   /* Get the size of the array.  */
668   nelem = size;
669   if (size && !callee_alloc)
670     size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
671                         TYPE_SIZE_UNIT (gfc_get_element_type (type)));
672   else
673     size = NULL_TREE;
674
675   gfc_trans_allocate_array_storage (pre, post, info, size, nelem, dynamic,
676                                     dealloc);
677
678   if (info->dimen > loop->temp_dim)
679     loop->temp_dim = info->dimen;
680
681   return size;
682 }
683
684
685 /* Generate code to transpose array EXPR by creating a new descriptor
686    in which the dimension specifications have been reversed.  */
687
688 void
689 gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
690 {
691   tree dest, src, dest_index, src_index;
692   gfc_loopinfo *loop;
693   gfc_ss_info *dest_info, *src_info;
694   gfc_ss *dest_ss, *src_ss;
695   gfc_se src_se;
696   int n;
697
698   loop = se->loop;
699
700   src_ss = gfc_walk_expr (expr);
701   dest_ss = se->ss;
702
703   src_info = &src_ss->data.info;
704   dest_info = &dest_ss->data.info;
705
706   /* Get a descriptor for EXPR.  */
707   gfc_init_se (&src_se, NULL);
708   gfc_conv_expr_descriptor (&src_se, expr, src_ss);
709   gfc_add_block_to_block (&se->pre, &src_se.pre);
710   gfc_add_block_to_block (&se->post, &src_se.post);
711   src = src_se.expr;
712
713   /* Allocate a new descriptor for the return value.  */
714   dest = gfc_create_var (TREE_TYPE (src), "atmp");
715   dest_info->descriptor = dest;
716   se->expr = dest;
717
718   /* Copy across the dtype field.  */
719   gfc_add_modify_expr (&se->pre,
720                        gfc_conv_descriptor_dtype (dest),
721                        gfc_conv_descriptor_dtype (src));
722
723   /* Copy the dimension information, renumbering dimension 1 to 0 and
724      0 to 1.  */
725   gcc_assert (dest_info->dimen == 2);
726   gcc_assert (src_info->dimen == 2);
727   for (n = 0; n < 2; n++)
728     {
729       dest_info->delta[n] = integer_zero_node;
730       dest_info->start[n] = integer_zero_node;
731       dest_info->stride[n] = integer_one_node;
732       dest_info->dim[n] = n;
733
734       dest_index = gfc_rank_cst[n];
735       src_index = gfc_rank_cst[1 - n];
736
737       gfc_add_modify_expr (&se->pre,
738                            gfc_conv_descriptor_stride (dest, dest_index),
739                            gfc_conv_descriptor_stride (src, src_index));
740
741       gfc_add_modify_expr (&se->pre,
742                            gfc_conv_descriptor_lbound (dest, dest_index),
743                            gfc_conv_descriptor_lbound (src, src_index));
744
745       gfc_add_modify_expr (&se->pre,
746                            gfc_conv_descriptor_ubound (dest, dest_index),
747                            gfc_conv_descriptor_ubound (src, src_index));
748
749       if (!loop->to[n])
750         {
751           gcc_assert (integer_zerop (loop->from[n]));
752           loop->to[n] = build2 (MINUS_EXPR, gfc_array_index_type,
753                                 gfc_conv_descriptor_ubound (dest, dest_index),
754                                 gfc_conv_descriptor_lbound (dest, dest_index));
755         }
756     }
757
758   /* Copy the data pointer.  */
759   dest_info->data = gfc_conv_descriptor_data_get (src);
760   gfc_conv_descriptor_data_set (&se->pre, dest, dest_info->data);
761
762   /* Copy the offset.  This is not changed by transposition: the top-left
763      element is still at the same offset as before.  */
764   dest_info->offset = gfc_conv_descriptor_offset (src);
765   gfc_add_modify_expr (&se->pre,
766                        gfc_conv_descriptor_offset (dest),
767                        dest_info->offset);
768
769   if (dest_info->dimen > loop->temp_dim)
770     loop->temp_dim = dest_info->dimen;
771 }
772
773
774 /* Return the number of iterations in a loop that starts at START,
775    ends at END, and has step STEP.  */
776
777 static tree
778 gfc_get_iteration_count (tree start, tree end, tree step)
779 {
780   tree tmp;
781   tree type;
782
783   type = TREE_TYPE (step);
784   tmp = fold_build2 (MINUS_EXPR, type, end, start);
785   tmp = fold_build2 (FLOOR_DIV_EXPR, type, tmp, step);
786   tmp = fold_build2 (PLUS_EXPR, type, tmp, build_int_cst (type, 1));
787   tmp = fold_build2 (MAX_EXPR, type, tmp, build_int_cst (type, 0));
788   return fold_convert (gfc_array_index_type, tmp);
789 }
790
791
792 /* Extend the data in array DESC by EXTRA elements.  */
793
794 static void
795 gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
796 {
797   tree args;
798   tree tmp;
799   tree size;
800   tree ubound;
801
802   if (integer_zerop (extra))
803     return;
804
805   ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
806
807   /* Add EXTRA to the upper bound.  */
808   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
809   gfc_add_modify_expr (pblock, ubound, tmp);
810
811   /* Get the value of the current data pointer.  */
812   tmp = gfc_conv_descriptor_data_get (desc);
813   args = gfc_chainon_list (NULL_TREE, tmp);
814
815   /* Calculate the new array size.  */
816   size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
817   tmp = build2 (PLUS_EXPR, gfc_array_index_type, ubound, gfc_index_one_node);
818   tmp = build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
819   args = gfc_chainon_list (args, tmp);
820
821   /* Pick the appropriate realloc function.  */
822   if (gfc_index_integer_kind == 4)
823     tmp = gfor_fndecl_internal_realloc;
824   else if (gfc_index_integer_kind == 8)
825     tmp = gfor_fndecl_internal_realloc64;
826   else
827     gcc_unreachable ();
828
829   /* Set the new data pointer.  */
830   tmp = build_function_call_expr (tmp, args);
831   gfc_conv_descriptor_data_set (pblock, desc, tmp);
832 }
833
834
835 /* Return true if the bounds of iterator I can only be determined
836    at run time.  */
837
838 static inline bool
839 gfc_iterator_has_dynamic_bounds (gfc_iterator * i)
840 {
841   return (i->start->expr_type != EXPR_CONSTANT
842           || i->end->expr_type != EXPR_CONSTANT
843           || i->step->expr_type != EXPR_CONSTANT);
844 }
845
846
847 /* Split the size of constructor element EXPR into the sum of two terms,
848    one of which can be determined at compile time and one of which must
849    be calculated at run time.  Set *SIZE to the former and return true
850    if the latter might be nonzero.  */
851
852 static bool
853 gfc_get_array_constructor_element_size (mpz_t * size, gfc_expr * expr)
854 {
855   if (expr->expr_type == EXPR_ARRAY)
856     return gfc_get_array_constructor_size (size, expr->value.constructor);
857   else if (expr->rank > 0)
858     {
859       /* Calculate everything at run time.  */
860       mpz_set_ui (*size, 0);
861       return true;
862     }
863   else
864     {
865       /* A single element.  */
866       mpz_set_ui (*size, 1);
867       return false;
868     }
869 }
870
871
872 /* Like gfc_get_array_constructor_element_size, but applied to the whole
873    of array constructor C.  */
874
875 static bool
876 gfc_get_array_constructor_size (mpz_t * size, gfc_constructor * c)
877 {
878   gfc_iterator *i;
879   mpz_t val;
880   mpz_t len;
881   bool dynamic;
882
883   mpz_set_ui (*size, 0);
884   mpz_init (len);
885   mpz_init (val);
886
887   dynamic = false;
888   for (; c; c = c->next)
889     {
890       i = c->iterator;
891       if (i && gfc_iterator_has_dynamic_bounds (i))
892         dynamic = true;
893       else
894         {
895           dynamic |= gfc_get_array_constructor_element_size (&len, c->expr);
896           if (i)
897             {
898               /* Multiply the static part of the element size by the
899                  number of iterations.  */
900               mpz_sub (val, i->end->value.integer, i->start->value.integer);
901               mpz_fdiv_q (val, val, i->step->value.integer);
902               mpz_add_ui (val, val, 1);
903               if (mpz_sgn (val) > 0)
904                 mpz_mul (len, len, val);
905               else
906                 mpz_set_ui (len, 0);
907             }
908           mpz_add (*size, *size, len);
909         }
910     }
911   mpz_clear (len);
912   mpz_clear (val);
913   return dynamic;
914 }
915
916
917 /* Make sure offset is a variable.  */
918
919 static void
920 gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
921                          tree * offsetvar)
922 {
923   /* We should have already created the offset variable.  We cannot
924      create it here because we may be in an inner scope.  */
925   gcc_assert (*offsetvar != NULL_TREE);
926   gfc_add_modify_expr (pblock, *offsetvar, *poffset);
927   *poffset = *offsetvar;
928   TREE_USED (*offsetvar) = 1;
929 }
930
931
932 /* Assign an element of an array constructor.  */
933
934 static void
935 gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
936                               tree offset, gfc_se * se, gfc_expr * expr)
937 {
938   tree tmp;
939   tree args;
940
941   gfc_conv_expr (se, expr);
942
943   /* Store the value.  */
944   tmp = build_fold_indirect_ref (gfc_conv_descriptor_data_get (desc));
945   tmp = gfc_build_array_ref (tmp, offset);
946   if (expr->ts.type == BT_CHARACTER)
947     {
948       gfc_conv_string_parameter (se);
949       if (POINTER_TYPE_P (TREE_TYPE (tmp)))
950         {
951           /* The temporary is an array of pointers.  */
952           se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
953           gfc_add_modify_expr (&se->pre, tmp, se->expr);
954         }
955       else
956         {
957           /* The temporary is an array of string values.  */
958           tmp = gfc_build_addr_expr (pchar_type_node, tmp);
959           /* We know the temporary and the value will be the same length,
960              so can use memcpy.  */
961           args = gfc_chainon_list (NULL_TREE, tmp);
962           args = gfc_chainon_list (args, se->expr);
963           args = gfc_chainon_list (args, se->string_length);
964           tmp = built_in_decls[BUILT_IN_MEMCPY];
965           tmp = build_function_call_expr (tmp, args);
966           gfc_add_expr_to_block (&se->pre, tmp);
967         }
968     }
969   else
970     {
971       /* TODO: Should the frontend already have done this conversion?  */
972       se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
973       gfc_add_modify_expr (&se->pre, tmp, se->expr);
974     }
975
976   gfc_add_block_to_block (pblock, &se->pre);
977   gfc_add_block_to_block (pblock, &se->post);
978 }
979
980
981 /* Add the contents of an array to the constructor.  DYNAMIC is as for
982    gfc_trans_array_constructor_value.  */
983
984 static void
985 gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
986                                       tree type ATTRIBUTE_UNUSED,
987                                       tree desc, gfc_expr * expr,
988                                       tree * poffset, tree * offsetvar,
989                                       bool dynamic)
990 {
991   gfc_se se;
992   gfc_ss *ss;
993   gfc_loopinfo loop;
994   stmtblock_t body;
995   tree tmp;
996   tree size;
997   int n;
998
999   /* We need this to be a variable so we can increment it.  */
1000   gfc_put_offset_into_var (pblock, poffset, offsetvar);
1001
1002   gfc_init_se (&se, NULL);
1003
1004   /* Walk the array expression.  */
1005   ss = gfc_walk_expr (expr);
1006   gcc_assert (ss != gfc_ss_terminator);
1007
1008   /* Initialize the scalarizer.  */
1009   gfc_init_loopinfo (&loop);
1010   gfc_add_ss_to_loop (&loop, ss);
1011
1012   /* Initialize the loop.  */
1013   gfc_conv_ss_startstride (&loop);
1014   gfc_conv_loop_setup (&loop);
1015
1016   /* Make sure the constructed array has room for the new data.  */
1017   if (dynamic)
1018     {
1019       /* Set SIZE to the total number of elements in the subarray.  */
1020       size = gfc_index_one_node;
1021       for (n = 0; n < loop.dimen; n++)
1022         {
1023           tmp = gfc_get_iteration_count (loop.from[n], loop.to[n],
1024                                          gfc_index_one_node);
1025           size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1026         }
1027
1028       /* Grow the constructed array by SIZE elements.  */
1029       gfc_grow_array (&loop.pre, desc, size);
1030     }
1031
1032   /* Make the loop body.  */
1033   gfc_mark_ss_chain_used (ss, 1);
1034   gfc_start_scalarized_body (&loop, &body);
1035   gfc_copy_loopinfo_to_se (&se, &loop);
1036   se.ss = ss;
1037
1038   if (expr->ts.type == BT_CHARACTER)
1039     gfc_todo_error ("character arrays in constructors");
1040
1041   gfc_trans_array_ctor_element (&body, desc, *poffset, &se, expr);
1042   gcc_assert (se.ss == gfc_ss_terminator);
1043
1044   /* Increment the offset.  */
1045   tmp = build2 (PLUS_EXPR, gfc_array_index_type, *poffset, gfc_index_one_node);
1046   gfc_add_modify_expr (&body, *poffset, tmp);
1047
1048   /* Finish the loop.  */
1049   gfc_trans_scalarizing_loops (&loop, &body);
1050   gfc_add_block_to_block (&loop.pre, &loop.post);
1051   tmp = gfc_finish_block (&loop.pre);
1052   gfc_add_expr_to_block (pblock, tmp);
1053
1054   gfc_cleanup_loop (&loop);
1055 }
1056
1057
1058 /* Assign the values to the elements of an array constructor.  DYNAMIC
1059    is true if descriptor DESC only contains enough data for the static
1060    size calculated by gfc_get_array_constructor_size.  When true, memory
1061    for the dynamic parts must be allocated using realloc.  */
1062
1063 static void
1064 gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
1065                                    tree desc, gfc_constructor * c,
1066                                    tree * poffset, tree * offsetvar,
1067                                    bool dynamic)
1068 {
1069   tree tmp;
1070   stmtblock_t body;
1071   gfc_se se;
1072   mpz_t size;
1073
1074   mpz_init (size);
1075   for (; c; c = c->next)
1076     {
1077       /* If this is an iterator or an array, the offset must be a variable.  */
1078       if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
1079         gfc_put_offset_into_var (pblock, poffset, offsetvar);
1080
1081       gfc_start_block (&body);
1082
1083       if (c->expr->expr_type == EXPR_ARRAY)
1084         {
1085           /* Array constructors can be nested.  */
1086           gfc_trans_array_constructor_value (&body, type, desc,
1087                                              c->expr->value.constructor,
1088                                              poffset, offsetvar, dynamic);
1089         }
1090       else if (c->expr->rank > 0)
1091         {
1092           gfc_trans_array_constructor_subarray (&body, type, desc, c->expr,
1093                                                 poffset, offsetvar, dynamic);
1094         }
1095       else
1096         {
1097           /* This code really upsets the gimplifier so don't bother for now.  */
1098           gfc_constructor *p;
1099           HOST_WIDE_INT n;
1100           HOST_WIDE_INT size;
1101
1102           p = c;
1103           n = 0;
1104           while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
1105             {
1106               p = p->next;
1107               n++;
1108             }
1109           if (n < 4)
1110             {
1111               /* Scalar values.  */
1112               gfc_init_se (&se, NULL);
1113               gfc_trans_array_ctor_element (&body, desc, *poffset,
1114                                             &se, c->expr);
1115
1116               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1117                                       *poffset, gfc_index_one_node);
1118             }
1119           else
1120             {
1121               /* Collect multiple scalar constants into a constructor.  */
1122               tree list;
1123               tree init;
1124               tree bound;
1125               tree tmptype;
1126
1127               p = c;
1128               list = NULL_TREE;
1129               /* Count the number of consecutive scalar constants.  */
1130               while (p && !(p->iterator
1131                             || p->expr->expr_type != EXPR_CONSTANT))
1132                 {
1133                   gfc_init_se (&se, NULL);
1134                   gfc_conv_constant (&se, p->expr);
1135                   if (p->expr->ts.type == BT_CHARACTER
1136                       && POINTER_TYPE_P (type))
1137                     {
1138                       /* For constant character array constructors we build
1139                          an array of pointers.  */
1140                       se.expr = gfc_build_addr_expr (pchar_type_node,
1141                                                      se.expr);
1142                     }
1143                     
1144                   list = tree_cons (NULL_TREE, se.expr, list);
1145                   c = p;
1146                   p = p->next;
1147                 }
1148
1149               bound = build_int_cst (NULL_TREE, n - 1);
1150               /* Create an array type to hold them.  */
1151               tmptype = build_range_type (gfc_array_index_type,
1152                                           gfc_index_zero_node, bound);
1153               tmptype = build_array_type (type, tmptype);
1154
1155               init = build_constructor_from_list (tmptype, nreverse (list));
1156               TREE_CONSTANT (init) = 1;
1157               TREE_INVARIANT (init) = 1;
1158               TREE_STATIC (init) = 1;
1159               /* Create a static variable to hold the data.  */
1160               tmp = gfc_create_var (tmptype, "data");
1161               TREE_STATIC (tmp) = 1;
1162               TREE_CONSTANT (tmp) = 1;
1163               TREE_INVARIANT (tmp) = 1;
1164               DECL_INITIAL (tmp) = init;
1165               init = tmp;
1166
1167               /* Use BUILTIN_MEMCPY to assign the values.  */
1168               tmp = gfc_conv_descriptor_data_get (desc);
1169               tmp = build_fold_indirect_ref (tmp);
1170               tmp = gfc_build_array_ref (tmp, *poffset);
1171               tmp = build_fold_addr_expr (tmp);
1172               init = build_fold_addr_expr (init);
1173
1174               size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
1175               bound = build_int_cst (NULL_TREE, n * size);
1176               tmp = gfc_chainon_list (NULL_TREE, tmp);
1177               tmp = gfc_chainon_list (tmp, init);
1178               tmp = gfc_chainon_list (tmp, bound);
1179               tmp = build_function_call_expr (built_in_decls[BUILT_IN_MEMCPY],
1180                                              tmp);
1181               gfc_add_expr_to_block (&body, tmp);
1182
1183               *poffset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1184                                       *poffset, build_int_cst (NULL_TREE, n));
1185             }
1186           if (!INTEGER_CST_P (*poffset))
1187             {
1188               gfc_add_modify_expr (&body, *offsetvar, *poffset);
1189               *poffset = *offsetvar;
1190             }
1191         }
1192
1193       /* The frontend should already have done any expansions possible
1194          at compile-time.  */
1195       if (!c->iterator)
1196         {
1197           /* Pass the code as is.  */
1198           tmp = gfc_finish_block (&body);
1199           gfc_add_expr_to_block (pblock, tmp);
1200         }
1201       else
1202         {
1203           /* Build the implied do-loop.  */
1204           tree cond;
1205           tree end;
1206           tree step;
1207           tree loopvar;
1208           tree exit_label;
1209           tree loopbody;
1210           tree tmp2;
1211
1212           loopbody = gfc_finish_block (&body);
1213
1214           gfc_init_se (&se, NULL);
1215           gfc_conv_expr (&se, c->iterator->var);
1216           gfc_add_block_to_block (pblock, &se.pre);
1217           loopvar = se.expr;
1218
1219           /* Initialize the loop.  */
1220           gfc_init_se (&se, NULL);
1221           gfc_conv_expr_val (&se, c->iterator->start);
1222           gfc_add_block_to_block (pblock, &se.pre);
1223           gfc_add_modify_expr (pblock, loopvar, se.expr);
1224
1225           gfc_init_se (&se, NULL);
1226           gfc_conv_expr_val (&se, c->iterator->end);
1227           gfc_add_block_to_block (pblock, &se.pre);
1228           end = gfc_evaluate_now (se.expr, pblock);
1229
1230           gfc_init_se (&se, NULL);
1231           gfc_conv_expr_val (&se, c->iterator->step);
1232           gfc_add_block_to_block (pblock, &se.pre);
1233           step = gfc_evaluate_now (se.expr, pblock);
1234
1235           /* If this array expands dynamically, and the number of iterations
1236              is not constant, we won't have allocated space for the static
1237              part of C->EXPR's size.  Do that now.  */
1238           if (dynamic && gfc_iterator_has_dynamic_bounds (c->iterator))
1239             {
1240               /* Get the number of iterations.  */
1241               tmp = gfc_get_iteration_count (loopvar, end, step);
1242
1243               /* Get the static part of C->EXPR's size.  */
1244               gfc_get_array_constructor_element_size (&size, c->expr);
1245               tmp2 = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1246
1247               /* Grow the array by TMP * TMP2 elements.  */
1248               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, tmp2);
1249               gfc_grow_array (pblock, desc, tmp);
1250             }
1251
1252           /* Generate the loop body.  */
1253           exit_label = gfc_build_label_decl (NULL_TREE);
1254           gfc_start_block (&body);
1255
1256           /* Generate the exit condition.  Depending on the sign of
1257              the step variable we have to generate the correct
1258              comparison.  */
1259           tmp = fold_build2 (GT_EXPR, boolean_type_node, step, 
1260                              build_int_cst (TREE_TYPE (step), 0));
1261           cond = fold_build3 (COND_EXPR, boolean_type_node, tmp,
1262                               build2 (GT_EXPR, boolean_type_node,
1263                                       loopvar, end),
1264                               build2 (LT_EXPR, boolean_type_node,
1265                                       loopvar, end));
1266           tmp = build1_v (GOTO_EXPR, exit_label);
1267           TREE_USED (exit_label) = 1;
1268           tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1269           gfc_add_expr_to_block (&body, tmp);
1270
1271           /* The main loop body.  */
1272           gfc_add_expr_to_block (&body, loopbody);
1273
1274           /* Increase loop variable by step.  */
1275           tmp = build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
1276           gfc_add_modify_expr (&body, loopvar, tmp);
1277
1278           /* Finish the loop.  */
1279           tmp = gfc_finish_block (&body);
1280           tmp = build1_v (LOOP_EXPR, tmp);
1281           gfc_add_expr_to_block (pblock, tmp);
1282
1283           /* Add the exit label.  */
1284           tmp = build1_v (LABEL_EXPR, exit_label);
1285           gfc_add_expr_to_block (pblock, tmp);
1286         }
1287     }
1288   mpz_clear (size);
1289 }
1290
1291
1292 /* Figure out the string length of a variable reference expression.
1293    Used by get_array_ctor_strlen.  */
1294
1295 static void
1296 get_array_ctor_var_strlen (gfc_expr * expr, tree * len)
1297 {
1298   gfc_ref *ref;
1299   gfc_typespec *ts;
1300
1301   /* Don't bother if we already know the length is a constant.  */
1302   if (*len && INTEGER_CST_P (*len))
1303     return;
1304
1305   ts = &expr->symtree->n.sym->ts;
1306   for (ref = expr->ref; ref; ref = ref->next)
1307     {
1308       switch (ref->type)
1309         {
1310         case REF_ARRAY:
1311           /* Array references don't change the string length.  */
1312           break;
1313
1314         case COMPONENT_REF:
1315           /* Use the length of the component.  */
1316           ts = &ref->u.c.component->ts;
1317           break;
1318
1319         default:
1320           /* TODO: Substrings are tricky because we can't evaluate the
1321              expression more than once.  For now we just give up, and hope
1322              we can figure it out elsewhere.  */
1323           return;
1324         }
1325     }
1326
1327   *len = ts->cl->backend_decl;
1328 }
1329
1330
1331 /* Figure out the string length of a character array constructor.
1332    Returns TRUE if all elements are character constants.  */
1333
1334 static bool
1335 get_array_ctor_strlen (gfc_constructor * c, tree * len)
1336 {
1337   bool is_const;
1338   
1339   is_const = TRUE;
1340   for (; c; c = c->next)
1341     {
1342       switch (c->expr->expr_type)
1343         {
1344         case EXPR_CONSTANT:
1345           if (!(*len && INTEGER_CST_P (*len)))
1346             *len = build_int_cstu (gfc_charlen_type_node,
1347                                    c->expr->value.character.length);
1348           break;
1349
1350         case EXPR_ARRAY:
1351           if (!get_array_ctor_strlen (c->expr->value.constructor, len))
1352             is_const = FALSE;
1353           break;
1354
1355         case EXPR_VARIABLE:
1356           is_const = false;
1357           get_array_ctor_var_strlen (c->expr, len);
1358           break;
1359
1360         default:
1361           is_const = FALSE;
1362           /* TODO: For now we just ignore anything we don't know how to
1363              handle, and hope we can figure it out a different way.  */
1364           break;
1365         }
1366     }
1367
1368   return is_const;
1369 }
1370
1371
1372 /* Array constructors are handled by constructing a temporary, then using that
1373    within the scalarization loop.  This is not optimal, but seems by far the
1374    simplest method.  */
1375
1376 static void
1377 gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
1378 {
1379   gfc_constructor *c;
1380   tree offset;
1381   tree offsetvar;
1382   tree desc;
1383   tree type;
1384   bool const_string;
1385   bool dynamic;
1386
1387   ss->data.info.dimen = loop->dimen;
1388
1389   c = ss->expr->value.constructor;
1390   if (ss->expr->ts.type == BT_CHARACTER)
1391     {
1392       const_string = get_array_ctor_strlen (c, &ss->string_length);
1393       if (!ss->string_length)
1394         gfc_todo_error ("complex character array constructors");
1395
1396       type = gfc_get_character_type_len (ss->expr->ts.kind, ss->string_length);
1397       if (const_string)
1398         type = build_pointer_type (type);
1399     }
1400   else
1401     {
1402       const_string = TRUE;
1403       type = gfc_typenode_for_spec (&ss->expr->ts);
1404     }
1405
1406   /* See if the constructor determines the loop bounds.  */
1407   dynamic = false;
1408   if (loop->to[0] == NULL_TREE)
1409     {
1410       mpz_t size;
1411
1412       /* We should have a 1-dimensional, zero-based loop.  */
1413       gcc_assert (loop->dimen == 1);
1414       gcc_assert (integer_zerop (loop->from[0]));
1415
1416       /* Split the constructor size into a static part and a dynamic part.
1417          Allocate the static size up-front and record whether the dynamic
1418          size might be nonzero.  */
1419       mpz_init (size);
1420       dynamic = gfc_get_array_constructor_size (&size, c);
1421       mpz_sub_ui (size, size, 1);
1422       loop->to[0] = gfc_conv_mpz_to_tree (size, gfc_index_integer_kind);
1423       mpz_clear (size);
1424     }
1425
1426   gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
1427                                type, dynamic, true, false);
1428
1429   desc = ss->data.info.descriptor;
1430   offset = gfc_index_zero_node;
1431   offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
1432   TREE_USED (offsetvar) = 0;
1433   gfc_trans_array_constructor_value (&loop->pre, type, desc, c,
1434                                      &offset, &offsetvar, dynamic);
1435
1436   /* If the array grows dynamically, the upper bound of the loop variable
1437      is determined by the array's final upper bound.  */
1438   if (dynamic)
1439     loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
1440
1441   if (TREE_USED (offsetvar))
1442     pushdecl (offsetvar);
1443   else
1444     gcc_assert (INTEGER_CST_P (offset));
1445 #if 0
1446   /* Disable bound checking for now because it's probably broken.  */
1447   if (flag_bounds_check)
1448     {
1449       gcc_unreachable ();
1450     }
1451 #endif
1452 }
1453
1454
1455 /* INFO describes a GFC_SS_SECTION in loop LOOP, and this function is
1456    called after evaluating all of INFO's vector dimensions.  Go through
1457    each such vector dimension and see if we can now fill in any missing
1458    loop bounds.  */
1459
1460 static void
1461 gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
1462 {
1463   gfc_se se;
1464   tree tmp;
1465   tree desc;
1466   tree zero;
1467   int n;
1468   int dim;
1469
1470   for (n = 0; n < loop->dimen; n++)
1471     {
1472       dim = info->dim[n];
1473       if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR
1474           && loop->to[n] == NULL)
1475         {
1476           /* Loop variable N indexes vector dimension DIM, and we don't
1477              yet know the upper bound of loop variable N.  Set it to the
1478              difference between the vector's upper and lower bounds.  */
1479           gcc_assert (loop->from[n] == gfc_index_zero_node);
1480           gcc_assert (info->subscript[dim]
1481                       && info->subscript[dim]->type == GFC_SS_VECTOR);
1482
1483           gfc_init_se (&se, NULL);
1484           desc = info->subscript[dim]->data.info.descriptor;
1485           zero = gfc_rank_cst[0];
1486           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1487                              gfc_conv_descriptor_ubound (desc, zero),
1488                              gfc_conv_descriptor_lbound (desc, zero));
1489           tmp = gfc_evaluate_now (tmp, &loop->pre);
1490           loop->to[n] = tmp;
1491         }
1492     }
1493 }
1494
1495
1496 /* Add the pre and post chains for all the scalar expressions in a SS chain
1497    to loop.  This is called after the loop parameters have been calculated,
1498    but before the actual scalarizing loops.  */
1499
1500 static void
1501 gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
1502 {
1503   gfc_se se;
1504   int n;
1505
1506   /* TODO: This can generate bad code if there are ordering dependencies.
1507      eg. a callee allocated function and an unknown size constructor.  */
1508   gcc_assert (ss != NULL);
1509
1510   for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
1511     {
1512       gcc_assert (ss);
1513
1514       switch (ss->type)
1515         {
1516         case GFC_SS_SCALAR:
1517           /* Scalar expression.  Evaluate this now.  This includes elemental
1518              dimension indices, but not array section bounds.  */
1519           gfc_init_se (&se, NULL);
1520           gfc_conv_expr (&se, ss->expr);
1521           gfc_add_block_to_block (&loop->pre, &se.pre);
1522
1523           if (ss->expr->ts.type != BT_CHARACTER)
1524             {
1525               /* Move the evaluation of scalar expressions outside the
1526                  scalarization loop.  */
1527               if (subscript)
1528                 se.expr = convert(gfc_array_index_type, se.expr);
1529               se.expr = gfc_evaluate_now (se.expr, &loop->pre);
1530               gfc_add_block_to_block (&loop->pre, &se.post);
1531             }
1532           else
1533             gfc_add_block_to_block (&loop->post, &se.post);
1534
1535           ss->data.scalar.expr = se.expr;
1536           ss->string_length = se.string_length;
1537           break;
1538
1539         case GFC_SS_REFERENCE:
1540           /* Scalar reference.  Evaluate this now.  */
1541           gfc_init_se (&se, NULL);
1542           gfc_conv_expr_reference (&se, ss->expr);
1543           gfc_add_block_to_block (&loop->pre, &se.pre);
1544           gfc_add_block_to_block (&loop->post, &se.post);
1545
1546           ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
1547           ss->string_length = se.string_length;
1548           break;
1549
1550         case GFC_SS_SECTION:
1551           /* Add the expressions for scalar and vector subscripts.  */
1552           for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1553             if (ss->data.info.subscript[n])
1554               gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
1555
1556           gfc_set_vector_loop_bounds (loop, &ss->data.info);
1557           break;
1558
1559         case GFC_SS_VECTOR:
1560           /* Get the vector's descriptor and store it in SS.  */
1561           gfc_init_se (&se, NULL);
1562           gfc_conv_expr_descriptor (&se, ss->expr, gfc_walk_expr (ss->expr));
1563           gfc_add_block_to_block (&loop->pre, &se.pre);
1564           gfc_add_block_to_block (&loop->post, &se.post);
1565           ss->data.info.descriptor = se.expr;
1566           break;
1567
1568         case GFC_SS_INTRINSIC:
1569           gfc_add_intrinsic_ss_code (loop, ss);
1570           break;
1571
1572         case GFC_SS_FUNCTION:
1573           /* Array function return value.  We call the function and save its
1574              result in a temporary for use inside the loop.  */
1575           gfc_init_se (&se, NULL);
1576           se.loop = loop;
1577           se.ss = ss;
1578           gfc_conv_expr (&se, ss->expr);
1579           gfc_add_block_to_block (&loop->pre, &se.pre);
1580           gfc_add_block_to_block (&loop->post, &se.post);
1581           ss->string_length = se.string_length;
1582           break;
1583
1584         case GFC_SS_CONSTRUCTOR:
1585           gfc_trans_array_constructor (loop, ss);
1586           break;
1587
1588         case GFC_SS_TEMP:
1589         case GFC_SS_COMPONENT:
1590           /* Do nothing.  These are handled elsewhere.  */
1591           break;
1592
1593         default:
1594           gcc_unreachable ();
1595         }
1596     }
1597 }
1598
1599
1600 /* Translate expressions for the descriptor and data pointer of a SS.  */
1601 /*GCC ARRAYS*/
1602
1603 static void
1604 gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
1605 {
1606   gfc_se se;
1607   tree tmp;
1608
1609   /* Get the descriptor for the array to be scalarized.  */
1610   gcc_assert (ss->expr->expr_type == EXPR_VARIABLE);
1611   gfc_init_se (&se, NULL);
1612   se.descriptor_only = 1;
1613   gfc_conv_expr_lhs (&se, ss->expr);
1614   gfc_add_block_to_block (block, &se.pre);
1615   ss->data.info.descriptor = se.expr;
1616   ss->string_length = se.string_length;
1617
1618   if (base)
1619     {
1620       /* Also the data pointer.  */
1621       tmp = gfc_conv_array_data (se.expr);
1622       /* If this is a variable or address of a variable we use it directly.
1623          Otherwise we must evaluate it now to avoid breaking dependency
1624          analysis by pulling the expressions for elemental array indices
1625          inside the loop.  */
1626       if (!(DECL_P (tmp)
1627             || (TREE_CODE (tmp) == ADDR_EXPR
1628                 && DECL_P (TREE_OPERAND (tmp, 0)))))
1629         tmp = gfc_evaluate_now (tmp, block);
1630       ss->data.info.data = tmp;
1631
1632       tmp = gfc_conv_array_offset (se.expr);
1633       ss->data.info.offset = gfc_evaluate_now (tmp, block);
1634     }
1635 }
1636
1637
1638 /* Initialize a gfc_loopinfo structure.  */
1639
1640 void
1641 gfc_init_loopinfo (gfc_loopinfo * loop)
1642 {
1643   int n;
1644
1645   memset (loop, 0, sizeof (gfc_loopinfo));
1646   gfc_init_block (&loop->pre);
1647   gfc_init_block (&loop->post);
1648
1649   /* Initially scalarize in order.  */
1650   for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
1651     loop->order[n] = n;
1652
1653   loop->ss = gfc_ss_terminator;
1654 }
1655
1656
1657 /* Copies the loop variable info to a gfc_se structure. Does not copy the SS
1658    chain.  */
1659
1660 void
1661 gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
1662 {
1663   se->loop = loop;
1664 }
1665
1666
1667 /* Return an expression for the data pointer of an array.  */
1668
1669 tree
1670 gfc_conv_array_data (tree descriptor)
1671 {
1672   tree type;
1673
1674   type = TREE_TYPE (descriptor);
1675   if (GFC_ARRAY_TYPE_P (type))
1676     {
1677       if (TREE_CODE (type) == POINTER_TYPE)
1678         return descriptor;
1679       else
1680         {
1681           /* Descriptorless arrays.  */
1682           return build_fold_addr_expr (descriptor);
1683         }
1684     }
1685   else
1686     return gfc_conv_descriptor_data_get (descriptor);
1687 }
1688
1689
1690 /* Return an expression for the base offset of an array.  */
1691
1692 tree
1693 gfc_conv_array_offset (tree descriptor)
1694 {
1695   tree type;
1696
1697   type = TREE_TYPE (descriptor);
1698   if (GFC_ARRAY_TYPE_P (type))
1699     return GFC_TYPE_ARRAY_OFFSET (type);
1700   else
1701     return gfc_conv_descriptor_offset (descriptor);
1702 }
1703
1704
1705 /* Get an expression for the array stride.  */
1706
1707 tree
1708 gfc_conv_array_stride (tree descriptor, int dim)
1709 {
1710   tree tmp;
1711   tree type;
1712
1713   type = TREE_TYPE (descriptor);
1714
1715   /* For descriptorless arrays use the array size.  */
1716   tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
1717   if (tmp != NULL_TREE)
1718     return tmp;
1719
1720   tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
1721   return tmp;
1722 }
1723
1724
1725 /* Like gfc_conv_array_stride, but for the lower bound.  */
1726
1727 tree
1728 gfc_conv_array_lbound (tree descriptor, int dim)
1729 {
1730   tree tmp;
1731   tree type;
1732
1733   type = TREE_TYPE (descriptor);
1734
1735   tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
1736   if (tmp != NULL_TREE)
1737     return tmp;
1738
1739   tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
1740   return tmp;
1741 }
1742
1743
1744 /* Like gfc_conv_array_stride, but for the upper bound.  */
1745
1746 tree
1747 gfc_conv_array_ubound (tree descriptor, int dim)
1748 {
1749   tree tmp;
1750   tree type;
1751
1752   type = TREE_TYPE (descriptor);
1753
1754   tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
1755   if (tmp != NULL_TREE)
1756     return tmp;
1757
1758   /* This should only ever happen when passing an assumed shape array
1759      as an actual parameter.  The value will never be used.  */
1760   if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
1761     return gfc_index_zero_node;
1762
1763   tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
1764   return tmp;
1765 }
1766
1767
1768 /* Generate code to perform an array index bound check.  */
1769
1770 static tree
1771 gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
1772 {
1773   tree cond;
1774   tree fault;
1775   tree tmp;
1776
1777   if (!flag_bounds_check)
1778     return index;
1779
1780   index = gfc_evaluate_now (index, &se->pre);
1781   /* Check lower bound.  */
1782   tmp = gfc_conv_array_lbound (descriptor, n);
1783   fault = fold_build2 (LT_EXPR, boolean_type_node, index, tmp);
1784   /* Check upper bound.  */
1785   tmp = gfc_conv_array_ubound (descriptor, n);
1786   cond = fold_build2 (GT_EXPR, boolean_type_node, index, tmp);
1787   fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1788
1789   gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1790
1791   return index;
1792 }
1793
1794
1795 /* Return the offset for an index.  Performs bound checking for elemental
1796    dimensions.  Single element references are processed separately.  */
1797
1798 static tree
1799 gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
1800                              gfc_array_ref * ar, tree stride)
1801 {
1802   tree index;
1803   tree desc;
1804   tree data;
1805
1806   /* Get the index into the array for this dimension.  */
1807   if (ar)
1808     {
1809       gcc_assert (ar->type != AR_ELEMENT);
1810       switch (ar->dimen_type[dim])
1811         {
1812         case DIMEN_ELEMENT:
1813           gcc_assert (i == -1);
1814           /* Elemental dimension.  */
1815           gcc_assert (info->subscript[dim]
1816                       && info->subscript[dim]->type == GFC_SS_SCALAR);
1817           /* We've already translated this value outside the loop.  */
1818           index = info->subscript[dim]->data.scalar.expr;
1819
1820           index =
1821             gfc_trans_array_bound_check (se, info->descriptor, index, dim);
1822           break;
1823
1824         case DIMEN_VECTOR:
1825           gcc_assert (info && se->loop);
1826           gcc_assert (info->subscript[dim]
1827                       && info->subscript[dim]->type == GFC_SS_VECTOR);
1828           desc = info->subscript[dim]->data.info.descriptor;
1829
1830           /* Get a zero-based index into the vector.  */
1831           index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1832                                se->loop->loopvar[i], se->loop->from[i]);
1833
1834           /* Multiply the index by the stride.  */
1835           index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1836                                index, gfc_conv_array_stride (desc, 0));
1837
1838           /* Read the vector to get an index into info->descriptor.  */
1839           data = build_fold_indirect_ref (gfc_conv_array_data (desc));
1840           index = gfc_build_array_ref (data, index);
1841           index = gfc_evaluate_now (index, &se->pre);
1842
1843           /* Do any bounds checking on the final info->descriptor index.  */
1844           index = gfc_trans_array_bound_check (se, info->descriptor,
1845                                                index, dim);
1846           break;
1847
1848         case DIMEN_RANGE:
1849           /* Scalarized dimension.  */
1850           gcc_assert (info && se->loop);
1851
1852           /* Multiply the loop variable by the stride and delta.  */
1853           index = se->loop->loopvar[i];
1854           index = fold_build2 (MULT_EXPR, gfc_array_index_type, index,
1855                                info->stride[i]);
1856           index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index,
1857                                info->delta[i]);
1858           break;
1859
1860         default:
1861           gcc_unreachable ();
1862         }
1863     }
1864   else
1865     {
1866       /* Temporary array or derived type component.  */
1867       gcc_assert (se->loop);
1868       index = se->loop->loopvar[se->loop->order[i]];
1869       if (!integer_zerop (info->delta[i]))
1870         index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1871                              index, info->delta[i]);
1872     }
1873
1874   /* Multiply by the stride.  */
1875   index = fold_build2 (MULT_EXPR, gfc_array_index_type, index, stride);
1876
1877   return index;
1878 }
1879
1880
1881 /* Build a scalarized reference to an array.  */
1882
1883 static void
1884 gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
1885 {
1886   gfc_ss_info *info;
1887   tree index;
1888   tree tmp;
1889   int n;
1890
1891   info = &se->ss->data.info;
1892   if (ar)
1893     n = se->loop->order[0];
1894   else
1895     n = 0;
1896
1897   index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
1898                                        info->stride0);
1899   /* Add the offset for this dimension to the stored offset for all other
1900      dimensions.  */
1901   index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, info->offset);
1902
1903   tmp = build_fold_indirect_ref (info->data);
1904   se->expr = gfc_build_array_ref (tmp, index);
1905 }
1906
1907
1908 /* Translate access of temporary array.  */
1909
1910 void
1911 gfc_conv_tmp_array_ref (gfc_se * se)
1912 {
1913   se->string_length = se->ss->string_length;
1914   gfc_conv_scalarized_array_ref (se, NULL);
1915 }
1916
1917
1918 /* Build an array reference.  se->expr already holds the array descriptor.
1919    This should be either a variable, indirect variable reference or component
1920    reference.  For arrays which do not have a descriptor, se->expr will be
1921    the data pointer.
1922    a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
1923
1924 void
1925 gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
1926 {
1927   int n;
1928   tree index;
1929   tree tmp;
1930   tree stride;
1931   tree fault;
1932   gfc_se indexse;
1933
1934   /* Handle scalarized references separately.  */
1935   if (ar->type != AR_ELEMENT)
1936     {
1937       gfc_conv_scalarized_array_ref (se, ar);
1938       gfc_advance_se_ss_chain (se);
1939       return;
1940     }
1941
1942   index = gfc_index_zero_node;
1943
1944   fault = gfc_index_zero_node;
1945
1946   /* Calculate the offsets from all the dimensions.  */
1947   for (n = 0; n < ar->dimen; n++)
1948     {
1949       /* Calculate the index for this dimension.  */
1950       gfc_init_se (&indexse, se);
1951       gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
1952       gfc_add_block_to_block (&se->pre, &indexse.pre);
1953
1954       if (flag_bounds_check)
1955         {
1956           /* Check array bounds.  */
1957           tree cond;
1958
1959           indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
1960
1961           tmp = gfc_conv_array_lbound (se->expr, n);
1962           cond = fold_build2 (LT_EXPR, boolean_type_node, 
1963                               indexse.expr, tmp);
1964           fault =
1965             fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1966
1967           tmp = gfc_conv_array_ubound (se->expr, n);
1968           cond = fold_build2 (GT_EXPR, boolean_type_node, 
1969                               indexse.expr, tmp);
1970           fault =
1971             fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault, cond);
1972         }
1973
1974       /* Multiply the index by the stride.  */
1975       stride = gfc_conv_array_stride (se->expr, n);
1976       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, indexse.expr,
1977                          stride);
1978
1979       /* And add it to the total.  */
1980       index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1981     }
1982
1983   if (flag_bounds_check)
1984     gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
1985
1986   tmp = gfc_conv_array_offset (se->expr);
1987   if (!integer_zerop (tmp))
1988     index = fold_build2 (PLUS_EXPR, gfc_array_index_type, index, tmp);
1989       
1990   /* Access the calculated element.  */
1991   tmp = gfc_conv_array_data (se->expr);
1992   tmp = build_fold_indirect_ref (tmp);
1993   se->expr = gfc_build_array_ref (tmp, index);
1994 }
1995
1996
1997 /* Generate the code to be executed immediately before entering a
1998    scalarization loop.  */
1999
2000 static void
2001 gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
2002                          stmtblock_t * pblock)
2003 {
2004   tree index;
2005   tree stride;
2006   gfc_ss_info *info;
2007   gfc_ss *ss;
2008   gfc_se se;
2009   int i;
2010
2011   /* This code will be executed before entering the scalarization loop
2012      for this dimension.  */
2013   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2014     {
2015       if ((ss->useflags & flag) == 0)
2016         continue;
2017
2018       if (ss->type != GFC_SS_SECTION
2019           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2020           && ss->type != GFC_SS_COMPONENT)
2021         continue;
2022
2023       info = &ss->data.info;
2024
2025       if (dim >= info->dimen)
2026         continue;
2027
2028       if (dim == info->dimen - 1)
2029         {
2030           /* For the outermost loop calculate the offset due to any
2031              elemental dimensions.  It will have been initialized with the
2032              base offset of the array.  */
2033           if (info->ref)
2034             {
2035               for (i = 0; i < info->ref->u.ar.dimen; i++)
2036                 {
2037                   if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2038                     continue;
2039
2040                   gfc_init_se (&se, NULL);
2041                   se.loop = loop;
2042                   se.expr = info->descriptor;
2043                   stride = gfc_conv_array_stride (info->descriptor, i);
2044                   index = gfc_conv_array_index_offset (&se, info, i, -1,
2045                                                        &info->ref->u.ar,
2046                                                        stride);
2047                   gfc_add_block_to_block (pblock, &se.pre);
2048
2049                   info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2050                                               info->offset, index);
2051                   info->offset = gfc_evaluate_now (info->offset, pblock);
2052                 }
2053
2054               i = loop->order[0];
2055               stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2056             }
2057           else
2058             stride = gfc_conv_array_stride (info->descriptor, 0);
2059
2060           /* Calculate the stride of the innermost loop.  Hopefully this will
2061              allow the backend optimizers to do their stuff more effectively.
2062            */
2063           info->stride0 = gfc_evaluate_now (stride, pblock);
2064         }
2065       else
2066         {
2067           /* Add the offset for the previous loop dimension.  */
2068           gfc_array_ref *ar;
2069
2070           if (info->ref)
2071             {
2072               ar = &info->ref->u.ar;
2073               i = loop->order[dim + 1];
2074             }
2075           else
2076             {
2077               ar = NULL;
2078               i = dim + 1;
2079             }
2080
2081           gfc_init_se (&se, NULL);
2082           se.loop = loop;
2083           se.expr = info->descriptor;
2084           stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
2085           index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
2086                                                ar, stride);
2087           gfc_add_block_to_block (pblock, &se.pre);
2088           info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2089                                       info->offset, index);
2090           info->offset = gfc_evaluate_now (info->offset, pblock);
2091         }
2092
2093       /* Remember this offset for the second loop.  */
2094       if (dim == loop->temp_dim - 1)
2095         info->saved_offset = info->offset;
2096     }
2097 }
2098
2099
2100 /* Start a scalarized expression.  Creates a scope and declares loop
2101    variables.  */
2102
2103 void
2104 gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
2105 {
2106   int dim;
2107   int n;
2108   int flags;
2109
2110   gcc_assert (!loop->array_parameter);
2111
2112   for (dim = loop->dimen - 1; dim >= 0; dim--)
2113     {
2114       n = loop->order[dim];
2115
2116       gfc_start_block (&loop->code[n]);
2117
2118       /* Create the loop variable.  */
2119       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
2120
2121       if (dim < loop->temp_dim)
2122         flags = 3;
2123       else
2124         flags = 1;
2125       /* Calculate values that will be constant within this loop.  */
2126       gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
2127     }
2128   gfc_start_block (pbody);
2129 }
2130
2131
2132 /* Generates the actual loop code for a scalarization loop.  */
2133
2134 static void
2135 gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
2136                                stmtblock_t * pbody)
2137 {
2138   stmtblock_t block;
2139   tree cond;
2140   tree tmp;
2141   tree loopbody;
2142   tree exit_label;
2143
2144   loopbody = gfc_finish_block (pbody);
2145
2146   /* Initialize the loopvar.  */
2147   gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
2148
2149   exit_label = gfc_build_label_decl (NULL_TREE);
2150
2151   /* Generate the loop body.  */
2152   gfc_init_block (&block);
2153
2154   /* The exit condition.  */
2155   cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
2156   tmp = build1_v (GOTO_EXPR, exit_label);
2157   TREE_USED (exit_label) = 1;
2158   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2159   gfc_add_expr_to_block (&block, tmp);
2160
2161   /* The main body.  */
2162   gfc_add_expr_to_block (&block, loopbody);
2163
2164   /* Increment the loopvar.  */
2165   tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2166                 loop->loopvar[n], gfc_index_one_node);
2167   gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
2168
2169   /* Build the loop.  */
2170   tmp = gfc_finish_block (&block);
2171   tmp = build1_v (LOOP_EXPR, tmp);
2172   gfc_add_expr_to_block (&loop->code[n], tmp);
2173
2174   /* Add the exit label.  */
2175   tmp = build1_v (LABEL_EXPR, exit_label);
2176   gfc_add_expr_to_block (&loop->code[n], tmp);
2177 }
2178
2179
2180 /* Finishes and generates the loops for a scalarized expression.  */
2181
2182 void
2183 gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
2184 {
2185   int dim;
2186   int n;
2187   gfc_ss *ss;
2188   stmtblock_t *pblock;
2189   tree tmp;
2190
2191   pblock = body;
2192   /* Generate the loops.  */
2193   for (dim = 0; dim < loop->dimen; dim++)
2194     {
2195       n = loop->order[dim];
2196       gfc_trans_scalarized_loop_end (loop, n, pblock);
2197       loop->loopvar[n] = NULL_TREE;
2198       pblock = &loop->code[n];
2199     }
2200
2201   tmp = gfc_finish_block (pblock);
2202   gfc_add_expr_to_block (&loop->pre, tmp);
2203
2204   /* Clear all the used flags.  */
2205   for (ss = loop->ss; ss; ss = ss->loop_chain)
2206     ss->useflags = 0;
2207 }
2208
2209
2210 /* Finish the main body of a scalarized expression, and start the secondary
2211    copying body.  */
2212
2213 void
2214 gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
2215 {
2216   int dim;
2217   int n;
2218   stmtblock_t *pblock;
2219   gfc_ss *ss;
2220
2221   pblock = body;
2222   /* We finish as many loops as are used by the temporary.  */
2223   for (dim = 0; dim < loop->temp_dim - 1; dim++)
2224     {
2225       n = loop->order[dim];
2226       gfc_trans_scalarized_loop_end (loop, n, pblock);
2227       loop->loopvar[n] = NULL_TREE;
2228       pblock = &loop->code[n];
2229     }
2230
2231   /* We don't want to finish the outermost loop entirely.  */
2232   n = loop->order[loop->temp_dim - 1];
2233   gfc_trans_scalarized_loop_end (loop, n, pblock);
2234
2235   /* Restore the initial offsets.  */
2236   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2237     {
2238       if ((ss->useflags & 2) == 0)
2239         continue;
2240
2241       if (ss->type != GFC_SS_SECTION
2242           && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR
2243           && ss->type != GFC_SS_COMPONENT)
2244         continue;
2245
2246       ss->data.info.offset = ss->data.info.saved_offset;
2247     }
2248
2249   /* Restart all the inner loops we just finished.  */
2250   for (dim = loop->temp_dim - 2; dim >= 0; dim--)
2251     {
2252       n = loop->order[dim];
2253
2254       gfc_start_block (&loop->code[n]);
2255
2256       loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
2257
2258       gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
2259     }
2260
2261   /* Start a block for the secondary copying code.  */
2262   gfc_start_block (body);
2263 }
2264
2265
2266 /* Calculate the upper bound of an array section.  */
2267
2268 static tree
2269 gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
2270 {
2271   int dim;
2272   gfc_expr *end;
2273   tree desc;
2274   tree bound;
2275   gfc_se se;
2276   gfc_ss_info *info;
2277
2278   gcc_assert (ss->type == GFC_SS_SECTION);
2279
2280   info = &ss->data.info;
2281   dim = info->dim[n];
2282
2283   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2284     /* We'll calculate the upper bound once we have access to the
2285        vector's descriptor.  */
2286     return NULL;
2287
2288   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2289   desc = info->descriptor;
2290   end = info->ref->u.ar.end[dim];
2291
2292   if (end)
2293     {
2294       /* The upper bound was specified.  */
2295       gfc_init_se (&se, NULL);
2296       gfc_conv_expr_type (&se, end, gfc_array_index_type);
2297       gfc_add_block_to_block (pblock, &se.pre);
2298       bound = se.expr;
2299     }
2300   else
2301     {
2302       /* No upper bound was specified, so use the bound of the array.  */
2303       bound = gfc_conv_array_ubound (desc, dim);
2304     }
2305
2306   return bound;
2307 }
2308
2309
2310 /* Calculate the lower bound of an array section.  */
2311
2312 static void
2313 gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
2314 {
2315   gfc_expr *start;
2316   gfc_expr *stride;
2317   tree desc;
2318   gfc_se se;
2319   gfc_ss_info *info;
2320   int dim;
2321
2322   gcc_assert (ss->type == GFC_SS_SECTION);
2323
2324   info = &ss->data.info;
2325   dim = info->dim[n];
2326
2327   if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2328     {
2329       /* We use a zero-based index to access the vector.  */
2330       info->start[n] = gfc_index_zero_node;
2331       info->stride[n] = gfc_index_one_node;
2332       return;
2333     }
2334
2335   gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
2336   desc = info->descriptor;
2337   start = info->ref->u.ar.start[dim];
2338   stride = info->ref->u.ar.stride[dim];
2339
2340   /* Calculate the start of the range.  For vector subscripts this will
2341      be the range of the vector.  */
2342   if (start)
2343     {
2344       /* Specified section start.  */
2345       gfc_init_se (&se, NULL);
2346       gfc_conv_expr_type (&se, start, gfc_array_index_type);
2347       gfc_add_block_to_block (&loop->pre, &se.pre);
2348       info->start[n] = se.expr;
2349     }
2350   else
2351     {
2352       /* No lower bound specified so use the bound of the array.  */
2353       info->start[n] = gfc_conv_array_lbound (desc, dim);
2354     }
2355   info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
2356
2357   /* Calculate the stride.  */
2358   if (stride == NULL)
2359     info->stride[n] = gfc_index_one_node;
2360   else
2361     {
2362       gfc_init_se (&se, NULL);
2363       gfc_conv_expr_type (&se, stride, gfc_array_index_type);
2364       gfc_add_block_to_block (&loop->pre, &se.pre);
2365       info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
2366     }
2367 }
2368
2369
2370 /* Calculates the range start and stride for a SS chain.  Also gets the
2371    descriptor and data pointer.  The range of vector subscripts is the size
2372    of the vector.  Array bounds are also checked.  */
2373
2374 void
2375 gfc_conv_ss_startstride (gfc_loopinfo * loop)
2376 {
2377   int n;
2378   tree tmp;
2379   gfc_ss *ss;
2380   tree desc;
2381
2382   loop->dimen = 0;
2383   /* Determine the rank of the loop.  */
2384   for (ss = loop->ss;
2385        ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
2386     {
2387       switch (ss->type)
2388         {
2389         case GFC_SS_SECTION:
2390         case GFC_SS_CONSTRUCTOR:
2391         case GFC_SS_FUNCTION:
2392         case GFC_SS_COMPONENT:
2393           loop->dimen = ss->data.info.dimen;
2394           break;
2395
2396         default:
2397           break;
2398         }
2399     }
2400
2401   if (loop->dimen == 0)
2402     gfc_todo_error ("Unable to determine rank of expression");
2403
2404
2405   /* Loop over all the SS in the chain.  */
2406   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2407     {
2408       if (ss->expr && ss->expr->shape && !ss->shape)
2409         ss->shape = ss->expr->shape;
2410
2411       switch (ss->type)
2412         {
2413         case GFC_SS_SECTION:
2414           /* Get the descriptor for the array.  */
2415           gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
2416
2417           for (n = 0; n < ss->data.info.dimen; n++)
2418             gfc_conv_section_startstride (loop, ss, n);
2419           break;
2420
2421         case GFC_SS_CONSTRUCTOR:
2422         case GFC_SS_FUNCTION:
2423           for (n = 0; n < ss->data.info.dimen; n++)
2424             {
2425               ss->data.info.start[n] = gfc_index_zero_node;
2426               ss->data.info.stride[n] = gfc_index_one_node;
2427             }
2428           break;
2429
2430         default:
2431           break;
2432         }
2433     }
2434
2435   /* The rest is just runtime bound checking.  */
2436   if (flag_bounds_check)
2437     {
2438       stmtblock_t block;
2439       tree fault;
2440       tree bound;
2441       tree end;
2442       tree size[GFC_MAX_DIMENSIONS];
2443       gfc_ss_info *info;
2444       int dim;
2445
2446       gfc_start_block (&block);
2447
2448       fault = integer_zero_node;
2449       for (n = 0; n < loop->dimen; n++)
2450         size[n] = NULL_TREE;
2451
2452       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2453         {
2454           if (ss->type != GFC_SS_SECTION)
2455             continue;
2456
2457           /* TODO: range checking for mapped dimensions.  */
2458           info = &ss->data.info;
2459
2460           /* This code only checks ranges.  Elemental and vector
2461              dimensions are checked later.  */
2462           for (n = 0; n < loop->dimen; n++)
2463             {
2464               dim = info->dim[n];
2465               if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
2466                 continue;
2467
2468               desc = ss->data.info.descriptor;
2469
2470               /* Check lower bound.  */
2471               bound = gfc_conv_array_lbound (desc, dim);
2472               tmp = info->start[n];
2473               tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);
2474               fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2475                                    tmp);
2476
2477               /* Check the upper bound.  */
2478               bound = gfc_conv_array_ubound (desc, dim);
2479               end = gfc_conv_section_upper_bound (ss, n, &block);
2480               tmp = fold_build2 (GT_EXPR, boolean_type_node, end, bound);
2481               fault = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, fault,
2482                                    tmp);
2483
2484               /* Check the section sizes match.  */
2485               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, end,
2486                                  info->start[n]);
2487               tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
2488                                  info->stride[n]);
2489               /* We remember the size of the first section, and check all the
2490                  others against this.  */
2491               if (size[n])
2492                 {
2493                   tmp =
2494                     fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]);
2495                   fault =
2496                     build2 (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
2497                 }
2498               else
2499                 size[n] = gfc_evaluate_now (tmp, &block);
2500             }
2501         }
2502       gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
2503
2504       tmp = gfc_finish_block (&block);
2505       gfc_add_expr_to_block (&loop->pre, tmp);
2506     }
2507 }
2508
2509
2510 /* Return true if the two SS could be aliased, i.e. both point to the same data
2511    object.  */
2512 /* TODO: resolve aliases based on frontend expressions.  */
2513
2514 static int
2515 gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
2516 {
2517   gfc_ref *lref;
2518   gfc_ref *rref;
2519   gfc_symbol *lsym;
2520   gfc_symbol *rsym;
2521
2522   lsym = lss->expr->symtree->n.sym;
2523   rsym = rss->expr->symtree->n.sym;
2524   if (gfc_symbols_could_alias (lsym, rsym))
2525     return 1;
2526
2527   if (rsym->ts.type != BT_DERIVED
2528       && lsym->ts.type != BT_DERIVED)
2529     return 0;
2530
2531   /* For derived types we must check all the component types.  We can ignore
2532      array references as these will have the same base type as the previous
2533      component ref.  */
2534   for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
2535     {
2536       if (lref->type != REF_COMPONENT)
2537         continue;
2538
2539       if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
2540         return 1;
2541
2542       for (rref = rss->expr->ref; rref != rss->data.info.ref;
2543            rref = rref->next)
2544         {
2545           if (rref->type != REF_COMPONENT)
2546             continue;
2547
2548           if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
2549             return 1;
2550         }
2551     }
2552
2553   for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
2554     {
2555       if (rref->type != REF_COMPONENT)
2556         break;
2557
2558       if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
2559         return 1;
2560     }
2561
2562   return 0;
2563 }
2564
2565
2566 /* Resolve array data dependencies.  Creates a temporary if required.  */
2567 /* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
2568    dependency.c.  */
2569
2570 void
2571 gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
2572                                gfc_ss * rss)
2573 {
2574   gfc_ss *ss;
2575   gfc_ref *lref;
2576   gfc_ref *rref;
2577   gfc_ref *aref;
2578   int nDepend = 0;
2579   int temp_dim = 0;
2580
2581   loop->temp_ss = NULL;
2582   aref = dest->data.info.ref;
2583   temp_dim = 0;
2584
2585   for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
2586     {
2587       if (ss->type != GFC_SS_SECTION)
2588         continue;
2589
2590       if (gfc_could_be_alias (dest, ss)
2591             || gfc_are_equivalenced_arrays (dest->expr, ss->expr))
2592         {
2593           nDepend = 1;
2594           break;
2595         }
2596
2597       if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
2598         {
2599           lref = dest->expr->ref;
2600           rref = ss->expr->ref;
2601
2602           nDepend = gfc_dep_resolver (lref, rref);
2603 #if 0
2604           /* TODO : loop shifting.  */
2605           if (nDepend == 1)
2606             {
2607               /* Mark the dimensions for LOOP SHIFTING */
2608               for (n = 0; n < loop->dimen; n++)
2609                 {
2610                   int dim = dest->data.info.dim[n];
2611
2612                   if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
2613                     depends[n] = 2;
2614                   else if (! gfc_is_same_range (&lref->u.ar,
2615                                                 &rref->u.ar, dim, 0))
2616                     depends[n] = 1;
2617                  }
2618
2619               /* Put all the dimensions with dependencies in the
2620                  innermost loops.  */
2621               dim = 0;
2622               for (n = 0; n < loop->dimen; n++)
2623                 {
2624                   gcc_assert (loop->order[n] == n);
2625                   if (depends[n])
2626                   loop->order[dim++] = n;
2627                 }
2628               temp_dim = dim;
2629               for (n = 0; n < loop->dimen; n++)
2630                 {
2631                   if (! depends[n])
2632                   loop->order[dim++] = n;
2633                 }
2634
2635               gcc_assert (dim == loop->dimen);
2636               break;
2637             }
2638 #endif
2639         }
2640     }
2641
2642   if (nDepend == 1)
2643     {
2644       tree base_type = gfc_typenode_for_spec (&dest->expr->ts);
2645       if (GFC_ARRAY_TYPE_P (base_type)
2646           || GFC_DESCRIPTOR_TYPE_P (base_type))
2647         base_type = gfc_get_element_type (base_type);
2648       loop->temp_ss = gfc_get_ss ();
2649       loop->temp_ss->type = GFC_SS_TEMP;
2650       loop->temp_ss->data.temp.type = base_type;
2651       loop->temp_ss->string_length = dest->string_length;
2652       loop->temp_ss->data.temp.dimen = loop->dimen;
2653       loop->temp_ss->next = gfc_ss_terminator;
2654       gfc_add_ss_to_loop (loop, loop->temp_ss);
2655     }
2656   else
2657     loop->temp_ss = NULL;
2658 }
2659
2660
2661 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
2662    the range of the loop variables.  Creates a temporary if required.
2663    Calculates how to transform from loop variables to array indices for each
2664    expression.  Also generates code for scalar expressions which have been
2665    moved outside the loop.  */
2666
2667 void
2668 gfc_conv_loop_setup (gfc_loopinfo * loop)
2669 {
2670   int n;
2671   int dim;
2672   gfc_ss_info *info;
2673   gfc_ss_info *specinfo;
2674   gfc_ss *ss;
2675   tree tmp;
2676   tree len;
2677   gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
2678   bool dynamic[GFC_MAX_DIMENSIONS];
2679   gfc_constructor *c;
2680   mpz_t *cshape;
2681   mpz_t i;
2682
2683   mpz_init (i);
2684   for (n = 0; n < loop->dimen; n++)
2685     {
2686       loopspec[n] = NULL;
2687       dynamic[n] = false;
2688       /* We use one SS term, and use that to determine the bounds of the
2689          loop for this dimension.  We try to pick the simplest term.  */
2690       for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2691         {
2692           if (ss->shape)
2693             {
2694               /* The frontend has worked out the size for us.  */
2695               loopspec[n] = ss;
2696               continue;
2697             }
2698
2699           if (ss->type == GFC_SS_CONSTRUCTOR)
2700             {
2701               /* An unknown size constructor will always be rank one.
2702                  Higher rank constructors will either have known shape,
2703                  or still be wrapped in a call to reshape.  */
2704               gcc_assert (loop->dimen == 1);
2705
2706               /* Always prefer to use the constructor bounds if the size
2707                  can be determined at compile time.  Prefer not to otherwise,
2708                  since the general case involves realloc, and it's better to
2709                  avoid that overhead if possible.  */
2710               c = ss->expr->value.constructor;
2711               dynamic[n] = gfc_get_array_constructor_size (&i, c);
2712               if (!dynamic[n] || !loopspec[n])
2713                 loopspec[n] = ss;
2714               continue;
2715             }
2716
2717           /* TODO: Pick the best bound if we have a choice between a
2718              function and something else.  */
2719           if (ss->type == GFC_SS_FUNCTION)
2720             {
2721               loopspec[n] = ss;
2722               continue;
2723             }
2724
2725           if (ss->type != GFC_SS_SECTION)
2726             continue;
2727
2728           if (loopspec[n])
2729             specinfo = &loopspec[n]->data.info;
2730           else
2731             specinfo = NULL;
2732           info = &ss->data.info;
2733
2734           if (!specinfo)
2735             loopspec[n] = ss;
2736           /* Criteria for choosing a loop specifier (most important first):
2737              doesn't need realloc
2738              stride of one
2739              known stride
2740              known lower bound
2741              known upper bound
2742            */
2743           else if (loopspec[n]->type == GFC_SS_CONSTRUCTOR && dynamic[n])
2744             loopspec[n] = ss;
2745           else if (integer_onep (info->stride[n])
2746                    && !integer_onep (specinfo->stride[n]))
2747             loopspec[n] = ss;
2748           else if (INTEGER_CST_P (info->stride[n])
2749                    && !INTEGER_CST_P (specinfo->stride[n]))
2750             loopspec[n] = ss;
2751           else if (INTEGER_CST_P (info->start[n])
2752                    && !INTEGER_CST_P (specinfo->start[n]))
2753             loopspec[n] = ss;
2754           /* We don't work out the upper bound.
2755              else if (INTEGER_CST_P (info->finish[n])
2756              && ! INTEGER_CST_P (specinfo->finish[n]))
2757              loopspec[n] = ss; */
2758         }
2759
2760       if (!loopspec[n])
2761         gfc_todo_error ("Unable to find scalarization loop specifier");
2762
2763       info = &loopspec[n]->data.info;
2764
2765       /* Set the extents of this range.  */
2766       cshape = loopspec[n]->shape;
2767       if (cshape && INTEGER_CST_P (info->start[n])
2768           && INTEGER_CST_P (info->stride[n]))
2769         {
2770           loop->from[n] = info->start[n];
2771           mpz_set (i, cshape[n]);
2772           mpz_sub_ui (i, i, 1);
2773           /* To = from + (size - 1) * stride.  */
2774           tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
2775           if (!integer_onep (info->stride[n]))
2776             tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2777                                tmp, info->stride[n]);
2778           loop->to[n] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2779                                      loop->from[n], tmp);
2780         }
2781       else
2782         {
2783           loop->from[n] = info->start[n];
2784           switch (loopspec[n]->type)
2785             {
2786             case GFC_SS_CONSTRUCTOR:
2787               /* The upper bound is calculated when we expand the
2788                  constructor.  */
2789               gcc_assert (loop->to[n] == NULL_TREE);
2790               break;
2791
2792             case GFC_SS_SECTION:
2793               loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
2794                                                           &loop->pre);
2795               break;
2796
2797             case GFC_SS_FUNCTION:
2798               /* The loop bound will be set when we generate the call.  */
2799               gcc_assert (loop->to[n] == NULL_TREE);
2800               break;
2801
2802             default:
2803               gcc_unreachable ();
2804             }
2805         }
2806
2807       /* Transform everything so we have a simple incrementing variable.  */
2808       if (integer_onep (info->stride[n]))
2809         info->delta[n] = gfc_index_zero_node;
2810       else
2811         {
2812           /* Set the delta for this section.  */
2813           info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
2814           /* Number of iterations is (end - start + step) / step.
2815              with start = 0, this simplifies to
2816              last = end / step;
2817              for (i = 0; i<=last; i++){...};  */
2818           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2819                              loop->to[n], loop->from[n]);
2820           tmp = fold_build2 (TRUNC_DIV_EXPR, gfc_array_index_type, 
2821                              tmp, info->stride[n]);
2822           loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
2823           /* Make the loop variable start at 0.  */
2824           loop->from[n] = gfc_index_zero_node;
2825         }
2826     }
2827
2828   /* Add all the scalar code that can be taken out of the loops.
2829      This may include calculating the loop bounds, so do it before
2830      allocating the temporary.  */
2831   gfc_add_loop_ss_code (loop, loop->ss, false);
2832
2833   /* If we want a temporary then create it.  */
2834   if (loop->temp_ss != NULL)
2835     {
2836       gcc_assert (loop->temp_ss->type == GFC_SS_TEMP);
2837       tmp = loop->temp_ss->data.temp.type;
2838       len = loop->temp_ss->string_length;
2839       n = loop->temp_ss->data.temp.dimen;
2840       memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
2841       loop->temp_ss->type = GFC_SS_SECTION;
2842       loop->temp_ss->data.info.dimen = n;
2843       gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
2844                                    &loop->temp_ss->data.info, tmp, false, true,
2845                                    false);
2846     }
2847
2848   for (n = 0; n < loop->temp_dim; n++)
2849     loopspec[loop->order[n]] = NULL;
2850
2851   mpz_clear (i);
2852
2853   /* For array parameters we don't have loop variables, so don't calculate the
2854      translations.  */
2855   if (loop->array_parameter)
2856     return;
2857
2858   /* Calculate the translation from loop variables to array indices.  */
2859   for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
2860     {
2861       if (ss->type != GFC_SS_SECTION && ss->type != GFC_SS_COMPONENT)
2862         continue;
2863
2864       info = &ss->data.info;
2865
2866       for (n = 0; n < info->dimen; n++)
2867         {
2868           dim = info->dim[n];
2869
2870           /* If we are specifying the range the delta is already set.  */
2871           if (loopspec[n] != ss)
2872             {
2873               /* Calculate the offset relative to the loop variable.
2874                  First multiply by the stride.  */
2875               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2876                                  loop->from[n], info->stride[n]);
2877
2878               /* Then subtract this from our starting value.  */
2879               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2880                                  info->start[n], tmp);
2881
2882               info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
2883             }
2884         }
2885     }
2886 }
2887
2888
2889 /* Fills in an array descriptor, and returns the size of the array.  The size
2890    will be a simple_val, ie a variable or a constant.  Also calculates the
2891    offset of the base.  Returns the size of the array.
2892    {
2893     stride = 1;
2894     offset = 0;
2895     for (n = 0; n < rank; n++)
2896       {
2897         a.lbound[n] = specified_lower_bound;
2898         offset = offset + a.lbond[n] * stride;
2899         size = 1 - lbound;
2900         a.ubound[n] = specified_upper_bound;
2901         a.stride[n] = stride;
2902         size = ubound + size; //size = ubound + 1 - lbound
2903         stride = stride * size;
2904       }
2905     return (stride);
2906    }  */
2907 /*GCC ARRAYS*/
2908
2909 static tree
2910 gfc_array_init_size (tree descriptor, int rank, tree * poffset,
2911                      gfc_expr ** lower, gfc_expr ** upper,
2912                      stmtblock_t * pblock)
2913 {
2914   tree type;
2915   tree tmp;
2916   tree size;
2917   tree offset;
2918   tree stride;
2919   gfc_expr *ubound;
2920   gfc_se se;
2921   int n;
2922
2923   type = TREE_TYPE (descriptor);
2924
2925   stride = gfc_index_one_node;
2926   offset = gfc_index_zero_node;
2927
2928   /* Set the dtype.  */
2929   tmp = gfc_conv_descriptor_dtype (descriptor);
2930   gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
2931
2932   for (n = 0; n < rank; n++)
2933     {
2934       /* We have 3 possibilities for determining the size of the array:
2935          lower == NULL    => lbound = 1, ubound = upper[n]
2936          upper[n] = NULL  => lbound = 1, ubound = lower[n]
2937          upper[n] != NULL => lbound = lower[n], ubound = upper[n]  */
2938       ubound = upper[n];
2939
2940       /* Set lower bound.  */
2941       gfc_init_se (&se, NULL);
2942       if (lower == NULL)
2943         se.expr = gfc_index_one_node;
2944       else
2945         {
2946           gcc_assert (lower[n]);
2947           if (ubound)
2948             {
2949               gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
2950               gfc_add_block_to_block (pblock, &se.pre);
2951             }
2952           else
2953             {
2954               se.expr = gfc_index_one_node;
2955               ubound = lower[n];
2956             }
2957         }
2958       tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
2959       gfc_add_modify_expr (pblock, tmp, se.expr);
2960
2961       /* Work out the offset for this component.  */
2962       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
2963       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
2964
2965       /* Start the calculation for the size of this dimension.  */
2966       size = build2 (MINUS_EXPR, gfc_array_index_type,
2967                      gfc_index_one_node, se.expr);
2968
2969       /* Set upper bound.  */
2970       gfc_init_se (&se, NULL);
2971       gcc_assert (ubound);
2972       gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
2973       gfc_add_block_to_block (pblock, &se.pre);
2974
2975       tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
2976       gfc_add_modify_expr (pblock, tmp, se.expr);
2977
2978       /* Store the stride.  */
2979       tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
2980       gfc_add_modify_expr (pblock, tmp, stride);
2981
2982       /* Calculate the size of this dimension.  */
2983       size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
2984
2985       /* Multiply the stride by the number of elements in this dimension.  */
2986       stride = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, size);
2987       stride = gfc_evaluate_now (stride, pblock);
2988     }
2989
2990   /* The stride is the number of elements in the array, so multiply by the
2991      size of an element to get the total size.  */
2992   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2993   size = fold_build2 (MULT_EXPR, gfc_array_index_type, stride, tmp);
2994
2995   if (poffset != NULL)
2996     {
2997       offset = gfc_evaluate_now (offset, pblock);
2998       *poffset = offset;
2999     }
3000
3001   size = gfc_evaluate_now (size, pblock);
3002   return size;
3003 }
3004
3005
3006 /* Initializes the descriptor and generates a call to _gfor_allocate.  Does
3007    the work for an ALLOCATE statement.  */
3008 /*GCC ARRAYS*/
3009
3010 bool
3011 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
3012 {
3013   tree tmp;
3014   tree pointer;
3015   tree allocate;
3016   tree offset;
3017   tree size;
3018   gfc_expr **lower;
3019   gfc_expr **upper;
3020   gfc_ref *ref;
3021   int allocatable_array;
3022
3023   ref = expr->ref;
3024
3025   /* Find the last reference in the chain.  */
3026   while (ref && ref->next != NULL)
3027     {
3028       gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3029       ref = ref->next;
3030     }
3031
3032   if (ref == NULL || ref->type != REF_ARRAY)
3033     return false;
3034
3035   /* Figure out the size of the array.  */
3036   switch (ref->u.ar.type)
3037     {
3038     case AR_ELEMENT:
3039       lower = NULL;
3040       upper = ref->u.ar.start;
3041       break;
3042
3043     case AR_FULL:
3044       gcc_assert (ref->u.ar.as->type == AS_EXPLICIT);
3045
3046       lower = ref->u.ar.as->lower;
3047       upper = ref->u.ar.as->upper;
3048       break;
3049
3050     case AR_SECTION:
3051       lower = ref->u.ar.start;
3052       upper = ref->u.ar.end;
3053       break;
3054
3055     default:
3056       gcc_unreachable ();
3057       break;
3058     }
3059
3060   size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
3061                               lower, upper, &se->pre);
3062
3063   /* Allocate memory to store the data.  */
3064   tmp = gfc_conv_descriptor_data_addr (se->expr);
3065   pointer = gfc_evaluate_now (tmp, &se->pre);
3066
3067   allocatable_array = expr->symtree->n.sym->attr.allocatable;
3068
3069   if (TYPE_PRECISION (gfc_array_index_type) == 32)
3070     {
3071       if (allocatable_array)
3072         allocate = gfor_fndecl_allocate_array;
3073       else
3074         allocate = gfor_fndecl_allocate;
3075     }
3076   else if (TYPE_PRECISION (gfc_array_index_type) == 64)
3077     {
3078       if (allocatable_array)
3079         allocate = gfor_fndecl_allocate64_array;
3080       else
3081         allocate = gfor_fndecl_allocate64;
3082     }
3083   else
3084     gcc_unreachable ();
3085
3086   tmp = gfc_chainon_list (NULL_TREE, pointer);
3087   tmp = gfc_chainon_list (tmp, size);
3088   tmp = gfc_chainon_list (tmp, pstat);
3089   tmp = build_function_call_expr (allocate, tmp);
3090   gfc_add_expr_to_block (&se->pre, tmp);
3091
3092   tmp = gfc_conv_descriptor_offset (se->expr);
3093   gfc_add_modify_expr (&se->pre, tmp, offset);
3094
3095   return true;
3096 }
3097
3098
3099 /* Deallocate an array variable.  Also used when an allocated variable goes
3100    out of scope.  */
3101 /*GCC ARRAYS*/
3102
3103 tree
3104 gfc_array_deallocate (tree descriptor, tree pstat)
3105 {
3106   tree var;
3107   tree tmp;
3108   stmtblock_t block;
3109
3110   gfc_start_block (&block);
3111   /* Get a pointer to the data.  */
3112   tmp = gfc_conv_descriptor_data_addr (descriptor);
3113   var = gfc_evaluate_now (tmp, &block);
3114
3115   /* Parameter is the address of the data component.  */
3116   tmp = gfc_chainon_list (NULL_TREE, var);
3117   tmp = gfc_chainon_list (tmp, pstat);
3118   tmp = build_function_call_expr (gfor_fndecl_deallocate, tmp);
3119   gfc_add_expr_to_block (&block, tmp);
3120
3121   return gfc_finish_block (&block);
3122 }
3123
3124
3125 /* Create an array constructor from an initialization expression.
3126    We assume the frontend already did any expansions and conversions.  */
3127
3128 tree
3129 gfc_conv_array_initializer (tree type, gfc_expr * expr)
3130 {
3131   gfc_constructor *c;
3132   tree tmp;
3133   mpz_t maxval;
3134   gfc_se se;
3135   HOST_WIDE_INT hi;
3136   unsigned HOST_WIDE_INT lo;
3137   tree index, range;
3138   VEC(constructor_elt,gc) *v = NULL;
3139
3140   switch (expr->expr_type)
3141     {
3142     case EXPR_CONSTANT:
3143     case EXPR_STRUCTURE:
3144       /* A single scalar or derived type value.  Create an array with all
3145          elements equal to that value.  */
3146       gfc_init_se (&se, NULL);
3147       
3148       if (expr->expr_type == EXPR_CONSTANT)
3149         gfc_conv_constant (&se, expr);
3150       else
3151         gfc_conv_structure (&se, expr, 1);
3152
3153       tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
3154       gcc_assert (tmp && INTEGER_CST_P (tmp));
3155       hi = TREE_INT_CST_HIGH (tmp);
3156       lo = TREE_INT_CST_LOW (tmp);
3157       lo++;
3158       if (lo == 0)
3159         hi++;
3160       /* This will probably eat buckets of memory for large arrays.  */
3161       while (hi != 0 || lo != 0)
3162         {
3163           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
3164           if (lo == 0)
3165             hi--;
3166           lo--;
3167         }
3168       break;
3169
3170     case EXPR_ARRAY:
3171       /* Create a vector of all the elements.  */
3172       for (c = expr->value.constructor; c; c = c->next)
3173         {
3174           if (c->iterator)
3175             {
3176               /* Problems occur when we get something like
3177                  integer :: a(lots) = (/(i, i=1,lots)/)  */
3178               /* TODO: Unexpanded array initializers.  */
3179               internal_error
3180                 ("Possible frontend bug: array constructor not expanded");
3181             }
3182           if (mpz_cmp_si (c->n.offset, 0) != 0)
3183             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3184           else
3185             index = NULL_TREE;
3186           mpz_init (maxval);
3187           if (mpz_cmp_si (c->repeat, 0) != 0)
3188             {
3189               tree tmp1, tmp2;
3190
3191               mpz_set (maxval, c->repeat);
3192               mpz_add (maxval, c->n.offset, maxval);
3193               mpz_sub_ui (maxval, maxval, 1);
3194               tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3195               if (mpz_cmp_si (c->n.offset, 0) != 0)
3196                 {
3197                   mpz_add_ui (maxval, c->n.offset, 1);
3198                   tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
3199                 }
3200               else
3201                 tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
3202
3203               range = build2 (RANGE_EXPR, integer_type_node, tmp1, tmp2);
3204             }
3205           else
3206             range = NULL;
3207           mpz_clear (maxval);
3208
3209           gfc_init_se (&se, NULL);
3210           switch (c->expr->expr_type)
3211             {
3212             case EXPR_CONSTANT:
3213               gfc_conv_constant (&se, c->expr);
3214               if (range == NULL_TREE)
3215                 CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3216               else
3217                 {
3218                   if (index != NULL_TREE)
3219                     CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3220                   CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
3221                 }
3222               break;
3223
3224             case EXPR_STRUCTURE:
3225               gfc_conv_structure (&se, c->expr, 1);
3226               CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
3227               break;
3228
3229             default:
3230               gcc_unreachable ();
3231             }
3232         }
3233       break;
3234
3235     default:
3236       gcc_unreachable ();
3237     }
3238
3239   /* Create a constructor from the list of elements.  */
3240   tmp = build_constructor (type, v);
3241   TREE_CONSTANT (tmp) = 1;
3242   TREE_INVARIANT (tmp) = 1;
3243   return tmp;
3244 }
3245
3246
3247 /* Generate code to evaluate non-constant array bounds.  Sets *poffset and
3248    returns the size (in elements) of the array.  */
3249
3250 static tree
3251 gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
3252                         stmtblock_t * pblock)
3253 {
3254   gfc_array_spec *as;
3255   tree size;
3256   tree stride;
3257   tree offset;
3258   tree ubound;
3259   tree lbound;
3260   tree tmp;
3261   gfc_se se;
3262
3263   int dim;
3264
3265   as = sym->as;
3266
3267   size = gfc_index_one_node;
3268   offset = gfc_index_zero_node;
3269   for (dim = 0; dim < as->rank; dim++)
3270     {
3271       /* Evaluate non-constant array bound expressions.  */
3272       lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
3273       if (as->lower[dim] && !INTEGER_CST_P (lbound))
3274         {
3275           gfc_init_se (&se, NULL);
3276           gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
3277           gfc_add_block_to_block (pblock, &se.pre);
3278           gfc_add_modify_expr (pblock, lbound, se.expr);
3279         }
3280       ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
3281       if (as->upper[dim] && !INTEGER_CST_P (ubound))
3282         {
3283           gfc_init_se (&se, NULL);
3284           gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
3285           gfc_add_block_to_block (pblock, &se.pre);
3286           gfc_add_modify_expr (pblock, ubound, se.expr);
3287         }
3288       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3289       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
3290       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3291
3292       /* The size of this dimension, and the stride of the next.  */
3293       if (dim + 1 < as->rank)
3294         stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
3295       else
3296         stride = GFC_TYPE_ARRAY_SIZE (type);
3297
3298       if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
3299         {
3300           /* Calculate stride = size * (ubound + 1 - lbound).  */
3301           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3302                              gfc_index_one_node, lbound);
3303           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
3304           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3305           if (stride)
3306             gfc_add_modify_expr (pblock, stride, tmp);
3307           else
3308             stride = gfc_evaluate_now (tmp, pblock);
3309         }
3310
3311       size = stride;
3312     }
3313
3314   gfc_trans_vla_type_sizes (sym, pblock);
3315
3316   *poffset = offset;
3317   return size;
3318 }
3319
3320
3321 /* Generate code to initialize/allocate an array variable.  */
3322
3323 tree
3324 gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
3325 {
3326   stmtblock_t block;
3327   tree type;
3328   tree tmp;
3329   tree fndecl;
3330   tree size;
3331   tree offset;
3332   bool onstack;
3333
3334   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
3335
3336   /* Do nothing for USEd variables.  */
3337   if (sym->attr.use_assoc)
3338     return fnbody;
3339
3340   type = TREE_TYPE (decl);
3341   gcc_assert (GFC_ARRAY_TYPE_P (type));
3342   onstack = TREE_CODE (type) != POINTER_TYPE;
3343
3344   gfc_start_block (&block);
3345
3346   /* Evaluate character string length.  */
3347   if (sym->ts.type == BT_CHARACTER
3348       && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3349     {
3350       gfc_trans_init_string_length (sym->ts.cl, &block);
3351
3352       gfc_trans_vla_type_sizes (sym, &block);
3353
3354       /* Emit a DECL_EXPR for this variable, which will cause the
3355          gimplifier to allocate storage, and all that good stuff.  */
3356       tmp = build1 (DECL_EXPR, TREE_TYPE (decl), decl);
3357       gfc_add_expr_to_block (&block, tmp);
3358     }
3359
3360   if (onstack)
3361     {
3362       gfc_add_expr_to_block (&block, fnbody);
3363       return gfc_finish_block (&block);
3364     }
3365
3366   type = TREE_TYPE (type);
3367
3368   gcc_assert (!sym->attr.use_assoc);
3369   gcc_assert (!TREE_STATIC (decl));
3370   gcc_assert (!sym->module);
3371
3372   if (sym->ts.type == BT_CHARACTER
3373       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
3374     gfc_trans_init_string_length (sym->ts.cl, &block);
3375
3376   size = gfc_trans_array_bounds (type, sym, &offset, &block);
3377
3378   /* Don't actually allocate space for Cray Pointees.  */
3379   if (sym->attr.cray_pointee)
3380     {
3381       if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3382         gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3383       gfc_add_expr_to_block (&block, fnbody);
3384       return gfc_finish_block (&block);
3385     }
3386
3387   /* The size is the number of elements in the array, so multiply by the
3388      size of an element to get the total size.  */
3389   tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
3390   size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
3391
3392   /* Allocate memory to hold the data.  */
3393   tmp = gfc_chainon_list (NULL_TREE, size);
3394
3395   if (gfc_index_integer_kind == 4)
3396     fndecl = gfor_fndecl_internal_malloc;
3397   else if (gfc_index_integer_kind == 8)
3398     fndecl = gfor_fndecl_internal_malloc64;
3399   else
3400     gcc_unreachable ();
3401   tmp = build_function_call_expr (fndecl, tmp);
3402   tmp = fold (convert (TREE_TYPE (decl), tmp));
3403   gfc_add_modify_expr (&block, decl, tmp);
3404
3405   /* Set offset of the array.  */
3406   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3407     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3408
3409
3410   /* Automatic arrays should not have initializers.  */
3411   gcc_assert (!sym->value);
3412
3413   gfc_add_expr_to_block (&block, fnbody);
3414
3415   /* Free the temporary.  */
3416   tmp = convert (pvoid_type_node, decl);
3417   tmp = gfc_chainon_list (NULL_TREE, tmp);
3418   tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
3419   gfc_add_expr_to_block (&block, tmp);
3420
3421   return gfc_finish_block (&block);
3422 }
3423
3424
3425 /* Generate entry and exit code for g77 calling convention arrays.  */
3426
3427 tree
3428 gfc_trans_g77_array (gfc_symbol * sym, tree body)
3429 {
3430   tree parm;
3431   tree type;
3432   locus loc;
3433   tree offset;
3434   tree tmp;
3435   stmtblock_t block;
3436
3437   gfc_get_backend_locus (&loc);
3438   gfc_set_backend_locus (&sym->declared_at);
3439
3440   /* Descriptor type.  */
3441   parm = sym->backend_decl;
3442   type = TREE_TYPE (parm);
3443   gcc_assert (GFC_ARRAY_TYPE_P (type));
3444
3445   gfc_start_block (&block);
3446
3447   if (sym->ts.type == BT_CHARACTER
3448       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3449     gfc_trans_init_string_length (sym->ts.cl, &block);
3450
3451   /* Evaluate the bounds of the array.  */
3452   gfc_trans_array_bounds (type, sym, &offset, &block);
3453
3454   /* Set the offset.  */
3455   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3456     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3457
3458   /* Set the pointer itself if we aren't using the parameter directly.  */
3459   if (TREE_CODE (parm) != PARM_DECL)
3460     {
3461       tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
3462       gfc_add_modify_expr (&block, parm, tmp);
3463     }
3464   tmp = gfc_finish_block (&block);
3465
3466   gfc_set_backend_locus (&loc);
3467
3468   gfc_start_block (&block);
3469   /* Add the initialization code to the start of the function.  */
3470   gfc_add_expr_to_block (&block, tmp);
3471   gfc_add_expr_to_block (&block, body);
3472
3473   return gfc_finish_block (&block);
3474 }
3475
3476
3477 /* Modify the descriptor of an array parameter so that it has the
3478    correct lower bound.  Also move the upper bound accordingly.
3479    If the array is not packed, it will be copied into a temporary.
3480    For each dimension we set the new lower and upper bounds.  Then we copy the
3481    stride and calculate the offset for this dimension.  We also work out
3482    what the stride of a packed array would be, and see it the two match.
3483    If the array need repacking, we set the stride to the values we just
3484    calculated, recalculate the offset and copy the array data.
3485    Code is also added to copy the data back at the end of the function.
3486    */
3487
3488 tree
3489 gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
3490 {
3491   tree size;
3492   tree type;
3493   tree offset;
3494   locus loc;
3495   stmtblock_t block;
3496   stmtblock_t cleanup;
3497   tree lbound;
3498   tree ubound;
3499   tree dubound;
3500   tree dlbound;
3501   tree dumdesc;
3502   tree tmp;
3503   tree stmt;
3504   tree stride;
3505   tree stmt_packed;
3506   tree stmt_unpacked;
3507   tree partial;
3508   gfc_se se;
3509   int n;
3510   int checkparm;
3511   int no_repack;
3512   bool optional_arg;
3513
3514   /* Do nothing for pointer and allocatable arrays.  */
3515   if (sym->attr.pointer || sym->attr.allocatable)
3516     return body;
3517
3518   if (sym->attr.dummy && gfc_is_nodesc_array (sym))
3519     return gfc_trans_g77_array (sym, body);
3520
3521   gfc_get_backend_locus (&loc);
3522   gfc_set_backend_locus (&sym->declared_at);
3523
3524   /* Descriptor type.  */
3525   type = TREE_TYPE (tmpdesc);
3526   gcc_assert (GFC_ARRAY_TYPE_P (type));
3527   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3528   dumdesc = build_fold_indirect_ref (dumdesc);
3529   gfc_start_block (&block);
3530
3531   if (sym->ts.type == BT_CHARACTER
3532       && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL)
3533     gfc_trans_init_string_length (sym->ts.cl, &block);
3534
3535   checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
3536
3537   no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
3538                 || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
3539
3540   if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
3541     {
3542       /* For non-constant shape arrays we only check if the first dimension
3543          is contiguous.  Repacking higher dimensions wouldn't gain us
3544          anything as we still don't know the array stride.  */
3545       partial = gfc_create_var (boolean_type_node, "partial");
3546       TREE_USED (partial) = 1;
3547       tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3548       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, integer_one_node);
3549       gfc_add_modify_expr (&block, partial, tmp);
3550     }
3551   else
3552     {
3553       partial = NULL_TREE;
3554     }
3555
3556   /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
3557      here, however I think it does the right thing.  */
3558   if (no_repack)
3559     {
3560       /* Set the first stride.  */
3561       stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
3562       stride = gfc_evaluate_now (stride, &block);
3563
3564       tmp = build2 (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
3565       tmp = build3 (COND_EXPR, gfc_array_index_type, tmp,
3566                     gfc_index_one_node, stride);
3567       stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
3568       gfc_add_modify_expr (&block, stride, tmp);
3569
3570       /* Allow the user to disable array repacking.  */
3571       stmt_unpacked = NULL_TREE;
3572     }
3573   else
3574     {
3575       gcc_assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
3576       /* A library call to repack the array if necessary.  */
3577       tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3578       tmp = gfc_chainon_list (NULL_TREE, tmp);
3579       stmt_unpacked = build_function_call_expr (gfor_fndecl_in_pack, tmp);
3580
3581       stride = gfc_index_one_node;
3582     }
3583
3584   /* This is for the case where the array data is used directly without
3585      calling the repack function.  */
3586   if (no_repack || partial != NULL_TREE)
3587     stmt_packed = gfc_conv_descriptor_data_get (dumdesc);
3588   else
3589     stmt_packed = NULL_TREE;
3590
3591   /* Assign the data pointer.  */
3592   if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3593     {
3594       /* Don't repack unknown shape arrays when the first stride is 1.  */
3595       tmp = build3 (COND_EXPR, TREE_TYPE (stmt_packed), partial,
3596                     stmt_packed, stmt_unpacked);
3597     }
3598   else
3599     tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
3600   gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
3601
3602   offset = gfc_index_zero_node;
3603   size = gfc_index_one_node;
3604
3605   /* Evaluate the bounds of the array.  */
3606   for (n = 0; n < sym->as->rank; n++)
3607     {
3608       if (checkparm || !sym->as->upper[n])
3609         {
3610           /* Get the bounds of the actual parameter.  */
3611           dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
3612           dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
3613         }
3614       else
3615         {
3616           dubound = NULL_TREE;
3617           dlbound = NULL_TREE;
3618         }
3619
3620       lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
3621       if (!INTEGER_CST_P (lbound))
3622         {
3623           gfc_init_se (&se, NULL);
3624           gfc_conv_expr_type (&se, sym->as->lower[n],
3625                               gfc_array_index_type);
3626           gfc_add_block_to_block (&block, &se.pre);
3627           gfc_add_modify_expr (&block, lbound, se.expr);
3628         }
3629
3630       ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
3631       /* Set the desired upper bound.  */
3632       if (sym->as->upper[n])
3633         {
3634           /* We know what we want the upper bound to be.  */
3635           if (!INTEGER_CST_P (ubound))
3636             {
3637               gfc_init_se (&se, NULL);
3638               gfc_conv_expr_type (&se, sym->as->upper[n],
3639                                   gfc_array_index_type);
3640               gfc_add_block_to_block (&block, &se.pre);
3641               gfc_add_modify_expr (&block, ubound, se.expr);
3642             }
3643
3644           /* Check the sizes match.  */
3645           if (checkparm)
3646             {
3647               /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)).  */
3648
3649               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3650                                  ubound, lbound);
3651               stride = build2 (MINUS_EXPR, gfc_array_index_type,
3652                                dubound, dlbound);
3653               tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride);
3654               gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
3655             }
3656         }
3657       else
3658         {
3659           /* For assumed shape arrays move the upper bound by the same amount
3660              as the lower bound.  */
3661           tmp = build2 (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
3662           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
3663           gfc_add_modify_expr (&block, ubound, tmp);
3664         }
3665       /* The offset of this dimension.  offset = offset - lbound * stride.  */
3666       tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
3667       offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
3668
3669       /* The size of this dimension, and the stride of the next.  */
3670       if (n + 1 < sym->as->rank)
3671         {
3672           stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
3673
3674           if (no_repack || partial != NULL_TREE)
3675             {
3676               stmt_unpacked =
3677                 gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
3678             }
3679
3680           /* Figure out the stride if not a known constant.  */
3681           if (!INTEGER_CST_P (stride))
3682             {
3683               if (no_repack)
3684                 stmt_packed = NULL_TREE;
3685               else
3686                 {
3687                   /* Calculate stride = size * (ubound + 1 - lbound).  */
3688                   tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3689                                      gfc_index_one_node, lbound);
3690                   tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3691                                      ubound, tmp);
3692                   size = fold_build2 (MULT_EXPR, gfc_array_index_type,
3693                                       size, tmp);
3694                   stmt_packed = size;
3695                 }
3696
3697               /* Assign the stride.  */
3698               if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
3699                 tmp = build3 (COND_EXPR, gfc_array_index_type, partial,
3700                               stmt_unpacked, stmt_packed);
3701               else
3702                 tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
3703               gfc_add_modify_expr (&block, stride, tmp);
3704             }
3705         }
3706       else
3707         {
3708           stride = GFC_TYPE_ARRAY_SIZE (type);
3709
3710           if (stride && !INTEGER_CST_P (stride))
3711             {
3712               /* Calculate size = stride * (ubound + 1 - lbound).  */
3713               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3714                                  gfc_index_one_node, lbound);
3715               tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3716                                  ubound, tmp);
3717               tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3718                                  GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
3719               gfc_add_modify_expr (&block, stride, tmp);
3720             }
3721         }
3722     }
3723
3724   /* Set the offset.  */
3725   if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
3726     gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
3727
3728   gfc_trans_vla_type_sizes (sym, &block);
3729
3730   stmt = gfc_finish_block (&block);
3731
3732   gfc_start_block (&block);
3733
3734   /* Only do the entry/initialization code if the arg is present.  */
3735   dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
3736   optional_arg = (sym->attr.optional
3737                   || (sym->ns->proc_name->attr.entry_master
3738                       && sym->attr.dummy));
3739   if (optional_arg)
3740     {
3741       tmp = gfc_conv_expr_present (sym);
3742       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3743     }
3744   gfc_add_expr_to_block (&block, stmt);
3745
3746   /* Add the main function body.  */
3747   gfc_add_expr_to_block (&block, body);
3748
3749   /* Cleanup code.  */
3750   if (!no_repack)
3751     {
3752       gfc_start_block (&cleanup);
3753       
3754       if (sym->attr.intent != INTENT_IN)
3755         {
3756           /* Copy the data back.  */
3757           tmp = gfc_chainon_list (NULL_TREE, dumdesc);
3758           tmp = gfc_chainon_list (tmp, tmpdesc);
3759           tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
3760           gfc_add_expr_to_block (&cleanup, tmp);
3761         }
3762
3763       /* Free the temporary.  */
3764       tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
3765       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
3766       gfc_add_expr_to_block (&cleanup, tmp);
3767
3768       stmt = gfc_finish_block (&cleanup);
3769         
3770       /* Only do the cleanup if the array was repacked.  */
3771       tmp = build_fold_indirect_ref (dumdesc);
3772       tmp = gfc_conv_descriptor_data_get (tmp);
3773       tmp = build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
3774       stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3775
3776       if (optional_arg)
3777         {
3778           tmp = gfc_conv_expr_present (sym);
3779           stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3780         }
3781       gfc_add_expr_to_block (&block, stmt);
3782     }
3783   /* We don't need to free any memory allocated by internal_pack as it will
3784      be freed at the end of the function by pop_context.  */
3785   return gfc_finish_block (&block);
3786 }
3787
3788
3789 /* Convert an array for passing as an actual argument.  Expressions and
3790    vector subscripts are evaluated and stored in a temporary, which is then
3791    passed.  For whole arrays the descriptor is passed.  For array sections
3792    a modified copy of the descriptor is passed, but using the original data.
3793
3794    This function is also used for array pointer assignments, and there
3795    are three cases:
3796
3797      - want_pointer && !se->direct_byref
3798          EXPR is an actual argument.  On exit, se->expr contains a
3799          pointer to the array descriptor.
3800
3801      - !want_pointer && !se->direct_byref
3802          EXPR is an actual argument to an intrinsic function or the
3803          left-hand side of a pointer assignment.  On exit, se->expr
3804          contains the descriptor for EXPR.
3805
3806      - !want_pointer && se->direct_byref
3807          EXPR is the right-hand side of a pointer assignment and
3808          se->expr is the descriptor for the previously-evaluated
3809          left-hand side.  The function creates an assignment from
3810          EXPR to se->expr.  */
3811
3812 void
3813 gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
3814 {
3815   gfc_loopinfo loop;
3816   gfc_ss *secss;
3817   gfc_ss_info *info;
3818   int need_tmp;
3819   int n;
3820   tree tmp;
3821   tree desc;
3822   stmtblock_t block;
3823   tree start;
3824   tree offset;
3825   int full;
3826   gfc_ref *ref;
3827
3828   gcc_assert (ss != gfc_ss_terminator);
3829
3830   /* TODO: Pass constant array constructors without a temporary.  */
3831   /* Special case things we know we can pass easily.  */
3832   switch (expr->expr_type)
3833     {
3834     case EXPR_VARIABLE:
3835       /* If we have a linear array section, we can pass it directly.
3836          Otherwise we need to copy it into a temporary.  */
3837
3838       /* Find the SS for the array section.  */
3839       secss = ss;
3840       while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
3841         secss = secss->next;
3842
3843       gcc_assert (secss != gfc_ss_terminator);
3844       info = &secss->data.info;
3845
3846       /* Get the descriptor for the array.  */
3847       gfc_conv_ss_descriptor (&se->pre, secss, 0);
3848       desc = info->descriptor;
3849
3850       need_tmp = gfc_ref_needs_temporary_p (expr->ref);
3851       if (need_tmp)
3852         full = 0;
3853       else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
3854         {
3855           /* Create a new descriptor if the array doesn't have one.  */
3856           full = 0;
3857         }
3858       else if (info->ref->u.ar.type == AR_FULL)
3859         full = 1;
3860       else if (se->direct_byref)
3861         full = 0;
3862       else
3863         {
3864           ref = info->ref;
3865           gcc_assert (ref->u.ar.type == AR_SECTION);
3866
3867           full = 1;
3868           for (n = 0; n < ref->u.ar.dimen; n++)
3869             {
3870               /* Detect passing the full array as a section.  This could do
3871                  even more checking, but it doesn't seem worth it.  */
3872               if (ref->u.ar.start[n]
3873                   || ref->u.ar.end[n]
3874                   || (ref->u.ar.stride[n]
3875                       && !gfc_expr_is_one (ref->u.ar.stride[n], 0)))
3876                 {
3877                   full = 0;
3878                   break;
3879                 }
3880             }
3881         }
3882
3883       if (full)
3884         {
3885           if (se->direct_byref)
3886             {
3887               /* Copy the descriptor for pointer assignments.  */
3888               gfc_add_modify_expr (&se->pre, se->expr, desc);
3889             }
3890           else if (se->want_pointer)
3891             {
3892               /* We pass full arrays directly.  This means that pointers and
3893                  allocatable arrays should also work.  */
3894               se->expr = build_fold_addr_expr (desc);
3895             }
3896           else
3897             {
3898               se->expr = desc;
3899             }
3900
3901           if (expr->ts.type == BT_CHARACTER)
3902             se->string_length = gfc_get_expr_charlen (expr);
3903
3904           return;
3905         }
3906       break;
3907       
3908     case EXPR_FUNCTION:
3909       /* A transformational function return value will be a temporary
3910          array descriptor.  We still need to go through the scalarizer
3911          to create the descriptor.  Elemental functions ar handled as
3912          arbitrary expressions, i.e. copy to a temporary.  */
3913       secss = ss;
3914       /* Look for the SS for this function.  */
3915       while (secss != gfc_ss_terminator
3916              && (secss->type != GFC_SS_FUNCTION || secss->expr != expr))
3917         secss = secss->next;
3918
3919       if (se->direct_byref)
3920         {
3921           gcc_assert (secss != gfc_ss_terminator);
3922
3923           /* For pointer assignments pass the descriptor directly.  */
3924           se->ss = secss;
3925           se->expr = build_fold_addr_expr (se->expr);
3926           gfc_conv_expr (se, expr);
3927           return;
3928         }
3929
3930       if (secss == gfc_ss_terminator)
3931         {
3932           /* Elemental function.  */
3933           need_tmp = 1;
3934           info = NULL;
3935         }
3936       else
3937         {
3938           /* Transformational function.  */
3939           info = &secss->data.info;
3940           need_tmp = 0;
3941         }
3942       break;
3943
3944     default:
3945       /* Something complicated.  Copy it into a temporary.  */
3946       need_tmp = 1;
3947       secss = NULL;
3948       info = NULL;
3949       break;
3950     }
3951
3952
3953   gfc_init_loopinfo (&loop);
3954
3955   /* Associate the SS with the loop.  */
3956   gfc_add_ss_to_loop (&loop, ss);
3957
3958   /* Tell the scalarizer not to bother creating loop variables, etc.  */
3959   if (!need_tmp)
3960     loop.array_parameter = 1;
3961   else
3962     /* The right-hand side of a pointer assignment mustn't use a temporary.  */
3963     gcc_assert (!se->direct_byref);
3964
3965   /* Setup the scalarizing loops and bounds.  */
3966   gfc_conv_ss_startstride (&loop);
3967
3968   if (need_tmp)
3969     {
3970       /* Tell the scalarizer to make a temporary.  */
3971       loop.temp_ss = gfc_get_ss ();
3972       loop.temp_ss->type = GFC_SS_TEMP;
3973       loop.temp_ss->next = gfc_ss_terminator;
3974       if (expr->ts.type == BT_CHARACTER)
3975         {
3976           gcc_assert (expr->ts.cl && expr->ts.cl->length
3977                       && expr->ts.cl->length->expr_type == EXPR_CONSTANT);
3978           loop.temp_ss->string_length = gfc_conv_mpz_to_tree
3979                         (expr->ts.cl->length->value.integer,
3980                          expr->ts.cl->length->ts.kind);
3981           expr->ts.cl->backend_decl = loop.temp_ss->string_length;
3982         }
3983         loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
3984
3985       /* ... which can hold our string, if present.  */
3986       if (expr->ts.type == BT_CHARACTER)
3987         {
3988           loop.temp_ss->string_length = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
3989           se->string_length = loop.temp_ss->string_length;
3990         }
3991       else
3992         loop.temp_ss->string_length = NULL;
3993       loop.temp_ss->data.temp.dimen = loop.dimen;
3994       gfc_add_ss_to_loop (&loop, loop.temp_ss);
3995     }
3996
3997   gfc_conv_loop_setup (&loop);
3998
3999   if (need_tmp)
4000     {
4001       /* Copy into a temporary and pass that.  We don't need to copy the data
4002          back because expressions and vector subscripts must be INTENT_IN.  */
4003       /* TODO: Optimize passing function return values.  */
4004       gfc_se lse;
4005       gfc_se rse;
4006
4007       /* Start the copying loops.  */
4008       gfc_mark_ss_chain_used (loop.temp_ss, 1);
4009       gfc_mark_ss_chain_used (ss, 1);
4010       gfc_start_scalarized_body (&loop, &block);
4011
4012       /* Copy each data element.  */
4013       gfc_init_se (&lse, NULL);
4014       gfc_copy_loopinfo_to_se (&lse, &loop);
4015       gfc_init_se (&rse, NULL);
4016       gfc_copy_loopinfo_to_se (&rse, &loop);
4017
4018       lse.ss = loop.temp_ss;
4019       rse.ss = ss;
4020
4021       gfc_conv_scalarized_array_ref (&lse, NULL);
4022       if (expr->ts.type == BT_CHARACTER)
4023         {
4024           gfc_conv_expr (&rse, expr);
4025           rse.expr = build_fold_indirect_ref (rse.expr);
4026         }
4027       else
4028         gfc_conv_expr_val (&rse, expr);
4029
4030       gfc_add_block_to_block (&block, &rse.pre);
4031       gfc_add_block_to_block (&block, &lse.pre);
4032
4033       gfc_add_modify_expr (&block, lse.expr, rse.expr);
4034
4035       /* Finish the copying loops.  */
4036       gfc_trans_scalarizing_loops (&loop, &block);
4037
4038       /* Set the first stride component to zero to indicate a temporary.  */
4039       desc = loop.temp_ss->data.info.descriptor;
4040       tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
4041       gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4042
4043       gcc_assert (is_gimple_lvalue (desc));
4044     }
4045   else if (expr->expr_type == EXPR_FUNCTION)
4046     {
4047       desc = info->descriptor;
4048       se->string_length = ss->string_length;
4049     }
4050   else
4051     {
4052       /* We pass sections without copying to a temporary.  Make a new
4053          descriptor and point it at the section we want.  The loop variable
4054          limits will be the limits of the section.
4055          A function may decide to repack the array to speed up access, but
4056          we're not bothered about that here.  */
4057       int dim;
4058       tree parm;
4059       tree parmtype;
4060       tree stride;
4061       tree from;
4062       tree to;
4063       tree base;
4064
4065       /* Set the string_length for a character array.  */
4066       if (expr->ts.type == BT_CHARACTER)
4067         se->string_length =  gfc_get_expr_charlen (expr);
4068
4069       desc = info->descriptor;
4070       gcc_assert (secss && secss != gfc_ss_terminator);
4071       if (se->direct_byref)
4072         {
4073           /* For pointer assignments we fill in the destination.  */
4074           parm = se->expr;
4075           parmtype = TREE_TYPE (parm);
4076         }
4077       else
4078         {
4079           /* Otherwise make a new one.  */
4080           parmtype = gfc_get_element_type (TREE_TYPE (desc));
4081           parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
4082                                                 loop.from, loop.to, 0);
4083           parm = gfc_create_var (parmtype, "parm");
4084         }
4085
4086       offset = gfc_index_zero_node;
4087       dim = 0;
4088
4089       /* The following can be somewhat confusing.  We have two
4090          descriptors, a new one and the original array.
4091          {parm, parmtype, dim} refer to the new one.
4092          {desc, type, n, secss, loop} refer to the original, which maybe
4093          a descriptorless array.
4094          The bounds of the scalarization are the bounds of the section.
4095          We don't have to worry about numeric overflows when calculating
4096          the offsets because all elements are within the array data.  */
4097
4098       /* Set the dtype.  */
4099       tmp = gfc_conv_descriptor_dtype (parm);
4100       gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
4101
4102       if (se->direct_byref)
4103         base = gfc_index_zero_node;
4104       else
4105         base = NULL_TREE;
4106
4107       for (n = 0; n < info->ref->u.ar.dimen; n++)
4108         {
4109           stride = gfc_conv_array_stride (desc, n);
4110
4111           /* Work out the offset.  */
4112           if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4113             {
4114               gcc_assert (info->subscript[n]
4115                       && info->subscript[n]->type == GFC_SS_SCALAR);
4116               start = info->subscript[n]->data.scalar.expr;
4117             }
4118           else
4119             {
4120               /* Check we haven't somehow got out of sync.  */
4121               gcc_assert (info->dim[dim] == n);
4122
4123               /* Evaluate and remember the start of the section.  */
4124               start = info->start[dim];
4125               stride = gfc_evaluate_now (stride, &loop.pre);
4126             }
4127
4128           tmp = gfc_conv_array_lbound (desc, n);
4129           tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), start, tmp);
4130
4131           tmp = fold_build2 (MULT_EXPR, TREE_TYPE (tmp), tmp, stride);
4132           offset = fold_build2 (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp);
4133
4134           if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
4135             {
4136               /* For elemental dimensions, we only need the offset.  */
4137               continue;
4138             }
4139
4140           /* Vector subscripts need copying and are handled elsewhere.  */
4141           gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
4142
4143           /* Set the new lower bound.  */
4144           from = loop.from[dim];
4145           to = loop.to[dim];
4146
4147           /* If we have an array section or are assigning to a pointer,
4148              make sure that the lower bound is 1.  References to the full
4149              array should otherwise keep the original bounds.  */
4150           if ((info->ref->u.ar.type != AR_FULL || se->direct_byref)
4151               && !integer_onep (from))
4152             {
4153               tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4154                                  gfc_index_one_node, from);
4155               to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
4156               from = gfc_index_one_node;
4157             }
4158           tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
4159           gfc_add_modify_expr (&loop.pre, tmp, from);
4160
4161           /* Set the new upper bound.  */
4162           tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
4163           gfc_add_modify_expr (&loop.pre, tmp, to);
4164
4165           /* Multiply the stride by the section stride to get the
4166              total stride.  */
4167           stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
4168                                 stride, info->stride[dim]);
4169
4170           if (se->direct_byref)
4171             base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
4172                                 base, stride);
4173
4174           /* Store the new stride.  */
4175           tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
4176           gfc_add_modify_expr (&loop.pre, tmp, stride);
4177
4178           dim++;
4179         }
4180
4181       if (se->data_not_needed)
4182         gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
4183       else
4184         {
4185           /* Point the data pointer at the first element in the section.  */
4186           tmp = gfc_conv_array_data (desc);
4187           tmp = build_fold_indirect_ref (tmp);
4188           tmp = gfc_build_array_ref (tmp, offset);
4189           offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
4190           gfc_conv_descriptor_data_set (&loop.pre, parm, offset);
4191         }
4192
4193       if (se->direct_byref && !se->data_not_needed)
4194         {
4195           /* Set the offset.  */
4196           tmp = gfc_conv_descriptor_offset (parm);
4197           gfc_add_modify_expr (&loop.pre, tmp, base);
4198         }
4199       else
4200         {
4201           /* Only the callee knows what the correct offset it, so just set
4202              it to zero here.  */
4203           tmp = gfc_conv_descriptor_offset (parm);
4204           gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
4205         }
4206       desc = parm;
4207     }
4208
4209   if (!se->direct_byref)
4210     {
4211       /* Get a pointer to the new descriptor.  */
4212       if (se->want_pointer)
4213         se->expr = build_fold_addr_expr (desc);
4214       else
4215         se->expr = desc;
4216     }
4217
4218   gfc_add_block_to_block (&se->pre, &loop.pre);
4219   gfc_add_block_to_block (&se->post, &loop.post);
4220
4221   /* Cleanup the scalarizer.  */
4222   gfc_cleanup_loop (&loop);
4223 }
4224
4225
4226 /* Convert an array for passing as an actual parameter.  */
4227 /* TODO: Optimize passing g77 arrays.  */
4228
4229 void
4230 gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
4231 {
4232   tree ptr;
4233   tree desc;
4234   tree tmp;
4235   tree stmt;
4236   gfc_symbol *sym;
4237   stmtblock_t block;
4238
4239   /* Passing address of the array if it is not pointer or assumed-shape.  */
4240   if (expr->expr_type == EXPR_VARIABLE
4241        && expr->ref->u.ar.type == AR_FULL && g77)
4242     {
4243       sym = expr->symtree->n.sym;
4244       tmp = gfc_get_symbol_decl (sym);
4245
4246       if (sym->ts.type == BT_CHARACTER)
4247         se->string_length = sym->ts.cl->backend_decl;
4248       if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE 
4249           && !sym->attr.allocatable)
4250         {
4251           /* Some variables are declared directly, others are declared as
4252              pointers and allocated on the heap.  */
4253           if (sym->attr.dummy || POINTER_TYPE_P (TREE_TYPE (tmp)))
4254             se->expr = tmp;
4255           else
4256             se->expr = build_fold_addr_expr (tmp);
4257           return;
4258         }
4259       if (sym->attr.allocatable)
4260         {
4261           se->expr = gfc_conv_array_data (tmp);
4262           return;
4263         }
4264     }
4265
4266   se->want_pointer = 1;
4267   gfc_conv_expr_descriptor (se, expr, ss);
4268
4269   if (g77)
4270     {
4271       desc = se->expr;
4272       /* Repack the array.  */
4273       tmp = gfc_chainon_list (NULL_TREE, desc);
4274       ptr = build_function_call_expr (gfor_fndecl_in_pack, tmp);
4275       ptr = gfc_evaluate_now (ptr, &se->pre);
4276       se->expr = ptr;
4277
4278       gfc_start_block (&block);
4279
4280       /* Copy the data back.  */
4281       tmp = gfc_chainon_list (NULL_TREE, desc);
4282       tmp = gfc_chainon_list (tmp, ptr);
4283       tmp = build_function_call_expr (gfor_fndecl_in_unpack, tmp);
4284       gfc_add_expr_to_block (&block, tmp);
4285
4286       /* Free the temporary.  */
4287       tmp = convert (pvoid_type_node, ptr);
4288       tmp = gfc_chainon_list (NULL_TREE, tmp);
4289       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
4290       gfc_add_expr_to_block (&block, tmp);
4291
4292       stmt = gfc_finish_block (&block);
4293
4294       gfc_init_block (&block);
4295       /* Only if it was repacked.  This code needs to be executed before the
4296          loop cleanup code.  */
4297       tmp = build_fold_indirect_ref (desc);
4298       tmp = gfc_conv_array_data (tmp);
4299       tmp = build2 (NE_EXPR, boolean_type_node, ptr, tmp);
4300       tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
4301
4302       gfc_add_expr_to_block (&block, tmp);
4303       gfc_add_block_to_block (&block, &se->post);
4304
4305       gfc_init_block (&se->post);
4306       gfc_add_block_to_block (&se->post, &block);
4307     }
4308 }
4309
4310
4311 /* Generate code to deallocate the symbol 'sym', if it is allocated.  */
4312
4313 tree
4314 gfc_trans_dealloc_allocated (gfc_symbol * sym)
4315
4316   tree tmp;
4317   tree descriptor;
4318   tree deallocate;
4319   stmtblock_t block;
4320
4321   gcc_assert (sym->attr.allocatable);
4322
4323   gfc_start_block (&block);
4324   descriptor = sym->backend_decl;
4325   deallocate = gfc_array_deallocate (descriptor, null_pointer_node);
4326
4327   tmp = gfc_conv_descriptor_data_get (descriptor);
4328   tmp = build2 (NE_EXPR, boolean_type_node, tmp,
4329                 build_int_cst (TREE_TYPE (tmp), 0));
4330   tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
4331   gfc_add_expr_to_block (&block, tmp);
4332
4333   tmp = gfc_finish_block (&block);
4334
4335   return tmp;
4336 }
4337
4338
4339 /* NULLIFY an allocatable/pointer array on function entry, free it on exit.  */
4340
4341 tree
4342 gfc_trans_deferred_array (gfc_symbol * sym, tree body)
4343 {
4344   tree type;
4345   tree tmp;
4346   tree descriptor;
4347   stmtblock_t fnblock;
4348   locus loc;
4349
4350   /* Make sure the frontend gets these right.  */
4351   if (!(sym->attr.pointer || sym->attr.allocatable))
4352     fatal_error
4353       ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
4354
4355   gfc_init_block (&fnblock);
4356
4357   gcc_assert (TREE_CODE (sym->backend_decl) == VAR_DECL
4358                 || TREE_CODE (sym->backend_decl) == PARM_DECL);
4359
4360   if (sym->ts.type == BT_CHARACTER
4361       && !INTEGER_CST_P (sym->ts.cl->backend_decl))
4362     {
4363       gfc_trans_init_string_length (sym->ts.cl, &fnblock);
4364       gfc_trans_vla_type_sizes (sym, &fnblock);
4365     }
4366
4367   /* Dummy and use associated variables don't need anything special.  */
4368   if (sym->attr.dummy || sym->attr.use_assoc)
4369     {
4370       gfc_add_expr_to_block (&fnblock, body);
4371
4372       return gfc_finish_block (&fnblock);
4373     }
4374
4375   gfc_get_backend_locus (&loc);
4376   gfc_set_backend_locus (&sym->declared_at);
4377   descriptor = sym->backend_decl;
4378
4379   if (TREE_STATIC (descriptor))
4380     {
4381       /* SAVEd variables are not freed on exit.  */
4382       gfc_trans_static_array_pointer (sym);
4383       return body;
4384     }
4385
4386   /* Get the descriptor type.  */
4387   type = TREE_TYPE (sym->backend_decl);
4388   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
4389
4390   /* NULLIFY the data pointer.  */
4391   gfc_conv_descriptor_data_set (&fnblock, descriptor, null_pointer_node);
4392
4393   gfc_add_expr_to_block (&fnblock, body);
4394
4395   gfc_set_backend_locus (&loc);
4396   /* Allocatable arrays need to be freed when they go out of scope.  */
4397   if (sym->attr.allocatable)
4398     {
4399       tmp = gfc_trans_dealloc_allocated (sym);
4400       gfc_add_expr_to_block (&fnblock, tmp);
4401     }
4402
4403   return gfc_finish_block (&fnblock);
4404 }
4405
4406 /************ Expression Walking Functions ******************/
4407
4408 /* Walk a variable reference.
4409
4410    Possible extension - multiple component subscripts.
4411     x(:,:) = foo%a(:)%b(:)
4412    Transforms to
4413     forall (i=..., j=...)
4414       x(i,j) = foo%a(j)%b(i)
4415     end forall
4416    This adds a fair amout of complexity because you need to deal with more
4417    than one ref.  Maybe handle in a similar manner to vector subscripts.
4418    Maybe not worth the effort.  */
4419
4420
4421 static gfc_ss *
4422 gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
4423 {
4424   gfc_ref *ref;
4425   gfc_array_ref *ar;
4426   gfc_ss *newss;
4427   gfc_ss *head;
4428   int n;
4429
4430   for (ref = expr->ref; ref; ref = ref->next)
4431     if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
4432       break;
4433
4434   for (; ref; ref = ref->next)
4435     {
4436       if (ref->type == REF_SUBSTRING)
4437         {
4438           newss = gfc_get_ss ();
4439           newss->type = GFC_SS_SCALAR;
4440           newss->expr = ref->u.ss.start;
4441           newss->next = ss;
4442           ss = newss;
4443
4444           newss = gfc_get_ss ();
4445           newss->type = GFC_SS_SCALAR;
4446           newss->expr = ref->u.ss.end;
4447           newss->next = ss;
4448           ss = newss;
4449         }
4450
4451       /* We're only interested in array sections from now on.  */
4452       if (ref->type != REF_ARRAY)
4453         continue;
4454
4455       ar = &ref->u.ar;
4456       switch (ar->type)
4457         {
4458         case AR_ELEMENT:
4459           for (n = 0; n < ar->dimen; n++)
4460             {
4461               newss = gfc_get_ss ();
4462               newss->type = GFC_SS_SCALAR;
4463               newss->expr = ar->start[n];
4464               newss->next = ss;
4465               ss = newss;
4466             }
4467           break;
4468
4469         case AR_FULL:
4470           newss = gfc_get_ss ();
4471           newss->type = GFC_SS_SECTION;
4472           newss->expr = expr;
4473           newss->next = ss;
4474           newss->data.info.dimen = ar->as->rank;
4475           newss->data.info.ref = ref;
4476
4477           /* Make sure array is the same as array(:,:), this way
4478              we don't need to special case all the time.  */
4479           ar->dimen = ar->as->rank;
4480           for (n = 0; n < ar->dimen; n++)
4481             {
4482               newss->data.info.dim[n] = n;
4483               ar->dimen_type[n] = DIMEN_RANGE;
4484
4485               gcc_assert (ar->start[n] == NULL);
4486               gcc_assert (ar->end[n] == NULL);
4487               gcc_assert (ar->stride[n] == NULL);
4488             }
4489           ss = newss;
4490           break;
4491
4492         case AR_SECTION:
4493           newss = gfc_get_ss ();
4494           newss->type = GFC_SS_SECTION;
4495           newss->expr = expr;
4496           newss->next = ss;
4497           newss->data.info.dimen = 0;
4498           newss->data.info.ref = ref;
4499
4500           head = newss;
4501
4502           /* We add SS chains for all the subscripts in the section.  */
4503           for (n = 0; n < ar->dimen; n++)
4504             {
4505               gfc_ss *indexss;
4506
4507               switch (ar->dimen_type[n])
4508                 {
4509                 case DIMEN_ELEMENT:
4510                   /* Add SS for elemental (scalar) subscripts.  */
4511                   gcc_assert (ar->start[n]);
4512                   indexss = gfc_get_ss ();
4513                   indexss->type = GFC_SS_SCALAR;
4514                   indexss->expr = ar->start[n];
4515                   indexss->next = gfc_ss_terminator;
4516                   indexss->loop_chain = gfc_ss_terminator;
4517                   newss->data.info.subscript[n] = indexss;
4518                   break;
4519
4520                 case DIMEN_RANGE:
4521                   /* We don't add anything for sections, just remember this
4522                      dimension for later.  */
4523                   newss->data.info.dim[newss->data.info.dimen] = n;
4524                   newss->data.info.dimen++;
4525                   break;
4526
4527                 case DIMEN_VECTOR:
4528                   /* Create a GFC_SS_VECTOR index in which we can store
4529                      the vector's descriptor.  */
4530                   indexss = gfc_get_ss ();
4531                   indexss->type = GFC_SS_VECTOR;
4532                   indexss->expr = ar->start[n];
4533                   indexss->next = gfc_ss_terminator;
4534                   indexss->loop_chain = gfc_ss_terminator;
4535                   newss->data.info.subscript[n] = indexss;
4536                   newss->data.info.dim[newss->data.info.dimen] = n;
4537                   newss->data.info.dimen++;
4538                   break;
4539
4540                 default:
4541                   /* We should know what sort of section it is by now.  */
4542                   gcc_unreachable ();
4543                 }
4544             }
4545           /* We should have at least one non-elemental dimension.  */
4546           gcc_assert (newss->data.info.dimen > 0);
4547           ss = newss;
4548           break;
4549
4550         default:
4551           /* We should know what sort of section it is by now.  */
4552           gcc_unreachable ();
4553         }
4554
4555     }
4556   return ss;
4557 }
4558
4559
4560 /* Walk an expression operator. If only one operand of a binary expression is
4561    scalar, we must also add the scalar term to the SS chain.  */
4562
4563 static gfc_ss *
4564 gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
4565 {
4566   gfc_ss *head;
4567   gfc_ss *head2;
4568   gfc_ss *newss;
4569
4570   head = gfc_walk_subexpr (ss, expr->value.op.op1);
4571   if (expr->value.op.op2 == NULL)
4572     head2 = head;
4573   else
4574     head2 = gfc_walk_subexpr (head, expr->value.op.op2);
4575
4576   /* All operands are scalar.  Pass back and let the caller deal with it.  */
4577   if (head2 == ss)
4578     return head2;
4579
4580   /* All operands require scalarization.  */
4581   if (head != ss && (expr->value.op.op2 == NULL || head2 != head))
4582     return head2;
4583
4584   /* One of the operands needs scalarization, the other is scalar.
4585      Create a gfc_ss for the scalar expression.  */
4586   newss = gfc_get_ss ();
4587   newss->type = GFC_SS_SCALAR;
4588   if (head == ss)
4589     {
4590       /* First operand is scalar.  We build the chain in reverse order, so
4591          add the scarar SS after the second operand.  */
4592       head = head2;
4593       while (head && head->next != ss)
4594         head = head->next;
4595       /* Check we haven't somehow broken the chain.  */
4596       gcc_assert (head);
4597       newss->next = ss;
4598       head->next = newss;
4599       newss->expr = expr->value.op.op1;
4600     }
4601   else                          /* head2 == head */
4602     {
4603       gcc_assert (head2 == head);
4604       /* Second operand is scalar.  */
4605       newss->next = head2;
4606       head2 = newss;
4607       newss->expr = expr->value.op.op2;
4608     }
4609
4610   return head2;
4611 }
4612
4613
4614 /* Reverse a SS chain.  */
4615
4616 gfc_ss *
4617 gfc_reverse_ss (gfc_ss * ss)
4618 {
4619   gfc_ss *next;
4620   gfc_ss *head;
4621
4622   gcc_assert (ss != NULL);
4623
4624   head = gfc_ss_terminator;
4625   while (ss != gfc_ss_terminator)
4626     {
4627       next = ss->next;
4628       /* Check we didn't somehow break the chain.  */
4629       gcc_assert (next != NULL);
4630       ss->next = head;
4631       head = ss;
4632       ss = next;
4633     }
4634
4635   return (head);
4636 }
4637
4638
4639 /* Walk the arguments of an elemental function.  */
4640
4641 gfc_ss *
4642 gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
4643                                   gfc_ss_type type)
4644 {
4645   int scalar;
4646   gfc_ss *head;
4647   gfc_ss *tail;
4648   gfc_ss *newss;
4649
4650   head = gfc_ss_terminator;
4651   tail = NULL;
4652   scalar = 1;
4653   for (; arg; arg = arg->next)
4654     {
4655       if (!arg->expr)
4656         continue;
4657
4658       newss = gfc_walk_subexpr (head, arg->expr);
4659       if (newss == head)
4660         {
4661           /* Scalar argument.  */
4662           newss = gfc_get_ss ();
4663           newss->type = type;
4664           newss->expr = arg->expr;
4665           newss->next = head;
4666         }
4667       else
4668         scalar = 0;
4669
4670       head = newss;
4671       if (!tail)
4672         {
4673           tail = head;
4674           while (tail->next != gfc_ss_terminator)
4675             tail = tail->next;
4676         }
4677     }
4678
4679   if (scalar)
4680     {
4681       /* If all the arguments are scalar we don't need the argument SS.  */
4682       gfc_free_ss_chain (head);
4683       /* Pass it back.  */
4684       return ss;
4685     }
4686
4687   /* Add it onto the existing chain.  */
4688   tail->next = ss;
4689   return head;
4690 }
4691
4692
4693 /* Walk a function call.  Scalar functions are passed back, and taken out of
4694    scalarization loops.  For elemental functions we walk their arguments.
4695    The result of functions returning arrays is stored in a temporary outside
4696    the loop, so that the function is only called once.  Hence we do not need
4697    to walk their arguments.  */
4698
4699 static gfc_ss *
4700 gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
4701 {
4702   gfc_ss *newss;
4703   gfc_intrinsic_sym *isym;
4704   gfc_symbol *sym;
4705
4706   isym = expr->value.function.isym;
4707
4708   /* Handle intrinsic functions separately.  */
4709   if (isym)
4710     return gfc_walk_intrinsic_function (ss, expr, isym);
4711
4712   sym = expr->value.function.esym;
4713   if (!sym)
4714       sym = expr->symtree->n.sym;
4715
4716   /* A function that returns arrays.  */
4717   if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
4718     {
4719       newss = gfc_get_ss ();
4720       newss->type = GFC_SS_FUNCTION;
4721       newss->expr = expr;
4722       newss->next = ss;
4723       newss->data.info.dimen = expr->rank;
4724       return newss;
4725     }
4726
4727   /* Walk the parameters of an elemental function.  For now we always pass
4728      by reference.  */
4729   if (sym->attr.elemental)
4730     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
4731                                              GFC_SS_REFERENCE);
4732
4733   /* Scalar functions are OK as these are evaluated outside the scalarization
4734      loop.  Pass back and let the caller deal with it.  */
4735   return ss;
4736 }
4737
4738
4739 /* An array temporary is constructed for array constructors.  */
4740
4741 static gfc_ss *
4742 gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
4743 {
4744   gfc_ss *newss;
4745   int n;
4746
4747   newss = gfc_get_ss ();
4748   newss->type = GFC_SS_CONSTRUCTOR;
4749   newss->expr = expr;
4750   newss->next = ss;
4751   newss->data.info.dimen = expr->rank;
4752   for (n = 0; n < expr->rank; n++)
4753     newss->data.info.dim[n] = n;
4754
4755   return newss;
4756 }
4757
4758
4759 /* Walk an expression.  Add walked expressions to the head of the SS chain.
4760    A wholly scalar expression will not be added.  */
4761
4762 static gfc_ss *
4763 gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
4764 {
4765   gfc_ss *head;
4766
4767   switch (expr->expr_type)
4768     {
4769     case EXPR_VARIABLE:
4770       head = gfc_walk_variable_expr (ss, expr);
4771       return head;
4772
4773     case EXPR_OP:
4774       head = gfc_walk_op_expr (ss, expr);
4775       return head;
4776
4777     case EXPR_FUNCTION:
4778       head = gfc_walk_function_expr (ss, expr);
4779       return head;
4780
4781     case EXPR_CONSTANT:
4782     case EXPR_NULL:
4783     case EXPR_STRUCTURE:
4784       /* Pass back and let the caller deal with it.  */
4785       break;
4786
4787     case EXPR_ARRAY:
4788       head = gfc_walk_array_constructor (ss, expr);
4789       return head;
4790
4791     case EXPR_SUBSTRING:
4792       /* Pass back and let the caller deal with it.  */
4793       break;
4794
4795     default:
4796       internal_error ("bad expression type during walk (%d)",
4797                       expr->expr_type);
4798     }
4799   return ss;
4800 }
4801
4802
4803 /* Entry point for expression walking.
4804    A return value equal to the passed chain means this is
4805    a scalar expression.  It is up to the caller to take whatever action is
4806    necessary to translate these.  */
4807
4808 gfc_ss *
4809 gfc_walk_expr (gfc_expr * expr)
4810 {
4811   gfc_ss *res;
4812
4813   res = gfc_walk_subexpr (gfc_ss_terminator, expr);
4814   return gfc_reverse_ss (res);
4815 }