OSDN Git Service

fortran/
[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   int kind;
557   int ikind;
558   gfc_se lse;
559   gfc_se rse;
560   tree fndecl;
561   tree tmp;
562
563   gfc_init_se (&lse, se);
564   gfc_conv_expr_val (&lse, expr->op1);
565   gfc_add_block_to_block (&se->pre, &lse.pre);
566
567   gfc_init_se (&rse, se);
568   gfc_conv_expr_val (&rse, expr->op2);
569   gfc_add_block_to_block (&se->pre, &rse.pre);
570
571   if (expr->op2->ts.type == BT_INTEGER
572          && expr->op2->expr_type == EXPR_CONSTANT)
573     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
574       return;        
575
576   kind = expr->op1->ts.kind;
577   switch (expr->op2->ts.type)
578     {
579     case BT_INTEGER:
580       ikind = expr->op2->ts.kind;
581       switch (ikind)
582         {
583         case 1:
584         case 2:
585           rse.expr = convert (gfc_int4_type_node, rse.expr);
586           /* Fall through.  */
587
588         case 4:
589           ikind = 0;
590           break;
591           
592         case 8:
593           ikind = 1;
594           break;
595
596         default:
597           abort();
598         }
599       switch (kind)
600         {
601         case 1:
602         case 2:
603           if (expr->op1->ts.type == BT_INTEGER)
604             lse.expr = convert (gfc_int4_type_node, lse.expr);
605           else
606             abort ();
607           /* Fall through.  */
608
609         case 4:
610           kind = 0;
611           break;
612           
613         case 8:
614           kind = 1;
615           break;
616
617         default:
618           abort();
619         }
620       
621       switch (expr->op1->ts.type)
622         {
623         case BT_INTEGER:
624           fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
625           break;
626
627         case BT_REAL:
628           fndecl = gfor_fndecl_math_powi[kind][ikind].real;
629           break;
630
631         case BT_COMPLEX:
632           fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
633           break;
634
635         default:
636           abort ();
637         }
638       break;
639
640     case BT_REAL:
641       switch (kind)
642         {
643         case 4:
644           fndecl = built_in_decls[BUILT_IN_POWF];
645           break;
646         case 8:
647           fndecl = built_in_decls[BUILT_IN_POW];
648           break;
649         default:
650           abort ();
651         }
652       break;
653
654     case BT_COMPLEX:
655       switch (kind)
656         {
657         case 4:
658           fndecl = gfor_fndecl_math_cpowf;
659           break;
660         case 8:
661           fndecl = gfor_fndecl_math_cpow;
662           break;
663         default:
664           abort ();
665         }
666       break;
667
668     default:
669       abort ();
670       break;
671     }
672
673   tmp = gfc_chainon_list (NULL_TREE, lse.expr);
674   tmp = gfc_chainon_list (tmp, rse.expr);
675   se->expr = fold (gfc_build_function_call (fndecl, tmp));
676 }
677
678
679 /* Generate code to allocate a string temporary.  */
680
681 tree
682 gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
683 {
684   tree var;
685   tree tmp;
686   tree args;
687
688   if (TREE_TYPE (len) != gfc_strlen_type_node)
689     abort ();
690
691   if (gfc_can_put_var_on_stack (len))
692     {
693       /* Create a temporary variable to hold the result.  */
694       tmp = fold (build2 (MINUS_EXPR, gfc_strlen_type_node, len,
695                           convert (gfc_strlen_type_node,
696                                    integer_one_node)));
697       tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
698       tmp = build_array_type (gfc_character1_type_node, tmp);
699       var = gfc_create_var (tmp, "str");
700       var = gfc_build_addr_expr (type, var);
701     }
702   else
703     {
704       /* Allocate a temporary to hold the result.  */
705       var = gfc_create_var (type, "pstr");
706       args = gfc_chainon_list (NULL_TREE, len);
707       tmp = gfc_build_function_call (gfor_fndecl_internal_malloc, args);
708       tmp = convert (type, tmp);
709       gfc_add_modify_expr (&se->pre, var, tmp);
710
711       /* Free the temporary afterwards.  */
712       tmp = convert (pvoid_type_node, var);
713       args = gfc_chainon_list (NULL_TREE, tmp);
714       tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
715       gfc_add_expr_to_block (&se->post, tmp);
716     }
717
718   return var;
719 }
720
721
722 /* Handle a string concatenation operation.  A temporary will be allocated to
723    hold the result.  */
724
725 static void
726 gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
727 {
728   gfc_se lse;
729   gfc_se rse;
730   tree len;
731   tree type;
732   tree var;
733   tree args;
734   tree tmp;
735
736   assert (expr->op1->ts.type == BT_CHARACTER
737           && expr->op2->ts.type == BT_CHARACTER);
738
739   gfc_init_se (&lse, se);
740   gfc_conv_expr (&lse, expr->op1);
741   gfc_conv_string_parameter (&lse);
742   gfc_init_se (&rse, se);
743   gfc_conv_expr (&rse, expr->op2);
744   gfc_conv_string_parameter (&rse);
745
746   gfc_add_block_to_block (&se->pre, &lse.pre);
747   gfc_add_block_to_block (&se->pre, &rse.pre);
748
749   type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
750   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
751   if (len == NULL_TREE)
752     {
753       len = fold (build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
754                           lse.string_length, rse.string_length));
755     }
756
757   type = build_pointer_type (type);
758
759   var = gfc_conv_string_tmp (se, type, len);
760
761   /* Do the actual concatenation.  */
762   args = NULL_TREE;
763   args = gfc_chainon_list (args, len);
764   args = gfc_chainon_list (args, var);
765   args = gfc_chainon_list (args, lse.string_length);
766   args = gfc_chainon_list (args, lse.expr);
767   args = gfc_chainon_list (args, rse.string_length);
768   args = gfc_chainon_list (args, rse.expr);
769   tmp = gfc_build_function_call (gfor_fndecl_concat_string, args);
770   gfc_add_expr_to_block (&se->pre, tmp);
771
772   /* Add the cleanup for the operands.  */
773   gfc_add_block_to_block (&se->pre, &rse.post);
774   gfc_add_block_to_block (&se->pre, &lse.post);
775
776   se->expr = var;
777   se->string_length = len;
778 }
779
780
781 /* Translates an op expression. Common (binary) cases are handled by this
782    function, others are passed on. Recursion is used in either case.
783    We use the fact that (op1.ts == op2.ts) (except for the power
784    operator **).
785    Operators need no special handling for scalarized expressions as long as
786    they call gfc_conv_simple_val to get their operands.
787    Character strings get special handling.  */
788
789 static void
790 gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
791 {
792   enum tree_code code;
793   gfc_se lse;
794   gfc_se rse;
795   tree type;
796   tree tmp;
797   int lop;
798   int checkstring;
799
800   checkstring = 0;
801   lop = 0;
802   switch (expr->operator)
803     {
804     case INTRINSIC_UPLUS:
805       gfc_conv_expr (se, expr->op1);
806       return;
807
808     case INTRINSIC_UMINUS:
809       gfc_conv_unary_op (NEGATE_EXPR, se, expr);
810       return;
811
812     case INTRINSIC_NOT:
813       gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
814       return;
815
816     case INTRINSIC_PLUS:
817       code = PLUS_EXPR;
818       break;
819
820     case INTRINSIC_MINUS:
821       code = MINUS_EXPR;
822       break;
823
824     case INTRINSIC_TIMES:
825       code = MULT_EXPR;
826       break;
827
828     case INTRINSIC_DIVIDE:
829       /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
830          an integer, we must round towards zero, so we use a
831          TRUNC_DIV_EXPR.  */
832       if (expr->ts.type == BT_INTEGER)
833         code = TRUNC_DIV_EXPR;
834       else
835         code = RDIV_EXPR;
836       break;
837
838     case INTRINSIC_POWER:
839       gfc_conv_power_op (se, expr);
840       return;
841
842     case INTRINSIC_CONCAT:
843       gfc_conv_concat_op (se, expr);
844       return;
845
846     case INTRINSIC_AND:
847       code = TRUTH_ANDIF_EXPR;
848       lop = 1;
849       break;
850
851     case INTRINSIC_OR:
852       code = TRUTH_ORIF_EXPR;
853       lop = 1;
854       break;
855
856       /* EQV and NEQV only work on logicals, but since we represent them
857          as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
858     case INTRINSIC_EQ:
859     case INTRINSIC_EQV:
860       code = EQ_EXPR;
861       checkstring = 1;
862       lop = 1;
863       break;
864
865     case INTRINSIC_NE:
866     case INTRINSIC_NEQV:
867       code = NE_EXPR;
868       checkstring = 1;
869       lop = 1;
870       break;
871
872     case INTRINSIC_GT:
873       code = GT_EXPR;
874       checkstring = 1;
875       lop = 1;
876       break;
877
878     case INTRINSIC_GE:
879       code = GE_EXPR;
880       checkstring = 1;
881       lop = 1;
882       break;
883
884     case INTRINSIC_LT:
885       code = LT_EXPR;
886       checkstring = 1;
887       lop = 1;
888       break;
889
890     case INTRINSIC_LE:
891       code = LE_EXPR;
892       checkstring = 1;
893       lop = 1;
894       break;
895
896     case INTRINSIC_USER:
897     case INTRINSIC_ASSIGN:
898       /* These should be converted into function calls by the frontend.  */
899       abort ();
900       return;
901
902     default:
903       fatal_error ("Unknown intrinsic op");
904       return;
905     }
906
907   /* The only exception to this is **, which is handled separately anyway.  */
908   assert (expr->op1->ts.type == expr->op2->ts.type);
909
910   if (checkstring && expr->op1->ts.type != BT_CHARACTER)
911     checkstring = 0;
912
913   /* lhs */
914   gfc_init_se (&lse, se);
915   gfc_conv_expr (&lse, expr->op1);
916   gfc_add_block_to_block (&se->pre, &lse.pre);
917
918   /* rhs */
919   gfc_init_se (&rse, se);
920   gfc_conv_expr (&rse, expr->op2);
921   gfc_add_block_to_block (&se->pre, &rse.pre);
922
923   /* For string comparisons we generate a library call, and compare the return
924      value with 0.  */
925   if (checkstring)
926     {
927       gfc_conv_string_parameter (&lse);
928       gfc_conv_string_parameter (&rse);
929       tmp = NULL_TREE;
930       tmp = gfc_chainon_list (tmp, lse.string_length);
931       tmp = gfc_chainon_list (tmp, lse.expr);
932       tmp = gfc_chainon_list (tmp, rse.string_length);
933       tmp = gfc_chainon_list (tmp, rse.expr);
934
935       /* Build a call for the comparison.  */
936       lse.expr = gfc_build_function_call (gfor_fndecl_compare_string, tmp);
937       gfc_add_block_to_block (&lse.post, &rse.post);
938
939       rse.expr = integer_zero_node;
940     }
941
942   type = gfc_typenode_for_spec (&expr->ts);
943
944   if (lop)
945     {
946       /* The result of logical ops is always boolean_type_node.  */
947       tmp = fold (build2 (code, type, lse.expr, rse.expr));
948       se->expr = convert (type, tmp);
949     }
950   else
951     se->expr = fold (build2 (code, type, lse.expr, rse.expr));
952
953   /* Add the post blocks.  */
954   gfc_add_block_to_block (&se->post, &rse.post);
955   gfc_add_block_to_block (&se->post, &lse.post);
956 }
957
958
959 static void
960 gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
961 {
962   tree tmp;
963
964   if (sym->attr.dummy)
965     {
966       tmp = gfc_get_symbol_decl (sym);
967       assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
968               && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
969
970       se->expr = tmp;
971     }
972   else
973     {
974       if (!sym->backend_decl)
975         sym->backend_decl = gfc_get_extern_function_decl (sym);
976
977       tmp = sym->backend_decl;
978       assert (TREE_CODE (tmp) == FUNCTION_DECL);
979       se->expr = gfc_build_addr_expr (NULL, tmp);
980     }
981 }
982
983
984 /* Generate code for a procedure call.  Note can return se->post != NULL.
985    If se->direct_byref is set then se->expr contains the return parameter.  */
986
987 void
988 gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
989                         gfc_actual_arglist * arg)
990 {
991   tree arglist;
992   tree tmp;
993   tree fntype;
994   gfc_se parmse;
995   gfc_ss *argss;
996   gfc_ss_info *info;
997   int byref;
998   tree type;
999   tree var;
1000   tree len;
1001   tree stringargs;
1002   gfc_formal_arglist *formal;
1003
1004   arglist = NULL_TREE;
1005   stringargs = NULL_TREE;
1006   var = NULL_TREE;
1007   len = NULL_TREE;
1008
1009   if (se->ss != NULL)
1010     {
1011       if (!sym->attr.elemental)
1012         {
1013           assert (se->ss->type == GFC_SS_FUNCTION);
1014           if (se->ss->useflags)
1015             {
1016               assert (gfc_return_by_reference (sym)
1017                       && sym->result->attr.dimension);
1018               assert (se->loop != NULL);
1019
1020               /* Access the previously obtained result.  */
1021               gfc_conv_tmp_array_ref (se);
1022               gfc_advance_se_ss_chain (se);
1023               return;
1024             }
1025         }
1026       info = &se->ss->data.info;
1027     }
1028   else
1029     info = NULL;
1030
1031   byref = gfc_return_by_reference (sym);
1032   if (byref)
1033     {
1034       if (se->direct_byref)
1035         arglist = gfc_chainon_list (arglist, se->expr);
1036       else if (sym->result->attr.dimension)
1037         {
1038           assert (se->loop && se->ss);
1039           /* Set the type of the array.  */
1040           tmp = gfc_typenode_for_spec (&sym->ts);
1041           info->dimen = se->loop->dimen;
1042           /* Allocate a temporary to store the result.  */
1043           gfc_trans_allocate_temp_array (se->loop, info, tmp);
1044
1045           /* Zero the first stride to indicate a temporary.  */
1046           tmp =
1047             gfc_conv_descriptor_stride (info->descriptor, gfc_rank_cst[0]);
1048           gfc_add_modify_expr (&se->pre, tmp,
1049                                convert (TREE_TYPE (tmp), integer_zero_node));
1050           /* Pass the temporary as the first argument.  */
1051           tmp = info->descriptor;
1052           tmp = gfc_build_addr_expr (NULL, tmp);
1053           arglist = gfc_chainon_list (arglist, tmp);
1054         }
1055       else if (sym->ts.type == BT_CHARACTER)
1056         {
1057           assert (sym->ts.cl && sym->ts.cl->length
1058                   && sym->ts.cl->length->expr_type == EXPR_CONSTANT);
1059           len = gfc_conv_mpz_to_tree
1060             (sym->ts.cl->length->value.integer, sym->ts.cl->length->ts.kind);
1061           sym->ts.cl->backend_decl = len;
1062           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
1063           type = build_pointer_type (type);
1064
1065           var = gfc_conv_string_tmp (se, type, len);
1066           arglist = gfc_chainon_list (arglist, var);
1067           arglist = gfc_chainon_list (arglist, convert (gfc_strlen_type_node,
1068                                                         len));
1069         }
1070       else      /* TODO: derived type function return values.  */
1071         abort ();
1072     }
1073
1074   formal = sym->formal;
1075   /* Evaluate the arguments.  */
1076   for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
1077     {
1078       if (arg->expr == NULL)
1079         {
1080
1081           if (se->ignore_optional)
1082             {
1083               /* Some intrinsics have already been resolved to the correct
1084                  parameters.  */
1085               continue;
1086             }
1087           else if (arg->label)
1088             {
1089               has_alternate_specifier = 1;
1090               continue;
1091             }
1092           else
1093             {
1094               /* Pass a NULL pointer for an absent arg.  */
1095               gfc_init_se (&parmse, NULL);
1096               parmse.expr = null_pointer_node;
1097               if (arg->missing_arg_type == BT_CHARACTER)
1098                 {
1099                   stringargs =
1100                     gfc_chainon_list (stringargs,
1101                                       convert (gfc_strlen_type_node,
1102                                                integer_zero_node));
1103                 }
1104             }
1105         }
1106       else if (se->ss && se->ss->useflags)
1107         {
1108           /* An elemental function inside a scalarized loop.  */
1109           gfc_init_se (&parmse, se);
1110           gfc_conv_expr_reference (&parmse, arg->expr);
1111         }
1112       else
1113         {
1114           /* A scalar or transformational function.  */
1115           gfc_init_se (&parmse, NULL);
1116           argss = gfc_walk_expr (arg->expr);
1117
1118           if (argss == gfc_ss_terminator)
1119             {
1120               gfc_conv_expr_reference (&parmse, arg->expr);
1121               if (formal && formal->sym->attr.pointer
1122                   && arg->expr->expr_type != EXPR_NULL)
1123                 {
1124                   /* Scalar pointer dummy args require an extra level of
1125                      indirection. The null pointer already contains
1126                      this level of indirection.  */
1127                   parmse.expr = gfc_build_addr_expr (NULL, parmse.expr);
1128                 }
1129             }
1130           else
1131             {
1132               /* If the procedure requires an explicit interface, the
1133                  actual argument is passed according to the
1134                  corresponding formal argument.  If the corresponding
1135                  formal argument is a POINTER or assumed shape, we do
1136                  not use g77's calling aonvention, and pass the
1137                  address of the array descriptor instead. Otherwise we
1138                  use g77's calling convention.  */
1139               int f;
1140               f = (formal != NULL)
1141                   && !formal->sym->attr.pointer
1142                   && formal->sym->as->type != AS_ASSUMED_SHAPE;
1143               f = f || !sym->attr.always_explicit;
1144               gfc_conv_array_parameter (&parmse, arg->expr, argss, f);
1145             } 
1146         }
1147
1148       gfc_add_block_to_block (&se->pre, &parmse.pre);
1149       gfc_add_block_to_block (&se->post, &parmse.post);
1150
1151       /* Character strings are passed as two paramarers, a length and a
1152          pointer.  */
1153       if (parmse.string_length != NULL_TREE)
1154         stringargs = gfc_chainon_list (stringargs, parmse.string_length);
1155
1156       arglist = gfc_chainon_list (arglist, parmse.expr);
1157     }
1158
1159   /* Add the hidden string length parameters to the arguments.  */
1160   arglist = chainon (arglist, stringargs);
1161
1162   /* Generate the actual call.  */
1163   gfc_conv_function_val (se, sym);
1164   /* If there are alternate return labels, function type should be
1165      integer.  */
1166   if (has_alternate_specifier)
1167     TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
1168
1169   fntype = TREE_TYPE (TREE_TYPE (se->expr));
1170   se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
1171                      arglist, NULL_TREE);
1172
1173   /* If we have a pointer function, but we don't want a pointer, e.g.
1174      something like
1175         x = f()
1176      where f is pointer valued, we have to dereference the result.  */
1177   if (sym->attr.pointer && !se->want_pointer && !byref)
1178     se->expr = gfc_build_indirect_ref (se->expr);
1179
1180   /* A pure function may still have side-effects - it may modify its
1181      parameters.  */
1182   TREE_SIDE_EFFECTS (se->expr) = 1;
1183 #if 0
1184   if (!sym->attr.pure)
1185     TREE_SIDE_EFFECTS (se->expr) = 1;
1186 #endif
1187
1188   if (byref)
1189     {
1190       /* Add the function call to the pre chain.  There is no expression.  */
1191       gfc_add_expr_to_block (&se->pre, se->expr);
1192       se->expr = NULL_TREE;
1193
1194       if (!se->direct_byref)
1195         {
1196           if (sym->result->attr.dimension)
1197             {
1198               if (flag_bounds_check)
1199                 {
1200                   /* Check the data pointer hasn't been modified.  This would
1201                      happen in a function returning a pointer.  */
1202                   tmp = gfc_conv_descriptor_data (info->descriptor);
1203                   tmp = build2 (NE_EXPR, boolean_type_node, tmp, info->data);
1204                   gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
1205                 }
1206               se->expr = info->descriptor;
1207             }
1208           else if (sym->ts.type == BT_CHARACTER)
1209             {
1210               se->expr = var;
1211               se->string_length = len;
1212             }
1213           else
1214             abort ();
1215         }
1216     }
1217 }
1218
1219
1220 /* Generate code to copy a string.  */
1221
1222 static void
1223 gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
1224                        tree slen, tree src)
1225 {
1226   tree tmp;
1227
1228   tmp = NULL_TREE;
1229   tmp = gfc_chainon_list (tmp, dlen);
1230   tmp = gfc_chainon_list (tmp, dest);
1231   tmp = gfc_chainon_list (tmp, slen);
1232   tmp = gfc_chainon_list (tmp, src);
1233   tmp = gfc_build_function_call (gfor_fndecl_copy_string, tmp);
1234   gfc_add_expr_to_block (block, tmp);
1235 }
1236
1237
1238 /* Translate a statement function.
1239    The value of a statement function reference is obtained by evaluating the
1240    expression using the values of the actual arguments for the values of the
1241    corresponding dummy arguments.  */
1242
1243 static void
1244 gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
1245 {
1246   gfc_symbol *sym;
1247   gfc_symbol *fsym;
1248   gfc_formal_arglist *fargs;
1249   gfc_actual_arglist *args;
1250   gfc_se lse;
1251   gfc_se rse;
1252   gfc_saved_var *saved_vars;
1253   tree *temp_vars;
1254   tree type;
1255   tree tmp;
1256   int n;
1257
1258   sym = expr->symtree->n.sym;
1259   args = expr->value.function.actual;
1260   gfc_init_se (&lse, NULL);
1261   gfc_init_se (&rse, NULL);
1262
1263   n = 0;
1264   for (fargs = sym->formal; fargs; fargs = fargs->next)
1265     n++;
1266   saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
1267   temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
1268
1269   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1270     {
1271       /* Each dummy shall be specified, explicitly or implicitly, to be
1272          scalar.  */
1273       assert (fargs->sym->attr.dimension == 0);
1274       fsym = fargs->sym;
1275
1276       /* Create a temporary to hold the value.  */
1277       type = gfc_typenode_for_spec (&fsym->ts);
1278       temp_vars[n] = gfc_create_var (type, fsym->name);
1279
1280       if (fsym->ts.type == BT_CHARACTER)
1281         {
1282           /* Copy string arguments.  */
1283           tree arglen;
1284
1285           assert (fsym->ts.cl && fsym->ts.cl->length
1286                   && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
1287
1288           arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
1289           tmp = gfc_build_addr_expr (build_pointer_type (type),
1290                                      temp_vars[n]);
1291
1292           gfc_conv_expr (&rse, args->expr);
1293           gfc_conv_string_parameter (&rse);
1294           gfc_add_block_to_block (&se->pre, &lse.pre);
1295           gfc_add_block_to_block (&se->pre, &rse.pre);
1296
1297           gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
1298                                  rse.expr);
1299           gfc_add_block_to_block (&se->pre, &lse.post);
1300           gfc_add_block_to_block (&se->pre, &rse.post);
1301         }
1302       else
1303         {
1304           /* For everything else, just evaluate the expression.  */
1305           gfc_conv_expr (&lse, args->expr);
1306
1307           gfc_add_block_to_block (&se->pre, &lse.pre);
1308           gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
1309           gfc_add_block_to_block (&se->pre, &lse.post);
1310         }
1311
1312       args = args->next;
1313     }
1314
1315   /* Use the temporary variables in place of the real ones.  */
1316   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1317     gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
1318
1319   gfc_conv_expr (se, sym->value);
1320
1321   if (sym->ts.type == BT_CHARACTER)
1322     {
1323       gfc_conv_const_charlen (sym->ts.cl);
1324
1325       /* Force the expression to the correct length.  */
1326       if (!INTEGER_CST_P (se->string_length)
1327           || tree_int_cst_lt (se->string_length,
1328                               sym->ts.cl->backend_decl))
1329         {
1330           type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
1331           tmp = gfc_create_var (type, sym->name);
1332           tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
1333           gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
1334                                  se->string_length, se->expr);
1335           se->expr = tmp;
1336         }
1337       se->string_length = sym->ts.cl->backend_decl;
1338     }
1339
1340   /* Restore the original variables.  */
1341   for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
1342     gfc_restore_sym (fargs->sym, &saved_vars[n]);
1343   gfc_free (saved_vars);
1344 }
1345
1346
1347 /* Translate a function expression.  */
1348
1349 static void
1350 gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
1351 {
1352   gfc_symbol *sym;
1353
1354   if (expr->value.function.isym)
1355     {
1356       gfc_conv_intrinsic_function (se, expr);
1357       return;
1358     }
1359
1360   /* We distinguish statement functions from general functions to improve
1361      runtime performance.  */
1362   if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
1363     {
1364       gfc_conv_statement_function (se, expr);
1365       return;
1366     }
1367
1368   /* expr.value.function.esym is the resolved (specific) function symbol for
1369      most functions.  However this isn't set for dummy procedures.  */
1370   sym = expr->value.function.esym;
1371   if (!sym)
1372     sym = expr->symtree->n.sym;
1373   gfc_conv_function_call (se, sym, expr->value.function.actual);
1374 }
1375
1376
1377 static void
1378 gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
1379 {
1380   assert (se->ss != NULL && se->ss != gfc_ss_terminator);
1381   assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
1382
1383   gfc_conv_tmp_array_ref (se);
1384   gfc_advance_se_ss_chain (se);
1385 }
1386
1387
1388 /* Build a static initializer.  EXPR is the expression for the initial value.
1389    The other parameters describe the variable of the component being 
1390    initialized. EXPR may be null.  */
1391
1392 tree
1393 gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
1394                       bool array, bool pointer)
1395 {
1396   gfc_se se;
1397
1398   if (!(expr || pointer))
1399     return NULL_TREE;
1400
1401   if (array)
1402     {
1403       /* Arrays need special handling.  */
1404       if (pointer)
1405         return gfc_build_null_descriptor (type);
1406       else
1407         return gfc_conv_array_initializer (type, expr);
1408     }
1409   else if (pointer)
1410     return fold_convert (type, null_pointer_node);
1411   else
1412     {
1413       switch (ts->type)
1414         {
1415         case BT_DERIVED:
1416           gfc_init_se (&se, NULL);
1417           gfc_conv_structure (&se, expr, 1);
1418           return se.expr;
1419
1420         case BT_CHARACTER:
1421           return gfc_conv_string_init (ts->cl->backend_decl,expr);
1422
1423         default:
1424           gfc_init_se (&se, NULL);
1425           gfc_conv_constant (&se, expr);
1426           return se.expr;
1427         }
1428     }
1429 }
1430   
1431 static tree
1432 gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
1433 {
1434   gfc_se rse;
1435   gfc_se lse;
1436   gfc_ss *rss;
1437   gfc_ss *lss;
1438   stmtblock_t body;
1439   stmtblock_t block;
1440   gfc_loopinfo loop;
1441   int n;
1442   tree tmp;
1443
1444   gfc_start_block (&block);
1445
1446   /* Initialize the scalarizer.  */
1447   gfc_init_loopinfo (&loop);
1448
1449   gfc_init_se (&lse, NULL);
1450   gfc_init_se (&rse, NULL);
1451
1452   /* Walk the rhs.  */
1453   rss = gfc_walk_expr (expr);
1454   if (rss == gfc_ss_terminator)
1455     {
1456       /* The rhs is scalar.  Add a ss for the expression.  */
1457       rss = gfc_get_ss ();
1458       rss->next = gfc_ss_terminator;
1459       rss->type = GFC_SS_SCALAR;
1460       rss->expr = expr;
1461     }
1462
1463   /* Create a SS for the destination.  */
1464   lss = gfc_get_ss ();
1465   lss->type = GFC_SS_COMPONENT;
1466   lss->expr = NULL;
1467   lss->shape = gfc_get_shape (cm->as->rank);
1468   lss->next = gfc_ss_terminator;
1469   lss->data.info.dimen = cm->as->rank;
1470   lss->data.info.descriptor = dest;
1471   lss->data.info.data = gfc_conv_array_data (dest);
1472   lss->data.info.offset = gfc_conv_array_offset (dest);
1473   for (n = 0; n < cm->as->rank; n++)
1474     {
1475       lss->data.info.dim[n] = n;
1476       lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
1477       lss->data.info.stride[n] = gfc_index_one_node;
1478
1479       mpz_init (lss->shape[n]);
1480       mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
1481                cm->as->lower[n]->value.integer);
1482       mpz_add_ui (lss->shape[n], lss->shape[n], 1);
1483     }
1484   
1485   /* Associate the SS with the loop.  */
1486   gfc_add_ss_to_loop (&loop, lss);
1487   gfc_add_ss_to_loop (&loop, rss);
1488
1489   /* Calculate the bounds of the scalarization.  */
1490   gfc_conv_ss_startstride (&loop);
1491
1492   /* Setup the scalarizing loops.  */
1493   gfc_conv_loop_setup (&loop);
1494
1495   /* Setup the gfc_se structures.  */
1496   gfc_copy_loopinfo_to_se (&lse, &loop);
1497   gfc_copy_loopinfo_to_se (&rse, &loop);
1498
1499   rse.ss = rss;
1500   gfc_mark_ss_chain_used (rss, 1);
1501   lse.ss = lss;
1502   gfc_mark_ss_chain_used (lss, 1);
1503
1504   /* Start the scalarized loop body.  */
1505   gfc_start_scalarized_body (&loop, &body);
1506
1507   gfc_conv_tmp_array_ref (&lse);
1508   gfc_conv_expr (&rse, expr);
1509
1510   tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts.type);
1511   gfc_add_expr_to_block (&body, tmp);
1512
1513   if (rse.ss != gfc_ss_terminator)
1514     abort ();
1515
1516   /* Generate the copying loops.  */
1517   gfc_trans_scalarizing_loops (&loop, &body);
1518
1519   /* Wrap the whole thing up.  */
1520   gfc_add_block_to_block (&block, &loop.pre);
1521   gfc_add_block_to_block (&block, &loop.post);
1522
1523   gfc_cleanup_loop (&loop);
1524
1525   for (n = 0; n < cm->as->rank; n++)
1526     mpz_clear (lss->shape[n]);
1527   gfc_free (lss->shape);
1528
1529   return gfc_finish_block (&block);
1530 }
1531
1532 /* Assign a single component of a derived type constructor.  */
1533
1534 static tree
1535 gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
1536 {
1537   gfc_se se;
1538   gfc_ss *rss;
1539   stmtblock_t block;
1540   tree tmp;
1541
1542   gfc_start_block (&block);
1543   if (cm->pointer)
1544     {
1545       gfc_init_se (&se, NULL);
1546       /* Pointer component.  */
1547       if (cm->dimension)
1548         {
1549           /* Array pointer.  */
1550           if (expr->expr_type == EXPR_NULL)
1551             {
1552               dest = gfc_conv_descriptor_data (dest);
1553               tmp = fold_convert (TREE_TYPE (se.expr),
1554                                   null_pointer_node);
1555               gfc_add_modify_expr (&block, dest, tmp);
1556             }
1557           else
1558             {
1559               rss = gfc_walk_expr (expr);
1560               se.direct_byref = 1;
1561               se.expr = dest;
1562               gfc_conv_expr_descriptor (&se, expr, rss);
1563               gfc_add_block_to_block (&block, &se.pre);
1564               gfc_add_block_to_block (&block, &se.post);
1565             }
1566         }
1567       else
1568         {
1569           /* Scalar pointers.  */
1570           se.want_pointer = 1;
1571           gfc_conv_expr (&se, expr);
1572           gfc_add_block_to_block (&block, &se.pre);
1573           gfc_add_modify_expr (&block, dest,
1574                                fold_convert (TREE_TYPE (dest), se.expr));
1575           gfc_add_block_to_block (&block, &se.post);
1576         }
1577     }
1578   else if (cm->dimension)
1579     {
1580       tmp = gfc_trans_subarray_assign (dest, cm, expr);
1581       gfc_add_expr_to_block (&block, tmp);
1582     }
1583   else if (expr->ts.type == BT_DERIVED)
1584     {
1585       /* Nested dervived type.  */
1586       tmp = gfc_trans_structure_assign (dest, expr);
1587       gfc_add_expr_to_block (&block, tmp);
1588     }
1589   else
1590     {
1591       /* Scalar component.  */
1592       gfc_se lse;
1593
1594       gfc_init_se (&se, NULL);
1595       gfc_init_se (&lse, NULL);
1596
1597       gfc_conv_expr (&se, expr);
1598       if (cm->ts.type == BT_CHARACTER)
1599         lse.string_length = cm->ts.cl->backend_decl;
1600       lse.expr = dest;
1601       tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts.type);
1602       gfc_add_expr_to_block (&block, tmp);
1603     }
1604   return gfc_finish_block (&block);
1605 }
1606
1607 /* Assign a derived type contructor to a variable.  */
1608
1609 static tree
1610 gfc_trans_structure_assign (tree dest, gfc_expr * expr)
1611 {
1612   gfc_constructor *c;
1613   gfc_component *cm;
1614   stmtblock_t block;
1615   tree field;
1616   tree tmp;
1617
1618   gfc_start_block (&block);
1619   cm = expr->ts.derived->components;
1620   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
1621     {
1622       /* Skip absent members in default initializers.  */
1623       if (!c->expr)
1624         continue;
1625
1626       field = cm->backend_decl;
1627       tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
1628       tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
1629       gfc_add_expr_to_block (&block, tmp);
1630     }
1631   return gfc_finish_block (&block);
1632 }
1633
1634 /* Build an expression for a constructor. If init is nonzero then
1635    this is part of a static variable initializer.  */
1636
1637 void
1638 gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
1639 {
1640   gfc_constructor *c;
1641   gfc_component *cm;
1642   tree head;
1643   tree tail;
1644   tree val;
1645   tree type;
1646   tree tmp;
1647
1648   assert (se->ss == NULL);
1649   assert (expr->expr_type == EXPR_STRUCTURE);
1650   type = gfc_typenode_for_spec (&expr->ts);
1651
1652   if (!init)
1653     {
1654       /* Create a temporary variable and fill it in.  */
1655       se->expr = gfc_create_var (type, expr->ts.derived->name);
1656       tmp = gfc_trans_structure_assign (se->expr, expr);
1657       gfc_add_expr_to_block (&se->pre, tmp);
1658       return;
1659     }
1660
1661   head = build1 (CONSTRUCTOR, type, NULL_TREE);
1662   tail = NULL_TREE;
1663
1664   cm = expr->ts.derived->components;
1665   for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
1666     {
1667       /* Skip absent members in default initializers.  */
1668       if (!c->expr)
1669         continue;
1670
1671       val = gfc_conv_initializer (c->expr, &cm->ts,
1672           TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
1673
1674       /* Build a TREE_CHAIN to hold it.  */
1675       val = tree_cons (cm->backend_decl, val, NULL_TREE);
1676
1677       /* Add it to the list.  */
1678       if (tail == NULL_TREE)
1679         TREE_OPERAND(head, 0) = tail = val;
1680       else
1681         {
1682           TREE_CHAIN (tail) = val;
1683           tail = val;
1684         }
1685     }
1686   se->expr = head;
1687 }
1688
1689
1690 /* Translate a substring expression.  */
1691
1692 static void
1693 gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
1694 {
1695   gfc_ref *ref;
1696
1697   ref = expr->ref;
1698
1699   assert(ref->type == REF_SUBSTRING);
1700
1701   se->expr = gfc_build_string_const(expr->value.character.length,
1702                                     expr->value.character.string);
1703   se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
1704   TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
1705
1706   gfc_conv_substring(se,ref,expr->ts.kind);
1707 }
1708
1709
1710 /* Entry point for expression translation.  */
1711
1712 void
1713 gfc_conv_expr (gfc_se * se, gfc_expr * expr)
1714 {
1715   if (se->ss && se->ss->expr == expr
1716       && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
1717     {
1718       /* Substitute a scalar expression evaluated outside the scalarization
1719          loop.  */
1720       se->expr = se->ss->data.scalar.expr;
1721       se->string_length = se->ss->string_length;
1722       gfc_advance_se_ss_chain (se);
1723       return;
1724     }
1725
1726   switch (expr->expr_type)
1727     {
1728     case EXPR_OP:
1729       gfc_conv_expr_op (se, expr);
1730       break;
1731
1732     case EXPR_FUNCTION:
1733       gfc_conv_function_expr (se, expr);
1734       break;
1735
1736     case EXPR_CONSTANT:
1737       gfc_conv_constant (se, expr);
1738       break;
1739
1740     case EXPR_VARIABLE:
1741       gfc_conv_variable (se, expr);
1742       break;
1743
1744     case EXPR_NULL:
1745       se->expr = null_pointer_node;
1746       break;
1747
1748     case EXPR_SUBSTRING:
1749       gfc_conv_substring_expr (se, expr);
1750       break;
1751
1752     case EXPR_STRUCTURE:
1753       gfc_conv_structure (se, expr, 0);
1754       break;
1755
1756     case EXPR_ARRAY:
1757       gfc_conv_array_constructor_expr (se, expr);
1758       break;
1759
1760     default:
1761       abort ();
1762       break;
1763     }
1764 }
1765
1766 void
1767 gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
1768 {
1769   gfc_conv_expr (se, expr);
1770   /* AFAICS all numeric lvalues have empty post chains.  If not we need to
1771      figure out a way of rewriting an lvalue so that it has no post chain.  */
1772   assert (expr->ts.type != BT_CHARACTER || !se->post.head);
1773 }
1774
1775 void
1776 gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
1777 {
1778   tree val;
1779
1780   assert (expr->ts.type != BT_CHARACTER);
1781   gfc_conv_expr (se, expr);
1782   if (se->post.head)
1783     {
1784       val = gfc_create_var (TREE_TYPE (se->expr), NULL);
1785       gfc_add_modify_expr (&se->pre, val, se->expr);
1786     }
1787 }
1788
1789 void
1790 gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
1791 {
1792   gfc_conv_expr_val (se, expr);
1793   se->expr = convert (type, se->expr);
1794 }
1795
1796
1797 /* Converts an expression so that it can be passed by reference.  Scalar
1798    values only.  */
1799
1800 void
1801 gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
1802 {
1803   tree var;
1804
1805   if (se->ss && se->ss->expr == expr
1806       && se->ss->type == GFC_SS_REFERENCE)
1807     {
1808       se->expr = se->ss->data.scalar.expr;
1809       se->string_length = se->ss->string_length;
1810       gfc_advance_se_ss_chain (se);
1811       return;
1812     }
1813
1814   if (expr->ts.type == BT_CHARACTER)
1815     {
1816       gfc_conv_expr (se, expr);
1817       gfc_conv_string_parameter (se);
1818       return;
1819     }
1820
1821   if (expr->expr_type == EXPR_VARIABLE)
1822     {
1823       se->want_pointer = 1;
1824       gfc_conv_expr (se, expr);
1825       if (se->post.head)
1826         {
1827           var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1828           gfc_add_modify_expr (&se->pre, var, se->expr);
1829           gfc_add_block_to_block (&se->pre, &se->post);
1830           se->expr = var;
1831         }
1832       return;
1833     }
1834
1835   gfc_conv_expr (se, expr);
1836
1837   /* Create a temporary var to hold the value.  */
1838   if (TREE_CONSTANT (se->expr))
1839     {
1840       var = build_decl (CONST_DECL, NULL, TREE_TYPE (se->expr));
1841       DECL_INITIAL (var) = se->expr;
1842       pushdecl (var);
1843     }
1844   else
1845     {
1846       var = gfc_create_var (TREE_TYPE (se->expr), NULL);
1847       gfc_add_modify_expr (&se->pre, var, se->expr);
1848     }
1849   gfc_add_block_to_block (&se->pre, &se->post);
1850
1851   /* Take the address of that value.  */
1852   se->expr = gfc_build_addr_expr (NULL, var);
1853 }
1854
1855
1856 tree
1857 gfc_trans_pointer_assign (gfc_code * code)
1858 {
1859   return gfc_trans_pointer_assignment (code->expr, code->expr2);
1860 }
1861
1862
1863 /* Generate code for a pointer assignment.  */
1864
1865 tree
1866 gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
1867 {
1868   gfc_se lse;
1869   gfc_se rse;
1870   gfc_ss *lss;
1871   gfc_ss *rss;
1872   stmtblock_t block;
1873
1874   gfc_start_block (&block);
1875
1876   gfc_init_se (&lse, NULL);
1877
1878   lss = gfc_walk_expr (expr1);
1879   rss = gfc_walk_expr (expr2);
1880   if (lss == gfc_ss_terminator)
1881     {
1882       /* Scalar pointers.  */
1883       lse.want_pointer = 1;
1884       gfc_conv_expr (&lse, expr1);
1885       assert (rss == gfc_ss_terminator);
1886       gfc_init_se (&rse, NULL);
1887       rse.want_pointer = 1;
1888       gfc_conv_expr (&rse, expr2);
1889       gfc_add_block_to_block (&block, &lse.pre);
1890       gfc_add_block_to_block (&block, &rse.pre);
1891       gfc_add_modify_expr (&block, lse.expr,
1892                            fold_convert (TREE_TYPE (lse.expr), rse.expr));
1893       gfc_add_block_to_block (&block, &rse.post);
1894       gfc_add_block_to_block (&block, &lse.post);
1895     }
1896   else
1897     {
1898       /* Array pointer.  */
1899       gfc_conv_expr_descriptor (&lse, expr1, lss);
1900       /* Implement Nullify.  */
1901       if (expr2->expr_type == EXPR_NULL)
1902         {
1903           lse.expr = gfc_conv_descriptor_data (lse.expr);
1904           rse.expr = fold_convert (TREE_TYPE (lse.expr), null_pointer_node);
1905           gfc_add_modify_expr (&block, lse.expr, rse.expr);
1906         }
1907       else
1908         {
1909           lse.direct_byref = 1;
1910           gfc_conv_expr_descriptor (&lse, expr2, rss);
1911         }
1912       gfc_add_block_to_block (&block, &lse.pre);
1913       gfc_add_block_to_block (&block, &lse.post);
1914     }
1915   return gfc_finish_block (&block);
1916 }
1917
1918
1919 /* Makes sure se is suitable for passing as a function string parameter.  */
1920 /* TODO: Need to check all callers fo this function.  It may be abused.  */
1921
1922 void
1923 gfc_conv_string_parameter (gfc_se * se)
1924 {
1925   tree type;
1926
1927   if (TREE_CODE (se->expr) == STRING_CST)
1928     {
1929       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
1930       return;
1931     }
1932
1933   type = TREE_TYPE (se->expr);
1934   if (TYPE_STRING_FLAG (type))
1935     {
1936       assert (TREE_CODE (se->expr) != INDIRECT_REF);
1937       se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
1938     }
1939
1940   assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
1941   assert (se->string_length
1942           && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
1943 }
1944
1945
1946 /* Generate code for assignment of scalar variables.  Includes character
1947    strings.  */
1948
1949 tree
1950 gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, bt type)
1951 {
1952   stmtblock_t block;
1953
1954   gfc_init_block (&block);
1955
1956   if (type == BT_CHARACTER)
1957     {
1958       assert (lse->string_length != NULL_TREE
1959               && rse->string_length != NULL_TREE);
1960
1961       gfc_conv_string_parameter (lse);
1962       gfc_conv_string_parameter (rse);
1963
1964       gfc_add_block_to_block (&block, &lse->pre);
1965       gfc_add_block_to_block (&block, &rse->pre);
1966
1967       gfc_trans_string_copy (&block, lse->string_length, lse->expr,
1968                              rse->string_length, rse->expr);
1969     }
1970   else
1971     {
1972       gfc_add_block_to_block (&block, &lse->pre);
1973       gfc_add_block_to_block (&block, &rse->pre);
1974
1975       gfc_add_modify_expr (&block, lse->expr,
1976                            fold_convert (TREE_TYPE (lse->expr), rse->expr));
1977     }
1978
1979   gfc_add_block_to_block (&block, &lse->post);
1980   gfc_add_block_to_block (&block, &rse->post);
1981
1982   return gfc_finish_block (&block);
1983 }
1984
1985
1986 /* Try to translate array(:) = func (...), where func is a transformational
1987    array function, without using a temporary.  Returns NULL is this isn't the
1988    case.  */
1989
1990 static tree
1991 gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
1992 {
1993   gfc_se se;
1994   gfc_ss *ss;
1995
1996   /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
1997   if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
1998     return NULL;
1999
2000   /* Elemental functions don't need a temporary anyway.  */
2001   if (expr2->symtree->n.sym->attr.elemental)
2002     return NULL;
2003
2004   /* Check for a dependency.  */
2005   if (gfc_check_fncall_dependency (expr1, expr2))
2006     return NULL;
2007
2008   /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
2009      functions.  */
2010   assert (expr2->value.function.isym
2011           || (gfc_return_by_reference (expr2->symtree->n.sym)
2012               && expr2->symtree->n.sym->result->attr.dimension));
2013
2014   ss = gfc_walk_expr (expr1);
2015   assert (ss != gfc_ss_terminator);
2016   gfc_init_se (&se, NULL);
2017   gfc_start_block (&se.pre);
2018   se.want_pointer = 1;
2019
2020   gfc_conv_array_parameter (&se, expr1, ss, 0);
2021
2022   se.direct_byref = 1;
2023   se.ss = gfc_walk_expr (expr2);
2024   assert (se.ss != gfc_ss_terminator);
2025   gfc_conv_function_expr (&se, expr2);
2026   gfc_add_block_to_block (&se.pre, &se.post);
2027
2028   return gfc_finish_block (&se.pre);
2029 }
2030
2031
2032 /* Translate an assignment.  Most of the code is concerned with
2033    setting up the scalarizer.  */
2034
2035 tree
2036 gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2)
2037 {
2038   gfc_se lse;
2039   gfc_se rse;
2040   gfc_ss *lss;
2041   gfc_ss *lss_section;
2042   gfc_ss *rss;
2043   gfc_loopinfo loop;
2044   tree tmp;
2045   stmtblock_t block;
2046   stmtblock_t body;
2047
2048   /* Special case a single function returning an array.  */
2049   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
2050     {
2051       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2052       if (tmp)
2053         return tmp;
2054     }
2055
2056   /* Assignment of the form lhs = rhs.  */
2057   gfc_start_block (&block);
2058
2059   gfc_init_se (&lse, NULL);
2060   gfc_init_se (&rse, NULL);
2061
2062   /* Walk the lhs.  */
2063   lss = gfc_walk_expr (expr1);
2064   rss = NULL;
2065   if (lss != gfc_ss_terminator)
2066     {
2067       /* The assignment needs scalarization.  */
2068       lss_section = lss;
2069
2070       /* Find a non-scalar SS from the lhs.  */
2071       while (lss_section != gfc_ss_terminator
2072              && lss_section->type != GFC_SS_SECTION)
2073         lss_section = lss_section->next;
2074
2075       assert (lss_section != gfc_ss_terminator);
2076
2077       /* Initialize the scalarizer.  */
2078       gfc_init_loopinfo (&loop);
2079
2080       /* Walk the rhs.  */
2081       rss = gfc_walk_expr (expr2);
2082       if (rss == gfc_ss_terminator)
2083         {
2084           /* The rhs is scalar.  Add a ss for the expression.  */
2085           rss = gfc_get_ss ();
2086           rss->next = gfc_ss_terminator;
2087           rss->type = GFC_SS_SCALAR;
2088           rss->expr = expr2;
2089         }
2090       /* Associate the SS with the loop.  */
2091       gfc_add_ss_to_loop (&loop, lss);
2092       gfc_add_ss_to_loop (&loop, rss);
2093
2094       /* Calculate the bounds of the scalarization.  */
2095       gfc_conv_ss_startstride (&loop);
2096       /* Resolve any data dependencies in the statement.  */
2097       gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2098       /* Setup the scalarizing loops.  */
2099       gfc_conv_loop_setup (&loop);
2100
2101       /* Setup the gfc_se structures.  */
2102       gfc_copy_loopinfo_to_se (&lse, &loop);
2103       gfc_copy_loopinfo_to_se (&rse, &loop);
2104
2105       rse.ss = rss;
2106       gfc_mark_ss_chain_used (rss, 1);
2107       if (loop.temp_ss == NULL)
2108         {
2109           lse.ss = lss;
2110           gfc_mark_ss_chain_used (lss, 1);
2111         }
2112       else
2113         {
2114           lse.ss = loop.temp_ss;
2115           gfc_mark_ss_chain_used (lss, 3);
2116           gfc_mark_ss_chain_used (loop.temp_ss, 3);
2117         }
2118
2119       /* Start the scalarized loop body.  */
2120       gfc_start_scalarized_body (&loop, &body);
2121     }
2122   else
2123     gfc_init_block (&body);
2124
2125   /* Translate the expression.  */
2126   gfc_conv_expr (&rse, expr2);
2127
2128   if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2129     {
2130       gfc_conv_tmp_array_ref (&lse);
2131       gfc_advance_se_ss_chain (&lse);
2132     }
2133   else
2134     gfc_conv_expr (&lse, expr1);
2135
2136   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2137   gfc_add_expr_to_block (&body, tmp);
2138
2139   if (lss == gfc_ss_terminator)
2140     {
2141       /* Use the scalar assignment as is.  */
2142       gfc_add_block_to_block (&block, &body);
2143     }
2144   else
2145     {
2146       if (lse.ss != gfc_ss_terminator)
2147         abort ();
2148       if (rse.ss != gfc_ss_terminator)
2149         abort ();
2150
2151       if (loop.temp_ss != NULL)
2152         {
2153           gfc_trans_scalarized_loop_boundary (&loop, &body);
2154
2155           /* We need to copy the temporary to the actual lhs.  */
2156           gfc_init_se (&lse, NULL);
2157           gfc_init_se (&rse, NULL);
2158           gfc_copy_loopinfo_to_se (&lse, &loop);
2159           gfc_copy_loopinfo_to_se (&rse, &loop);
2160
2161           rse.ss = loop.temp_ss;
2162           lse.ss = lss;
2163
2164           gfc_conv_tmp_array_ref (&rse);
2165           gfc_advance_se_ss_chain (&rse);
2166           gfc_conv_expr (&lse, expr1);
2167
2168           if (lse.ss != gfc_ss_terminator)
2169             abort ();
2170
2171           if (rse.ss != gfc_ss_terminator)
2172             abort ();
2173
2174           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2175           gfc_add_expr_to_block (&body, tmp);
2176         }
2177       /* Generate the copying loops.  */
2178       gfc_trans_scalarizing_loops (&loop, &body);
2179
2180       /* Wrap the whole thing up.  */
2181       gfc_add_block_to_block (&block, &loop.pre);
2182       gfc_add_block_to_block (&block, &loop.post);
2183
2184       gfc_cleanup_loop (&loop);
2185     }
2186
2187   return gfc_finish_block (&block);
2188 }
2189
2190 tree
2191 gfc_trans_assign (gfc_code * code)
2192 {
2193   return gfc_trans_assignment (code->expr, code->expr2);
2194 }