OSDN Git Service

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