OSDN Git Service

* Make-lang.in (fortran/f95-lang.o): Update dependencies.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-expr.c
1 /* Expression translation
2    Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3    Contributed by Paul Brook <paul@nowt.org>
4    and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "convert.h"
30 #include <stdio.h>
31 #include "ggc.h"
32 #include "toplev.h"
33 #include "real.h"
34 #include "tree-gimple.h"
35 #include "flags.h"
36 #include <gmp.h>
37 #include <assert.h>
38 #include "gfortran.h"
39 #include "trans.h"
40 #include "trans-const.h"
41 #include "trans-types.h"
42 #include "trans-array.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
44 #include "trans-stmt.h"
45
46 static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
47
48 /* Copy the scalarization loop variables.  */
49
50 static void
51 gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
52 {
53   dest->ss = src->ss;
54   dest->loop = src->loop;
55 }
56
57
58 /* Initialize a simple expression holder.
59
60    Care must be taken when multiple se are created with the same parent.
61    The child se must be kept in sync.  The easiest way is to delay creation
62    of a child se until after after the previous se has been translated.  */
63
64 void
65 gfc_init_se (gfc_se * se, gfc_se * parent)
66 {
67   memset (se, 0, sizeof (gfc_se));
68   gfc_init_block (&se->pre);
69   gfc_init_block (&se->post);
70
71   se->parent = parent;
72
73   if (parent)
74     gfc_copy_se_loopvars (se, parent);
75 }
76
77
78 /* Advances to the next SS in the chain.  Use this rather than setting
79    se->ss = se->ss->next because all the parents needs to be kept in sync.
80    See gfc_init_se.  */
81
82 void
83 gfc_advance_se_ss_chain (gfc_se * se)
84 {
85   gfc_se *p;
86
87   assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
88
89   p = se;
90   /* Walk down the parent chain.  */
91   while (p != NULL)
92     {
93       /* Simple consistency check.  */
94       assert (p->parent == NULL || p->parent->ss == p->ss);
95
96       p->ss = p->ss->next;
97
98       p = p->parent;
99     }
100 }
101
102
103 /* Ensures the result of the expression as either a temporary variable
104    or a constant so that it can be used repeatedly.  */
105
106 void
107 gfc_make_safe_expr (gfc_se * se)
108 {
109   tree var;
110
111   if (TREE_CODE_CLASS (TREE_CODE (se->expr)) == 'c')
112     return;
113
114   /* We need a temporary for this result.  */
115   var = gfc_create_var (TREE_TYPE (se->expr), NULL);
116   gfc_add_modify_expr (&se->pre, var, se->expr);
117   se->expr = var;
118 }
119
120
121 /* Return an expression which determines if a dummy parameter is present.  */
122
123 tree
124 gfc_conv_expr_present (gfc_symbol * sym)
125 {
126   tree decl;
127
128   assert (sym->attr.dummy && sym->attr.optional);
129
130   decl = gfc_get_symbol_decl (sym);
131   if (TREE_CODE (decl) != PARM_DECL)
132     {
133       /* Array parameters use a temporary descriptor, we want the real
134          parameter.  */
135       assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
136              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
137       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
138     }
139   return build2 (NE_EXPR, boolean_type_node, decl,
140                  fold_convert (TREE_TYPE (decl), null_pointer_node));
141 }
142
143
144 /* Generate code to initialize a string length variable. Returns the
145    value.  */
146
147 void
148 gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
149 {
150   gfc_se se;
151   tree tmp;
152
153   gfc_init_se (&se, NULL);
154   gfc_conv_expr_type (&se, cl->length, gfc_strlen_type_node);
155   gfc_add_block_to_block (pblock, &se.pre);
156
157   tmp = cl->backend_decl;
158   gfc_add_modify_expr (pblock, tmp, se.expr);
159 }
160
161
162 static void
163 gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind)
164 {
165   tree tmp;
166   tree type;
167   tree var;
168   gfc_se start;
169   gfc_se end;
170
171   type = gfc_get_character_type (kind, ref->u.ss.length);
172   type = build_pointer_type (type);
173
174   var = NULL_TREE;
175   gfc_init_se (&start, se);
176   gfc_conv_expr_type (&start, ref->u.ss.start, gfc_strlen_type_node);
177   gfc_add_block_to_block (&se->pre, &start.pre);
178
179   if (integer_onep (start.expr))
180     gfc_conv_string_parameter (se);
181   else
182     {
183       /* Change the start of the string.  */
184       if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
185         tmp = se->expr;
186       else
187         tmp = gfc_build_indirect_ref (se->expr);
188       tmp = gfc_build_array_ref (tmp, start.expr);
189       se->expr = gfc_build_addr_expr (type, tmp);
190     }
191
192   /* Length = end + 1 - start.  */
193   gfc_init_se (&end, se);
194   if (ref->u.ss.end == NULL)
195     end.expr = se->string_length;
196   else
197     {
198       gfc_conv_expr_type (&end, ref->u.ss.end, gfc_strlen_type_node);
199       gfc_add_block_to_block (&se->pre, &end.pre);
200     }
201   tmp =
202     build2 (MINUS_EXPR, gfc_strlen_type_node,
203             fold_convert (gfc_strlen_type_node, integer_one_node),
204             start.expr);
205   tmp = build2 (PLUS_EXPR, gfc_strlen_type_node, end.expr, tmp);
206   se->string_length = fold (tmp);
207 }
208
209
210 /* Convert a derived type component reference.  */
211
212 static void
213 gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
214 {
215   gfc_component *c;
216   tree tmp;
217   tree decl;
218   tree field;
219
220   c = ref->u.c.component;
221
222   assert (c->backend_decl);
223
224   field = c->backend_decl;
225   assert (TREE_CODE (field) == FIELD_DECL);
226   decl = se->expr;
227   tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
228
229   se->expr = tmp;
230
231   if (c->ts.type == BT_CHARACTER)
232     {
233       tmp = c->ts.cl->backend_decl;
234       /* Components must always be constant length.  */
235       assert (tmp && INTEGER_CST_P (tmp));
236       se->string_length = tmp;
237     }
238
239   if (c->pointer && c->dimension == 0)
240     se->expr = gfc_build_indirect_ref (se->expr);
241 }
242
243
244 /* Return the contents of a variable. Also handles reference/pointer
245    variables (all Fortran pointer references are implicit).  */
246
247 static void
248 gfc_conv_variable (gfc_se * se, gfc_expr * expr)
249 {
250   gfc_ref *ref;
251   gfc_symbol *sym;
252
253   sym = expr->symtree->n.sym;
254   if (se->ss != NULL)
255     {
256       /* Check that something hasn't gone horribly wrong.  */
257       assert (se->ss != gfc_ss_terminator);
258       assert (se->ss->expr == expr);
259
260       /* A scalarized term.  We already know the descriptor.  */
261       se->expr = se->ss->data.info.descriptor;
262       se->string_length = se->ss->string_length;
263       ref = se->ss->data.info.ref;
264     }
265   else
266     {
267       se->expr = gfc_get_symbol_decl (sym);
268
269       /* Procedure actual arguments.  */
270       if (sym->attr.flavor == FL_PROCEDURE
271           && se->expr != current_function_decl)
272         {
273           assert (se->want_pointer);
274           if (!sym->attr.dummy)
275             {
276               assert (TREE_CODE (se->expr) == FUNCTION_DECL);
277               se->expr = gfc_build_addr_expr (NULL, se->expr);
278             }
279           return;
280         }
281
282       /* Special case for assigning the return value of a function.
283          Self recursive functions must have an explicit return value.  */
284       if (se->expr == current_function_decl && sym->attr.function
285           && (sym->result == sym))
286         {
287           se->expr = gfc_get_fake_result_decl (sym);
288         }
289
290       /* Dereference scalar dummy variables.  */
291       if (sym->attr.dummy
292           && sym->ts.type != BT_CHARACTER
293           && !sym->attr.dimension)
294         se->expr = gfc_build_indirect_ref (se->expr);
295
296       /* Dereference pointer variables.  */
297       if ((sym->attr.pointer || sym->attr.allocatable)
298           && (sym->attr.dummy
299               || sym->attr.result
300               || sym->attr.function
301               || !sym->attr.dimension)
302           && sym->ts.type != BT_CHARACTER)
303         se->expr = gfc_build_indirect_ref (se->expr);
304
305       ref = expr->ref;
306     }
307
308   /* For character variables, also get the length.  */
309   if (sym->ts.type == BT_CHARACTER)
310     {
311       se->string_length = sym->ts.cl->backend_decl;
312       assert (se->string_length);
313     }
314
315   while (ref)
316     {
317       switch (ref->type)
318         {
319         case REF_ARRAY:
320           /* Return the descriptor if that's what we want and this is an array
321              section reference.  */
322           if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
323             return;
324 /* TODO: Pointers to single elements of array sections, eg elemental subs.  */
325           /* Return the descriptor for array pointers and allocations.  */
326           if (se->want_pointer
327               && ref->next == NULL && (se->descriptor_only))
328             return;
329
330           gfc_conv_array_ref (se, &ref->u.ar);
331           /* Return a pointer to an element.  */
332           break;
333
334         case REF_COMPONENT:
335           gfc_conv_component_ref (se, ref);
336           break;
337
338         case REF_SUBSTRING:
339           gfc_conv_substring (se, ref, expr->ts.kind);
340           break;
341
342         default:
343           abort ();
344           break;
345         }
346       ref = ref->next;
347     }
348   /* Pointer assignment, allocation or pass by reference.  Arrays are handled
349      separately.  */
350   if (se->want_pointer)
351     {
352       if (expr->ts.type == BT_CHARACTER)
353         gfc_conv_string_parameter (se);
354       else 
355         se->expr = gfc_build_addr_expr (NULL, se->expr);
356     }
357   if (se->ss != NULL)
358     gfc_advance_se_ss_chain (se);
359 }
360
361
362 /* Unary ops are easy... Or they would be if ! was a valid op.  */
363
364 static void
365 gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
366 {
367   gfc_se operand;
368   tree type;
369
370   assert (expr->ts.type != BT_CHARACTER);
371   /* Initialize the operand.  */
372   gfc_init_se (&operand, se);
373   gfc_conv_expr_val (&operand, expr->op1);
374   gfc_add_block_to_block (&se->pre, &operand.pre);
375
376   type = gfc_typenode_for_spec (&expr->ts);
377
378   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
379      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
380      All other unary operators have an equivalent GIMPLE unary operator.  */
381   if (code == TRUTH_NOT_EXPR)
382     se->expr = build2 (EQ_EXPR, type, operand.expr,
383                        convert (type, integer_zero_node));
384   else
385     se->expr = build1 (code, type, operand.expr);
386
387 }
388
389 /* Expand power operator to optimal multiplications when a value is raised
390    to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
391    Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
392    Programming", 3rd Edition, 1998.  */
393
394 /* This code is mostly duplicated from expand_powi in the backend.
395    We establish the "optimal power tree" lookup table with the defined size.
396    The items in the table are the exponents used to calculate the index
397    exponents. Any integer n less than the value can get an "addition chain",
398    with the first node being one.  */
399 #define POWI_TABLE_SIZE 256
400
401 /* The table is from builtins.c.  */
402 static const unsigned char powi_table[POWI_TABLE_SIZE] =
403   {
404       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
405       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
406       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
407      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
408      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
409      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
410      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
411      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
412      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
413      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
414      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
415      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
416      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
417      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
418      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
419      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
420      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
421      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
422      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
423      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
424      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
425      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
426      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
427      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
428      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
429     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
430     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
431     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
432     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
433     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
434     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
435     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
436   };
437
438 /* If n is larger than lookup table's max index, we use the "window 
439    method".  */
440 #define POWI_WINDOW_SIZE 3
441
442 /* Recursive function to expand the power operator. The temporary 
443    values are put in tmpvar. The function returns tmpvar[1] ** n.  */
444 static tree
445 gfc_conv_powi (gfc_se * se, int n, tree * tmpvar)
446 {
447   tree op0;
448   tree op1;
449   tree tmp;
450   int digit;
451
452   if (n < POWI_TABLE_SIZE)
453     {
454       if (tmpvar[n])
455         return tmpvar[n];
456
457       op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
458       op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
459     }
460   else if (n & 1)
461     {
462       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
463       op0 = gfc_conv_powi (se, n - digit, tmpvar);
464       op1 = gfc_conv_powi (se, digit, tmpvar);
465     }
466   else
467     {
468       op0 = gfc_conv_powi (se, n >> 1, tmpvar);
469       op1 = op0;
470     }
471
472   tmp = fold (build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1));
473   tmp = gfc_evaluate_now (tmp, &se->pre);
474
475   if (n < POWI_TABLE_SIZE)
476     tmpvar[n] = tmp;
477
478   return tmp;
479 }
480
481
482 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
483    return 1. Else return 0 and a call to runtime library functions
484    will have to be built.  */
485 static int
486 gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
487 {
488   tree cond;
489   tree tmp;
490   tree type;
491   tree vartmp[POWI_TABLE_SIZE];
492   int n;
493   int sgn;
494
495   type = TREE_TYPE (lhs);
496   n = abs (TREE_INT_CST_LOW (rhs));
497   sgn = tree_int_cst_sgn (rhs);
498
499   if ((!flag_unsafe_math_optimizations || optimize_size) && (n > 2 || n < -1))
500     return 0;
501
502   /* rhs == 0  */
503   if (sgn == 0)
504     {
505       se->expr = gfc_build_const (type, integer_one_node);
506       return 1;
507     }
508   /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
509   if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
510     {
511       tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
512                     fold_convert (TREE_TYPE (lhs), integer_minus_one_node));
513       cond = build2 (EQ_EXPR, boolean_type_node, lhs,
514                      convert (TREE_TYPE (lhs), integer_one_node));
515
516       /* If rhs is even,
517          result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
518       if ((n & 1) == 0)
519         {
520           tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
521           se->expr = build3 (COND_EXPR, type, tmp,
522                              convert (type, integer_one_node),
523                              convert (type, integer_zero_node));
524           return 1;
525         }
526       /* If rhs is odd,
527          result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
528       tmp = build3 (COND_EXPR, type, tmp,
529                     convert (type, integer_minus_one_node),
530                     convert (type, integer_zero_node));
531       se->expr = build3 (COND_EXPR, type, cond,
532                          convert (type, integer_one_node),
533                          tmp);
534       return 1;
535     }
536
537   memset (vartmp, 0, sizeof (vartmp));
538   vartmp[1] = lhs;
539   if (sgn == -1)
540     {
541       tmp = gfc_build_const (type, integer_one_node);
542       vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
543     }
544
545   se->expr = gfc_conv_powi (se, n, vartmp);
546
547   return 1;
548 }
549
550
551 /* Power op (**).  Constant integer exponent has special handling.  */
552
553 static void
554 gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
555 {
556   tree gfc_int4_type_node;
557   int kind;
558   int ikind;
559   gfc_se lse;
560   gfc_se rse;
561   tree fndecl;
562   tree tmp;
563
564   gfc_init_se (&lse, se);
565   gfc_conv_expr_val (&lse, expr->op1);
566   gfc_add_block_to_block (&se->pre, &lse.pre);
567
568   gfc_init_se (&rse, se);
569   gfc_conv_expr_val (&rse, expr->op2);
570   gfc_add_block_to_block (&se->pre, &rse.pre);
571
572   if (expr->op2->ts.type == BT_INTEGER
573          && expr->op2->expr_type == EXPR_CONSTANT)
574     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
575       return;        
576
577   gfc_int4_type_node = gfc_get_int_type (4);
578
579   kind = expr->op1->ts.kind;
580   switch (expr->op2->ts.type)
581     {
582     case BT_INTEGER:
583       ikind = expr->op2->ts.kind;
584       switch (ikind)
585         {
586         case 1:
587         case 2:
588           rse.expr = convert (gfc_int4_type_node, rse.expr);
589           /* Fall through.  */
590
591         case 4:
592           ikind = 0;
593           break;
594           
595         case 8:
596           ikind = 1;
597           break;
598
599         default:
600           abort();
601         }
602       switch (kind)
603         {
604         case 1:
605         case 2:
606           if (expr->op1->ts.type == BT_INTEGER)
607             lse.expr = convert (gfc_int4_type_node, lse.expr);
608           else
609             abort ();
610           /* Fall through.  */
611
612         case 4:
613           kind = 0;
614           break;
615           
616         case 8:
617           kind = 1;
618           break;
619
620         default:
621           abort();
622         }
623       
624       switch (expr->op1->ts.type)
625         {
626         case BT_INTEGER:
627           fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
628           break;
629
630         case BT_REAL:
631           fndecl = gfor_fndecl_math_powi[kind][ikind].real;
632           break;
633
634         case BT_COMPLEX:
635           fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
636           break;
637
638         default:
639           abort ();
640         }
641       break;
642
643     case BT_REAL:
644       switch (kind)
645         {
646         case 4:
647           fndecl = built_in_decls[BUILT_IN_POWF];
648           break;
649         case 8:
650           fndecl = built_in_decls[BUILT_IN_POW];
651           break;
652         default:
653           abort ();
654         }
655       break;
656
657     case BT_COMPLEX:
658       switch (kind)
659         {
660         case 4:
661           fndecl = gfor_fndecl_math_cpowf;
662           break;
663         case 8:
664           fndecl = gfor_fndecl_math_cpow;
665           break;
666         default:
667           abort ();
668         }
669       break;
670
671     default:
672       abort ();
673       break;
674     }
675
676   tmp = gfc_chainon_list (NULL_TREE, lse.expr);
677   tmp = gfc_chainon_list (tmp, rse.expr);
678   se->expr = fold (gfc_build_function_call (fndecl, tmp));
679 }
680
681
682 /* Generate code to allocate a string temporary.  */
683
684 tree
685 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
686 {
687   tree var;
688   tree tmp;
689   tree args;
690
691   if (TREE_TYPE (len) != gfc_strlen_type_node)
692     abort ();
693
694   if (gfc_can_put_var_on_stack (len))
695     {
696       /* Create a temporary variable to hold the result.  */
697       tmp = fold (build2 (MINUS_EXPR, gfc_strlen_type_node, len,
698                           convert (gfc_strlen_type_node,
699                                    integer_one_node)));
700       tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
701       tmp = build_array_type (gfc_character1_type_node, tmp);
702       var = gfc_create_var (tmp, "str");
703       var = gfc_build_addr_expr (type, var);
704     }
705   else
706     {
707       /* Allocate a temporary to hold the result.  */
708       var = gfc_create_var (type, "pstr");
709       args = gfc_chainon_list (NULL_TREE, len);
710       tmp = gfc_build_function_call (gfor_fndecl_internal_malloc, args);
711       tmp = convert (type, tmp);
712       gfc_add_modify_expr (&se->pre, var, tmp);
713
714       /* Free the temporary afterwards.  */
715       tmp = convert (pvoid_type_node, var);
716       args = gfc_chainon_list (NULL_TREE, tmp);
717       tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
718       gfc_add_expr_to_block (&se->post, tmp);
719     }
720
721   return var;
722 }
723
724
725 /* Handle a string concatenation operation.  A temporary will be allocated to
726    hold the result.  */
727
728 static void
729 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
730 {
731   gfc_se lse;
732   gfc_se rse;
733   tree len;
734   tree type;
735   tree var;
736   tree args;
737   tree tmp;
738
739   assert (expr->op1->ts.type == BT_CHARACTER
740           && expr->op2->ts.type == BT_CHARACTER);
741
742   gfc_init_se (&lse, se);
743   gfc_conv_expr (&lse, expr->op1);
744   gfc_conv_string_parameter (&lse);
745   gfc_init_se (&rse, se);
746   gfc_conv_expr (&rse, expr->op2);
747   gfc_conv_string_parameter (&rse);
748
749   gfc_add_block_to_block (&se->pre, &lse.pre);
750   gfc_add_block_to_block (&se->pre, &rse.pre);
751
752   type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
753   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
754   if (len == NULL_TREE)
755     {
756       len = fold (build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
757                           lse.string_length, rse.string_length));
758     }
759
760   type = build_pointer_type (type);
761
762   var = gfc_conv_string_tmp (se, type, len);
763
764   /* Do the actual concatenation.  */
765   args = NULL_TREE;
766   args = gfc_chainon_list (args, len);
767   args = gfc_chainon_list (args, var);
768   args = gfc_chainon_list (args, lse.string_length);
769   args = gfc_chainon_list (args, lse.expr);
770   args = gfc_chainon_list (args, rse.string_length);
771   args = gfc_chainon_list (args, rse.expr);
772   tmp = gfc_build_function_call (gfor_fndecl_concat_string, args);
773   gfc_add_expr_to_block (&se->pre, tmp);
774
775   /* Add the cleanup for the operands.  */
776   gfc_add_block_to_block (&se->pre, &rse.post);
777   gfc_add_block_to_block (&se->pre, &lse.post);
778
779   se->expr = var;
780   se->string_length = len;
781 }
782
783
784 /* Translates an op expression. Common (binary) cases are handled by this
785    function, others are passed on. Recursion is used in either case.
786    We use the fact that (op1.ts == op2.ts) (except for the power
787    operator **).
788    Operators need no special handling for scalarized expressions as long as
789    they call gfc_conv_simple_val to get their operands.
790    Character strings get special handling.  */
791
792 static void
793 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
794 {
795   enum tree_code code;
796   gfc_se lse;
797   gfc_se rse;
798   tree type;
799   tree tmp;
800   int lop;
801   int checkstring;
802
803   checkstring = 0;
804   lop = 0;
805   switch (expr->operator)
806     {
807     case INTRINSIC_UPLUS:
808       gfc_conv_expr (se, expr->op1);
809       return;
810
811     case INTRINSIC_UMINUS:
812       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
813       return;
814
815     case INTRINSIC_NOT:
816       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
817       return;
818
819     case INTRINSIC_PLUS:
820       code = PLUS_EXPR;
821       break;
822
823     case INTRINSIC_MINUS:
824       code = MINUS_EXPR;
825       break;
826
827     case INTRINSIC_TIMES:
828       code = MULT_EXPR;
829       break;
830
831     case INTRINSIC_DIVIDE:
832       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
833          an integer, we must round towards zero, so we use a
834          TRUNC_DIV_EXPR.  */
835       if (expr->ts.type == BT_INTEGER)
836         code = TRUNC_DIV_EXPR;
837       else
838         code = RDIV_EXPR;
839       break;
840
841     case INTRINSIC_POWER:
842       gfc_conv_power_op (se, expr);
843       return;
844
845     case INTRINSIC_CONCAT:
846       gfc_conv_concat_op (se, expr);
847       return;
848
849     case INTRINSIC_AND:
850       code = TRUTH_ANDIF_EXPR;
851       lop = 1;
852       break;
853
854     case INTRINSIC_OR:
855       code = TRUTH_ORIF_EXPR;
856       lop = 1;
857       break;
858
859       /* EQV and NEQV only work on logicals, but since we represent them
860          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
861     case INTRINSIC_EQ:
862     case INTRINSIC_EQV:
863       code = EQ_EXPR;
864       checkstring = 1;
865       lop = 1;
866       break;
867
868     case INTRINSIC_NE:
869     case INTRINSIC_NEQV:
870       code = NE_EXPR;
871       checkstring = 1;
872       lop = 1;
873       break;
874
875     case INTRINSIC_GT:
876       code = GT_EXPR;
877       checkstring = 1;
878       lop = 1;
879       break;
880
881     case INTRINSIC_GE:
882       code = GE_EXPR;
883       checkstring = 1;
884       lop = 1;
885       break;
886
887     case INTRINSIC_LT:
888       code = LT_EXPR;
889       checkstring = 1;
890       lop = 1;
891       break;
892
893     case INTRINSIC_LE:
894       code = LE_EXPR;
895       checkstring = 1;
896       lop = 1;
897       break;
898
899     case INTRINSIC_USER:
900     case INTRINSIC_ASSIGN:
901       /* These should be converted into function calls by the frontend.  */
902       abort ();
903       return;
904
905     default:
906       fatal_error ("Unknown intrinsic op");
907       return;
908     }
909
910   /* The only exception to this is **, which is handled separately anyway.  */
911   assert (expr->op1->ts.type == expr->op2->ts.type);
912
913   if (checkstring && expr->op1->ts.type != BT_CHARACTER)
914     checkstring = 0;
915
916   /* lhs */
917   gfc_init_se (&lse, se);
918   gfc_conv_expr (&lse, expr->op1);
919   gfc_add_block_to_block (&se->pre, &lse.pre);
920
921   /* rhs */
922   gfc_init_se (&rse, se);
923   gfc_conv_expr (&rse, expr->op2);
924   gfc_add_block_to_block (&se->pre, &rse.pre);
925
926   /* For string comparisons we generate a library call, and compare the return
927      value with 0.  */
928   if (checkstring)
929     {
930       gfc_conv_string_parameter (&lse);
931       gfc_conv_string_parameter (&rse);
932       tmp = NULL_TREE;
933       tmp = gfc_chainon_list (tmp, lse.string_length);
934       tmp = gfc_chainon_list (tmp, lse.expr);
935       tmp = gfc_chainon_list (tmp, rse.string_length);
936       tmp = gfc_chainon_list (tmp, rse.expr);
937
938       /* Build a call for the comparison.  */
939       lse.expr = gfc_build_function_call (gfor_fndecl_compare_string, tmp);
940       gfc_add_block_to_block (&lse.post, &rse.post);
941
942       rse.expr = integer_zero_node;
943     }
944
945   type = gfc_typenode_for_spec (&expr->ts);
946
947   if (lop)
948     {
949       /* The result of logical ops is always boolean_type_node.  */
950       tmp = fold (build2 (code, type, lse.expr, rse.expr));
951       se->expr = convert (type, tmp);
952     }
953   else
954     se->expr = fold (build2 (code, type, lse.expr, rse.expr));
955
956   /* Add the post blocks.  */
957   gfc_add_block_to_block (&se->post, &rse.post);
958   gfc_add_block_to_block (&se->post, &lse.post);
959 }
960
961
962 static void
963 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
964 {
965   tree tmp;
966
967   if (sym->attr.dummy)
968     {
969       tmp = gfc_get_symbol_decl (sym);
970       assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
971               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
972
973       se->expr = tmp;
974     }
975   else
976     {
977       if (!sym->backend_decl)
978         sym->backend_decl = gfc_get_extern_function_decl (sym);
979
980       tmp = sym->backend_decl;
981       assert (TREE_CODE (tmp) == FUNCTION_DECL);
982       se->expr = gfc_build_addr_expr (NULL, tmp);
983     }
984 }
985
986
987 /* Generate code for a procedure call.  Note can return se->post != NULL.
988    If se->direct_byref is set then se->expr contains the return parameter.  */
989
990 void
991 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
992                         gfc_actual_arglist * arg)
993 {
994   tree arglist;
995   tree tmp;
996   tree fntype;
997   gfc_se parmse;
998   gfc_ss *argss;
999   gfc_ss_info *info;
1000   int byref;
1001   tree type;
1002   tree var;
1003   tree len;
1004   tree stringargs;
1005   gfc_formal_arglist *formal;
1006
1007   arglist = NULL_TREE;
1008   stringargs = NULL_TREE;
1009   var = NULL_TREE;
1010   len = NULL_TREE;
1011
1012   if (se->ss != NULL)
1013     {
1014       if (!sym->attr.elemental)
1015         {
1016           assert (se->ss->type == GFC_SS_FUNCTION);
1017           if (se->ss->useflags)
1018             {
1019               assert (gfc_return_by_reference (sym)
1020                       && sym->result->attr.dimension);
1021               assert (se->loop != NULL);
1022
1023               /* Access the previously obtained result.  */
1024               gfc_conv_tmp_array_ref (se);
1025               gfc_advance_se_ss_chain (se);
1026               return;
1027             }
1028         }
1029       info = &se->ss->data.info;
1030     }
1031   else
1032     info = NULL;
1033
1034   byref = gfc_return_by_reference (sym);
1035   if (byref)
1036     {
1037       if (se->direct_byref)
1038         arglist = gfc_chainon_list (arglist, se->expr);
1039       else if (sym->result->attr.dimension)
1040         {
1041           assert (se->loop && se->ss);
1042           /* Set the type of the array.  */
1043           tmp = gfc_typenode_for_spec (&sym->ts);
1044           info->dimen = se->loop->dimen;
1045           /* Allocate a temporary to store the result.  */
1046           gfc_trans_allocate_temp_array (se->loop, info, tmp);
1047
1048           /* Zero the first stride to indicate a temporary.  */
1049           tmp =
1050             gfc_conv_descriptor_stride (info->descriptor, gfc_rank_cst[0]);
1051           gfc_add_modify_expr (&se->pre, tmp,
1052                                convert (TREE_TYPE (tmp), integer_zero_node));
1053           /* Pass the temporary as the first argument.  */
1054           tmp = info->descriptor;
1055           tmp = gfc_build_addr_expr (NULL, tmp);
1056           arglist = gfc_chainon_list (arglist, tmp);
1057         }
1058       else if (sym->ts.type == BT_CHARACTER)
1059         {
1060           assert (sym->ts.cl && sym->ts.cl->length
1061                   && sym->ts.cl->length->expr_type == EXPR_CONSTANT);
1062           len = gfc_conv_mpz_to_tree
1063             (sym->ts.cl->length->value.integer, sym->ts.cl->length->ts.kind);
1064           sym->ts.cl->backend_decl = len;
1065           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
1066           type = build_pointer_type (type);
1067
1068           var = gfc_conv_string_tmp (se, type, len);
1069           arglist = gfc_chainon_list (arglist, var);
1070           arglist = gfc_chainon_list (arglist, convert (gfc_strlen_type_node,
1071                                                         len));
1072         }
1073       else      /* TODO: derived type function return values.  */
1074         abort ();
1075     }
1076
1077   formal = sym->formal;
1078   /* Evaluate the arguments.  */
1079   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
1080     {
1081       if (arg->expr == NULL)
1082         {
1083
1084           if (se->ignore_optional)
1085             {
1086               /* Some intrinsics have already been resolved to the correct
1087                  parameters.  */
1088               continue;
1089             }
1090           else if (arg->label)
1091             {
1092               has_alternate_specifier = 1;
1093               continue;
1094             }
1095           else
1096             {
1097               /* Pass a NULL pointer for an absent arg.  */
1098               gfc_init_se (&parmse, NULL);
1099               parmse.expr = null_pointer_node;
1100               if (arg->missing_arg_type == BT_CHARACTER)
1101                 {
1102                   stringargs =
1103                     gfc_chainon_list (stringargs,
1104                                       convert (gfc_strlen_type_node,
1105                                                integer_zero_node));
1106                 }
1107             }
1108         }
1109       else if (se->ss && se->ss->useflags)
1110         {
1111           /* An elemental function inside a scalarized loop.  */
1112           gfc_init_se (&parmse, se);
1113           gfc_conv_expr_reference (&parmse, arg->expr);
1114         }
1115       else
1116         {
1117           /* A scalar or transformational function.  */
1118           gfc_init_se (&parmse, NULL);
1119           argss = gfc_walk_expr (arg->expr);
1120
1121           if (argss == gfc_ss_terminator)
1122             {
1123               gfc_conv_expr_reference (&parmse, arg->expr);
1124               if (formal && formal->sym->attr.pointer
1125                   && arg->expr->expr_type != EXPR_NULL)
1126                 {
1127                   /* Scalar pointer dummy args require an extra level of
1128                      indirection. The null pointer already contains
1129                      this level of indirection.  */
1130                   parmse.expr = gfc_build_addr_expr (NULL, parmse.expr);
1131                 }
1132             }
1133           else
1134             {
1135               /* If the procedure requires an explicit interface, the
1136                  actual argument is passed according to the
1137                  corresponding formal argument.  If the corresponding
1138                  formal argument is a POINTER or assumed shape, we do
1139                  not use g77's calling aonvention, and pass the
1140                  address of the array descriptor instead. Otherwise we
1141                  use g77's calling convention.  */
1142               int f;
1143               f = (formal != NULL)
1144                   && !formal->sym->attr.pointer
1145                   && formal->sym->as->type != AS_ASSUMED_SHAPE;
1146               f = f || !sym->attr.always_explicit;
1147               gfc_conv_array_parameter (&parmse, arg->expr, argss, f);
1148             } 
1149         }
1150
1151       gfc_add_block_to_block (&se->pre, &parmse.pre);
1152       gfc_add_block_to_block (&se->post, &parmse.post);
1153
1154       /* Character strings are passed as two paramarers, a length and a
1155          pointer.  */
1156       if (parmse.string_length != NULL_TREE)
1157         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
1158
1159       arglist = gfc_chainon_list (arglist, parmse.expr);
1160     }
1161
1162   /* Add the hidden string length parameters to the arguments.  */
1163   arglist = chainon (arglist, stringargs);
1164
1165   /* Generate the actual call.  */
1166   gfc_conv_function_val (se, sym);
1167   /* If there are alternate return labels, function type should be
1168      integer.  */
1169   if (has_alternate_specifier)
1170     TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
1171
1172   fntype = TREE_TYPE (TREE_TYPE (se->expr));
1173   se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
1174                      arglist, NULL_TREE);
1175
1176   /* If we have a pointer function, but we don't want a pointer, e.g.
1177      something like
1178         x = f()
1179      where f is pointer valued, we have to dereference the result.  */
1180   if (sym->attr.pointer && !se->want_pointer && !byref)
1181     se->expr = gfc_build_indirect_ref (se->expr);
1182
1183   /* A pure function may still have side-effects - it may modify its
1184      parameters.  */
1185   TREE_SIDE_EFFECTS (se->expr) = 1;
1186 #if 0
1187   if (!sym->attr.pure)
1188     TREE_SIDE_EFFECTS (se->expr) = 1;
1189 #endif
1190
1191   if (byref)
1192     {
1193       /* Add the function call to the pre chain.  There is no expression.  */
1194       gfc_add_expr_to_block (&se->pre, se->expr);
1195       se->expr = NULL_TREE;
1196
1197       if (!se->direct_byref)
1198         {
1199           if (sym->result->attr.dimension)
1200             {
1201               if (flag_bounds_check)
1202                 {
1203                   /* Check the data pointer hasn't been modified.  This would
1204                      happen in a function returning a pointer.  */
1205                   tmp = gfc_conv_descriptor_data (info->descriptor);
1206                   tmp = build2 (NE_EXPR, boolean_type_node, tmp, info->data);
1207                   gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
1208                 }
1209               se->expr = info->descriptor;
1210             }
1211           else if (sym->ts.type == BT_CHARACTER)
1212             {
1213               se->expr = var;
1214               se->string_length = len;
1215             }
1216           else
1217             abort ();
1218         }
1219     }
1220 }
1221
1222
1223 /* Generate code to copy a string.  */
1224
1225 static void
1226 gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
1227                        tree slen, tree src)
1228 {
1229   tree tmp;
1230
1231   tmp = NULL_TREE;
1232   tmp = gfc_chainon_list (tmp, dlen);
1233   tmp = gfc_chainon_list (tmp, dest);
1234   tmp = gfc_chainon_list (tmp, slen);
1235   tmp = gfc_chainon_list (tmp, src);
1236   tmp = gfc_build_function_call (gfor_fndecl_copy_string, tmp);
1237   gfc_add_expr_to_block (block, tmp);
1238 }
1239
1240
1241 /* Translate a statement function.
1242    The value of a statement function reference is obtained by evaluating the
1243    expression using the values of the actual arguments for the values of the
1244    corresponding dummy arguments.  */
1245
1246 static void
1247 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
1248 {
1249   gfc_symbol *sym;
1250   gfc_symbol *fsym;
1251   gfc_formal_arglist *fargs;
1252   gfc_actual_arglist *args;
1253   gfc_se lse;
1254   gfc_se rse;
1255   gfc_saved_var *saved_vars;
1256   tree *temp_vars;
1257   tree type;
1258   tree tmp;
1259   int n;
1260
1261   sym = expr->symtree->n.sym;
1262   args = expr->value.function.actual;
1263   gfc_init_se (&lse, NULL);
1264   gfc_init_se (&rse, NULL);
1265
1266   n = 0;
1267   for (fargs = sym->formal; fargs; fargs = fargs->next)
1268     n++;
1269   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
1270   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
1271
1272   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1273     {
1274       /* Each dummy shall be specified, explicitly or implicitly, to be
1275          scalar.  */
1276       assert (fargs->sym->attr.dimension == 0);
1277       fsym = fargs->sym;
1278
1279       /* Create a temporary to hold the value.  */
1280       type = gfc_typenode_for_spec (&fsym->ts);
1281       temp_vars[n] = gfc_create_var (type, fsym->name);
1282
1283       if (fsym->ts.type == BT_CHARACTER)
1284         {
1285           /* Copy string arguments.  */
1286           tree arglen;
1287
1288           assert (fsym->ts.cl && fsym->ts.cl->length
1289                   && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
1290
1291           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1292           tmp = gfc_build_addr_expr (build_pointer_type (type),
1293                                      temp_vars[n]);
1294
1295           gfc_conv_expr (&rse, args->expr);
1296           gfc_conv_string_parameter (&rse);
1297           gfc_add_block_to_block (&se->pre, &lse.pre);
1298           gfc_add_block_to_block (&se->pre, &rse.pre);
1299
1300           gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
1301                                  rse.expr);
1302           gfc_add_block_to_block (&se->pre, &lse.post);
1303           gfc_add_block_to_block (&se->pre, &rse.post);
1304         }
1305       else
1306         {
1307           /* For everything else, just evaluate the expression.  */
1308           gfc_conv_expr (&lse, args->expr);
1309
1310           gfc_add_block_to_block (&se->pre, &lse.pre);
1311           gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
1312           gfc_add_block_to_block (&se->pre, &lse.post);
1313         }
1314
1315       args = args->next;
1316     }
1317
1318   /* Use the temporary variables in place of the real ones.  */
1319   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1320     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
1321
1322   gfc_conv_expr (se, sym->value);
1323
1324   if (sym->ts.type == BT_CHARACTER)
1325     {
1326       gfc_conv_const_charlen (sym->ts.cl);
1327
1328       /* Force the expression to the correct length.  */
1329       if (!INTEGER_CST_P (se->string_length)
1330           || tree_int_cst_lt (se->string_length,
1331                               sym->ts.cl->backend_decl))
1332         {
1333           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
1334           tmp = gfc_create_var (type, sym->name);
1335           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
1336           gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
1337                                  se->string_length, se->expr);
1338           se->expr = tmp;
1339         }
1340       se->string_length = sym->ts.cl->backend_decl;
1341     }
1342
1343   /* Restore the original variables.  */
1344   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1345     gfc_restore_sym (fargs->sym, &saved_vars[n]);
1346   gfc_free (saved_vars);
1347 }
1348
1349
1350 /* Translate a function expression.  */
1351
1352 static void
1353 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
1354 {
1355   gfc_symbol *sym;
1356
1357   if (expr->value.function.isym)
1358     {
1359       gfc_conv_intrinsic_function (se, expr);
1360       return;
1361     }
1362
1363   /* We distinguish statement functions from general functions to improve
1364      runtime performance.  */
1365   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
1366     {
1367       gfc_conv_statement_function (se, expr);
1368       return;
1369     }
1370
1371   /* expr.value.function.esym is the resolved (specific) function symbol for
1372      most functions.  However this isn't set for dummy procedures.  */
1373   sym = expr->value.function.esym;
1374   if (!sym)
1375     sym = expr->symtree->n.sym;
1376   gfc_conv_function_call (se, sym, expr->value.function.actual);
1377 }
1378
1379
1380 static void
1381 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
1382 {
1383   assert (se->ss != NULL && se->ss != gfc_ss_terminator);
1384   assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
1385
1386   gfc_conv_tmp_array_ref (se);
1387   gfc_advance_se_ss_chain (se);
1388 }
1389
1390
1391 /* Build a static initializer.  EXPR is the expression for the initial value.
1392    The other parameters describe the variable of the component being 
1393    initialized. EXPR may be null.  */
1394
1395 tree
1396 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
1397                       bool array, bool pointer)
1398 {
1399   gfc_se se;
1400
1401   if (!(expr || pointer))
1402     return NULL_TREE;
1403
1404   if (array)
1405     {
1406       /* Arrays need special handling.  */
1407       if (pointer)
1408         return gfc_build_null_descriptor (type);
1409       else
1410         return gfc_conv_array_initializer (type, expr);
1411     }
1412   else if (pointer)
1413     return fold_convert (type, null_pointer_node);
1414   else
1415     {
1416       switch (ts->type)
1417         {
1418         case BT_DERIVED:
1419           gfc_init_se (&se, NULL);
1420           gfc_conv_structure (&se, expr, 1);
1421           return se.expr;
1422
1423         case BT_CHARACTER:
1424           return gfc_conv_string_init (ts->cl->backend_decl,expr);
1425
1426         default:
1427           gfc_init_se (&se, NULL);
1428           gfc_conv_constant (&se, expr);
1429           return se.expr;
1430         }
1431     }
1432 }
1433   
1434 static tree
1435 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
1436 {
1437   gfc_se rse;
1438   gfc_se lse;
1439   gfc_ss *rss;
1440   gfc_ss *lss;
1441   stmtblock_t body;
1442   stmtblock_t block;
1443   gfc_loopinfo loop;
1444   int n;
1445   tree tmp;
1446
1447   gfc_start_block (&block);
1448
1449   /* Initialize the scalarizer.  */
1450   gfc_init_loopinfo (&loop);
1451
1452   gfc_init_se (&lse, NULL);
1453   gfc_init_se (&rse, NULL);
1454
1455   /* Walk the rhs.  */
1456   rss = gfc_walk_expr (expr);
1457   if (rss == gfc_ss_terminator)
1458     {
1459       /* The rhs is scalar.  Add a ss for the expression.  */
1460       rss = gfc_get_ss ();
1461       rss->next = gfc_ss_terminator;
1462       rss->type = GFC_SS_SCALAR;
1463       rss->expr = expr;
1464     }
1465
1466   /* Create a SS for the destination.  */
1467   lss = gfc_get_ss ();
1468   lss->type = GFC_SS_COMPONENT;
1469   lss->expr = NULL;
1470   lss->shape = gfc_get_shape (cm->as->rank);
1471   lss->next = gfc_ss_terminator;
1472   lss->data.info.dimen = cm->as->rank;
1473   lss->data.info.descriptor = dest;
1474   lss->data.info.data = gfc_conv_array_data (dest);
1475   lss->data.info.offset = gfc_conv_array_offset (dest);
1476   for (n = 0; n < cm->as->rank; n++)
1477     {
1478       lss->data.info.dim[n] = n;
1479       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
1480       lss->data.info.stride[n] = gfc_index_one_node;
1481
1482       mpz_init (lss->shape[n]);
1483       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
1484                cm->as->lower[n]->value.integer);
1485       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
1486     }
1487   
1488   /* Associate the SS with the loop.  */
1489   gfc_add_ss_to_loop (&loop, lss);
1490   gfc_add_ss_to_loop (&loop, rss);
1491
1492   /* Calculate the bounds of the scalarization.  */
1493   gfc_conv_ss_startstride (&loop);
1494
1495   /* Setup the scalarizing loops.  */
1496   gfc_conv_loop_setup (&loop);
1497
1498   /* Setup the gfc_se structures.  */
1499   gfc_copy_loopinfo_to_se (&lse, &loop);
1500   gfc_copy_loopinfo_to_se (&rse, &loop);
1501
1502   rse.ss = rss;
1503   gfc_mark_ss_chain_used (rss, 1);
1504   lse.ss = lss;
1505   gfc_mark_ss_chain_used (lss, 1);
1506
1507   /* Start the scalarized loop body.  */
1508   gfc_start_scalarized_body (&loop, &body);
1509
1510   gfc_conv_tmp_array_ref (&lse);
1511   gfc_conv_expr (&rse, expr);
1512
1513   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts.type);
1514   gfc_add_expr_to_block (&body, tmp);
1515
1516   if (rse.ss != gfc_ss_terminator)
1517     abort ();
1518
1519   /* Generate the copying loops.  */
1520   gfc_trans_scalarizing_loops (&loop, &body);
1521
1522   /* Wrap the whole thing up.  */
1523   gfc_add_block_to_block (&block, &loop.pre);
1524   gfc_add_block_to_block (&block, &loop.post);
1525
1526   gfc_cleanup_loop (&loop);
1527
1528   for (n = 0; n < cm->as->rank; n++)
1529     mpz_clear (lss->shape[n]);
1530   gfc_free (lss->shape);
1531
1532   return gfc_finish_block (&block);
1533 }
1534
1535 /* Assign a single component of a derived type constructor.  */
1536
1537 static tree
1538 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
1539 {
1540   gfc_se se;
1541   gfc_ss *rss;
1542   stmtblock_t block;
1543   tree tmp;
1544
1545   gfc_start_block (&block);
1546   if (cm->pointer)
1547     {
1548       gfc_init_se (&se, NULL);
1549       /* Pointer component.  */
1550       if (cm->dimension)
1551         {
1552           /* Array pointer.  */
1553           if (expr->expr_type == EXPR_NULL)
1554             {
1555               dest = gfc_conv_descriptor_data (dest);
1556               tmp = fold_convert (TREE_TYPE (se.expr),
1557                                   null_pointer_node);
1558               gfc_add_modify_expr (&block, dest, tmp);
1559             }
1560           else
1561             {
1562               rss = gfc_walk_expr (expr);
1563               se.direct_byref = 1;
1564               se.expr = dest;
1565               gfc_conv_expr_descriptor (&se, expr, rss);
1566               gfc_add_block_to_block (&block, &se.pre);
1567               gfc_add_block_to_block (&block, &se.post);
1568             }
1569         }
1570       else
1571         {
1572           /* Scalar pointers.  */
1573           se.want_pointer = 1;
1574           gfc_conv_expr (&se, expr);
1575           gfc_add_block_to_block (&block, &se.pre);
1576           gfc_add_modify_expr (&block, dest,
1577                                fold_convert (TREE_TYPE (dest), se.expr));
1578           gfc_add_block_to_block (&block, &se.post);
1579         }
1580     }
1581   else if (cm->dimension)
1582     {
1583       tmp = gfc_trans_subarray_assign (dest, cm, expr);
1584       gfc_add_expr_to_block (&block, tmp);
1585     }
1586   else if (expr->ts.type == BT_DERIVED)
1587     {
1588       /* Nested dervived type.  */
1589       tmp = gfc_trans_structure_assign (dest, expr);
1590       gfc_add_expr_to_block (&block, tmp);
1591     }
1592   else
1593     {
1594       /* Scalar component.  */
1595       gfc_se lse;
1596
1597       gfc_init_se (&se, NULL);
1598       gfc_init_se (&lse, NULL);
1599
1600       gfc_conv_expr (&se, expr);
1601       if (cm->ts.type == BT_CHARACTER)
1602         lse.string_length = cm->ts.cl->backend_decl;
1603       lse.expr = dest;
1604       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts.type);
1605       gfc_add_expr_to_block (&block, tmp);
1606     }
1607   return gfc_finish_block (&block);
1608 }
1609
1610 /* Assign a derived type contructor to a variable.  */
1611
1612 static tree
1613 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
1614 {
1615   gfc_constructor *c;
1616   gfc_component *cm;
1617   stmtblock_t block;
1618   tree field;
1619   tree tmp;
1620
1621   gfc_start_block (&block);
1622   cm = expr->ts.derived->components;
1623   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
1624     {
1625       /* Skip absent members in default initializers.  */
1626       if (!c->expr)
1627         continue;
1628
1629       field = cm->backend_decl;
1630       tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
1631       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
1632       gfc_add_expr_to_block (&block, tmp);
1633     }
1634   return gfc_finish_block (&block);
1635 }
1636
1637 /* Build an expression for a constructor. If init is nonzero then
1638    this is part of a static variable initializer.  */
1639
1640 void
1641 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
1642 {
1643   gfc_constructor *c;
1644   gfc_component *cm;
1645   tree head;
1646   tree tail;
1647   tree val;
1648   tree type;
1649   tree tmp;
1650
1651   assert (se->ss == NULL);
1652   assert (expr->expr_type == EXPR_STRUCTURE);
1653   type = gfc_typenode_for_spec (&expr->ts);
1654
1655   if (!init)
1656     {
1657       /* Create a temporary variable and fill it in.  */
1658       se->expr = gfc_create_var (type, expr->ts.derived->name);
1659       tmp = gfc_trans_structure_assign (se->expr, expr);
1660       gfc_add_expr_to_block (&se->pre, tmp);
1661       return;
1662     }
1663
1664   head = build1 (CONSTRUCTOR, type, NULL_TREE);
1665   tail = NULL_TREE;
1666
1667   cm = expr->ts.derived->components;
1668   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
1669     {
1670       /* Skip absent members in default initializers.  */
1671       if (!c->expr)
1672         continue;
1673
1674       val = gfc_conv_initializer (c->expr, &cm->ts,
1675           TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
1676
1677       /* Build a TREE_CHAIN to hold it.  */
1678       val = tree_cons (cm->backend_decl, val, NULL_TREE);
1679
1680       /* Add it to the list.  */
1681       if (tail == NULL_TREE)
1682         TREE_OPERAND(head, 0) = tail = val;
1683       else
1684         {
1685           TREE_CHAIN (tail) = val;
1686           tail = val;
1687         }
1688     }
1689   se->expr = head;
1690 }
1691
1692
1693 /* Translate a substring expression.  */
1694
1695 static void
1696 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
1697 {
1698   gfc_ref *ref;
1699
1700   ref = expr->ref;
1701
1702   assert(ref->type == REF_SUBSTRING);
1703
1704   se->expr = gfc_build_string_const(expr->value.character.length,
1705                                     expr->value.character.string);
1706   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
1707   TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
1708
1709   gfc_conv_substring(se,ref,expr->ts.kind);
1710 }
1711
1712
1713 /* Entry point for expression translation.  */
1714
1715 void
1716 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
1717 {
1718   if (se->ss && se->ss->expr == expr
1719       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
1720     {
1721       /* Substitute a scalar expression evaluated outside the scalarization
1722          loop.  */
1723       se->expr = se->ss->data.scalar.expr;
1724       se->string_length = se->ss->string_length;
1725       gfc_advance_se_ss_chain (se);
1726       return;
1727     }
1728
1729   switch (expr->expr_type)
1730     {
1731     case EXPR_OP:
1732       gfc_conv_expr_op (se, expr);
1733       break;
1734
1735     case EXPR_FUNCTION:
1736       gfc_conv_function_expr (se, expr);
1737       break;
1738
1739     case EXPR_CONSTANT:
1740       gfc_conv_constant (se, expr);
1741       break;
1742
1743     case EXPR_VARIABLE:
1744       gfc_conv_variable (se, expr);
1745       break;
1746
1747     case EXPR_NULL:
1748       se->expr = null_pointer_node;
1749       break;
1750
1751     case EXPR_SUBSTRING:
1752       gfc_conv_substring_expr (se, expr);
1753       break;
1754
1755     case EXPR_STRUCTURE:
1756       gfc_conv_structure (se, expr, 0);
1757       break;
1758
1759     case EXPR_ARRAY:
1760       gfc_conv_array_constructor_expr (se, expr);
1761       break;
1762
1763     default:
1764       abort ();
1765       break;
1766     }
1767 }
1768
1769 void
1770 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
1771 {
1772   gfc_conv_expr (se, expr);
1773   /* AFAICS all numeric lvalues have empty post chains.  If not we need to
1774      figure out a way of rewriting an lvalue so that it has no post chain.  */
1775   assert (expr->ts.type != BT_CHARACTER || !se->post.head);
1776 }
1777
1778 void
1779 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
1780 {
1781   tree val;
1782
1783   assert (expr->ts.type != BT_CHARACTER);
1784   gfc_conv_expr (se, expr);
1785   if (se->post.head)
1786     {
1787       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
1788       gfc_add_modify_expr (&se->pre, val, se->expr);
1789     }
1790 }
1791
1792 void
1793 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
1794 {
1795   gfc_conv_expr_val (se, expr);
1796   se->expr = convert (type, se->expr);
1797 }
1798
1799
1800 /* Converts an expression so that it can be passed by reference.  Scalar
1801    values only.  */
1802
1803 void
1804 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
1805 {
1806   tree var;
1807
1808   if (se->ss && se->ss->expr == expr
1809       && se->ss->type == GFC_SS_REFERENCE)
1810     {
1811       se->expr = se->ss->data.scalar.expr;
1812       se->string_length = se->ss->string_length;
1813       gfc_advance_se_ss_chain (se);
1814       return;
1815     }
1816
1817   if (expr->ts.type == BT_CHARACTER)
1818     {
1819       gfc_conv_expr (se, expr);
1820       gfc_conv_string_parameter (se);
1821       return;
1822     }
1823
1824   if (expr->expr_type == EXPR_VARIABLE)
1825     {
1826       se->want_pointer = 1;
1827       gfc_conv_expr (se, expr);
1828       if (se->post.head)
1829         {
1830           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1831           gfc_add_modify_expr (&se->pre, var, se->expr);
1832           gfc_add_block_to_block (&se->pre, &se->post);
1833           se->expr = var;
1834         }
1835       return;
1836     }
1837
1838   gfc_conv_expr (se, expr);
1839
1840   /* Create a temporary var to hold the value.  */
1841   if (TREE_CONSTANT (se->expr))
1842     {
1843       var = build_decl (CONST_DECL, NULL, TREE_TYPE (se->expr));
1844       DECL_INITIAL (var) = se->expr;
1845       pushdecl (var);
1846     }
1847   else
1848     {
1849       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1850       gfc_add_modify_expr (&se->pre, var, se->expr);
1851     }
1852   gfc_add_block_to_block (&se->pre, &se->post);
1853
1854   /* Take the address of that value.  */
1855   se->expr = gfc_build_addr_expr (NULL, var);
1856 }
1857
1858
1859 tree
1860 gfc_trans_pointer_assign (gfc_code * code)
1861 {
1862   return gfc_trans_pointer_assignment (code->expr, code->expr2);
1863 }
1864
1865
1866 /* Generate code for a pointer assignment.  */
1867
1868 tree
1869 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
1870 {
1871   gfc_se lse;
1872   gfc_se rse;
1873   gfc_ss *lss;
1874   gfc_ss *rss;
1875   stmtblock_t block;
1876
1877   gfc_start_block (&block);
1878
1879   gfc_init_se (&lse, NULL);
1880
1881   lss = gfc_walk_expr (expr1);
1882   rss = gfc_walk_expr (expr2);
1883   if (lss == gfc_ss_terminator)
1884     {
1885       /* Scalar pointers.  */
1886       lse.want_pointer = 1;
1887       gfc_conv_expr (&lse, expr1);
1888       assert (rss == gfc_ss_terminator);
1889       gfc_init_se (&rse, NULL);
1890       rse.want_pointer = 1;
1891       gfc_conv_expr (&rse, expr2);
1892       gfc_add_block_to_block (&block, &lse.pre);
1893       gfc_add_block_to_block (&block, &rse.pre);
1894       gfc_add_modify_expr (&block, lse.expr,
1895                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
1896       gfc_add_block_to_block (&block, &rse.post);
1897       gfc_add_block_to_block (&block, &lse.post);
1898     }
1899   else
1900     {
1901       /* Array pointer.  */
1902       gfc_conv_expr_descriptor (&lse, expr1, lss);
1903       /* Implement Nullify.  */
1904       if (expr2->expr_type == EXPR_NULL)
1905         {
1906           lse.expr = gfc_conv_descriptor_data (lse.expr);
1907           rse.expr = fold_convert (TREE_TYPE (lse.expr), null_pointer_node);
1908           gfc_add_modify_expr (&block, lse.expr, rse.expr);
1909         }
1910       else
1911         {
1912           lse.direct_byref = 1;
1913           gfc_conv_expr_descriptor (&lse, expr2, rss);
1914         }
1915       gfc_add_block_to_block (&block, &lse.pre);
1916       gfc_add_block_to_block (&block, &lse.post);
1917     }
1918   return gfc_finish_block (&block);
1919 }
1920
1921
1922 /* Makes sure se is suitable for passing as a function string parameter.  */
1923 /* TODO: Need to check all callers fo this function.  It may be abused.  */
1924
1925 void
1926 gfc_conv_string_parameter (gfc_se * se)
1927 {
1928   tree type;
1929
1930   if (TREE_CODE (se->expr) == STRING_CST)
1931     {
1932       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
1933       return;
1934     }
1935
1936   type = TREE_TYPE (se->expr);
1937   if (TYPE_STRING_FLAG (type))
1938     {
1939       assert (TREE_CODE (se->expr) != INDIRECT_REF);
1940       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
1941     }
1942
1943   assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
1944   assert (se->string_length
1945           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
1946 }
1947
1948
1949 /* Generate code for assignment of scalar variables.  Includes character
1950    strings.  */
1951
1952 tree
1953 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, bt type)
1954 {
1955   stmtblock_t block;
1956
1957   gfc_init_block (&block);
1958
1959   if (type == BT_CHARACTER)
1960     {
1961       assert (lse->string_length != NULL_TREE
1962               && rse->string_length != NULL_TREE);
1963
1964       gfc_conv_string_parameter (lse);
1965       gfc_conv_string_parameter (rse);
1966
1967       gfc_add_block_to_block (&block, &lse->pre);
1968       gfc_add_block_to_block (&block, &rse->pre);
1969
1970       gfc_trans_string_copy (&block, lse->string_length, lse->expr,
1971                              rse->string_length, rse->expr);
1972     }
1973   else
1974     {
1975       gfc_add_block_to_block (&block, &lse->pre);
1976       gfc_add_block_to_block (&block, &rse->pre);
1977
1978       gfc_add_modify_expr (&block, lse->expr,
1979                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
1980     }
1981
1982   gfc_add_block_to_block (&block, &lse->post);
1983   gfc_add_block_to_block (&block, &rse->post);
1984
1985   return gfc_finish_block (&block);
1986 }
1987
1988
1989 /* Try to translate array(:) = func (...), where func is a transformational
1990    array function, without using a temporary.  Returns NULL is this isn't the
1991    case.  */
1992
1993 static tree
1994 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
1995 {
1996   gfc_se se;
1997   gfc_ss *ss;
1998
1999   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
2000   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
2001     return NULL;
2002
2003   /* Elemental functions don't need a temporary anyway.  */
2004   if (expr2->symtree->n.sym->attr.elemental)
2005     return NULL;
2006
2007   /* Check for a dependency.  */
2008   if (gfc_check_fncall_dependency (expr1, expr2))
2009     return NULL;
2010
2011   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
2012      functions.  */
2013   assert (expr2->value.function.isym
2014           || (gfc_return_by_reference (expr2->symtree->n.sym)
2015               && expr2->symtree->n.sym->result->attr.dimension));
2016
2017   ss = gfc_walk_expr (expr1);
2018   assert (ss != gfc_ss_terminator);
2019   gfc_init_se (&se, NULL);
2020   gfc_start_block (&se.pre);
2021   se.want_pointer = 1;
2022
2023   gfc_conv_array_parameter (&se, expr1, ss, 0);
2024
2025   se.direct_byref = 1;
2026   se.ss = gfc_walk_expr (expr2);
2027   assert (se.ss != gfc_ss_terminator);
2028   gfc_conv_function_expr (&se, expr2);
2029   gfc_add_block_to_block (&se.pre, &se.post);
2030
2031   return gfc_finish_block (&se.pre);
2032 }
2033
2034
2035 /* Translate an assignment.  Most of the code is concerned with
2036    setting up the scalarizer.  */
2037
2038 tree
2039 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2)
2040 {
2041   gfc_se lse;
2042   gfc_se rse;
2043   gfc_ss *lss;
2044   gfc_ss *lss_section;
2045   gfc_ss *rss;
2046   gfc_loopinfo loop;
2047   tree tmp;
2048   stmtblock_t block;
2049   stmtblock_t body;
2050
2051   /* Special case a single function returning an array.  */
2052   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
2053     {
2054       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2055       if (tmp)
2056         return tmp;
2057     }
2058
2059   /* Assignment of the form lhs = rhs.  */
2060   gfc_start_block (&block);
2061
2062   gfc_init_se (&lse, NULL);
2063   gfc_init_se (&rse, NULL);
2064
2065   /* Walk the lhs.  */
2066   lss = gfc_walk_expr (expr1);
2067   rss = NULL;
2068   if (lss != gfc_ss_terminator)
2069     {
2070       /* The assignment needs scalarization.  */
2071       lss_section = lss;
2072
2073       /* Find a non-scalar SS from the lhs.  */
2074       while (lss_section != gfc_ss_terminator
2075              && lss_section->type != GFC_SS_SECTION)
2076         lss_section = lss_section->next;
2077
2078       assert (lss_section != gfc_ss_terminator);
2079
2080       /* Initialize the scalarizer.  */
2081       gfc_init_loopinfo (&loop);
2082
2083       /* Walk the rhs.  */
2084       rss = gfc_walk_expr (expr2);
2085       if (rss == gfc_ss_terminator)
2086         {
2087           /* The rhs is scalar.  Add a ss for the expression.  */
2088           rss = gfc_get_ss ();
2089           rss->next = gfc_ss_terminator;
2090           rss->type = GFC_SS_SCALAR;
2091           rss->expr = expr2;
2092         }
2093       /* Associate the SS with the loop.  */
2094       gfc_add_ss_to_loop (&loop, lss);
2095       gfc_add_ss_to_loop (&loop, rss);
2096
2097       /* Calculate the bounds of the scalarization.  */
2098       gfc_conv_ss_startstride (&loop);
2099       /* Resolve any data dependencies in the statement.  */
2100       gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2101       /* Setup the scalarizing loops.  */
2102       gfc_conv_loop_setup (&loop);
2103
2104       /* Setup the gfc_se structures.  */
2105       gfc_copy_loopinfo_to_se (&lse, &loop);
2106       gfc_copy_loopinfo_to_se (&rse, &loop);
2107
2108       rse.ss = rss;
2109       gfc_mark_ss_chain_used (rss, 1);
2110       if (loop.temp_ss == NULL)
2111         {
2112           lse.ss = lss;
2113           gfc_mark_ss_chain_used (lss, 1);
2114         }
2115       else
2116         {
2117           lse.ss = loop.temp_ss;
2118           gfc_mark_ss_chain_used (lss, 3);
2119           gfc_mark_ss_chain_used (loop.temp_ss, 3);
2120         }
2121
2122       /* Start the scalarized loop body.  */
2123       gfc_start_scalarized_body (&loop, &body);
2124     }
2125   else
2126     gfc_init_block (&body);
2127
2128   /* Translate the expression.  */
2129   gfc_conv_expr (&rse, expr2);
2130
2131   if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2132     {
2133       gfc_conv_tmp_array_ref (&lse);
2134       gfc_advance_se_ss_chain (&lse);
2135     }
2136   else
2137     gfc_conv_expr (&lse, expr1);
2138
2139   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2140   gfc_add_expr_to_block (&body, tmp);
2141
2142   if (lss == gfc_ss_terminator)
2143     {
2144       /* Use the scalar assignment as is.  */
2145       gfc_add_block_to_block (&block, &body);
2146     }
2147   else
2148     {
2149       if (lse.ss != gfc_ss_terminator)
2150         abort ();
2151       if (rse.ss != gfc_ss_terminator)
2152         abort ();
2153
2154       if (loop.temp_ss != NULL)
2155         {
2156           gfc_trans_scalarized_loop_boundary (&loop, &body);
2157
2158           /* We need to copy the temporary to the actual lhs.  */
2159           gfc_init_se (&lse, NULL);
2160           gfc_init_se (&rse, NULL);
2161           gfc_copy_loopinfo_to_se (&lse, &loop);
2162           gfc_copy_loopinfo_to_se (&rse, &loop);
2163
2164           rse.ss = loop.temp_ss;
2165           lse.ss = lss;
2166
2167           gfc_conv_tmp_array_ref (&rse);
2168           gfc_advance_se_ss_chain (&rse);
2169           gfc_conv_expr (&lse, expr1);
2170
2171           if (lse.ss != gfc_ss_terminator)
2172             abort ();
2173
2174           if (rse.ss != gfc_ss_terminator)
2175             abort ();
2176
2177           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2178           gfc_add_expr_to_block (&body, tmp);
2179         }
2180       /* Generate the copying loops.  */
2181       gfc_trans_scalarizing_loops (&loop, &body);
2182
2183       /* Wrap the whole thing up.  */
2184       gfc_add_block_to_block (&block, &loop.pre);
2185       gfc_add_block_to_block (&block, &loop.post);
2186
2187       gfc_cleanup_loop (&loop);
2188     }
2189
2190   return gfc_finish_block (&block);
2191 }
2192
2193 tree
2194 gfc_trans_assign (gfc_code * code)
2195 {
2196   return gfc_trans_assignment (code->expr, code->expr2);
2197 }