OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [fortran/] [trans-expr.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Expression translation
2
   Copyright (C) 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
21
02110-1301, 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 "ggc.h"
31
#include "toplev.h"
32
#include "real.h"
33
#include "tree-gimple.h"
34
#include "flags.h"
35
#include "gfortran.h"
36
#include "trans.h"
37
#include "trans-const.h"
38
#include "trans-types.h"
39
#include "trans-array.h"
40
/* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
41
#include "trans-stmt.h"
42
#include "dependency.h"
43
 
44
static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
45
static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
46
                                                 gfc_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
  gcc_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
      gcc_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 (CONSTANT_CLASS_P (se->expr))
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
   Also used for arguments to procedures with multiple entry points.  */
123
 
124
tree
125
gfc_conv_expr_present (gfc_symbol * sym)
126
{
127
  tree decl;
128
 
129
  gcc_assert (sym->attr.dummy);
130
 
131
  decl = gfc_get_symbol_decl (sym);
132
  if (TREE_CODE (decl) != PARM_DECL)
133
    {
134
      /* Array parameters use a temporary descriptor, we want the real
135
         parameter.  */
136
      gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
137
             || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
138
      decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
139
    }
140
  return build2 (NE_EXPR, boolean_type_node, decl,
141
                 fold_convert (TREE_TYPE (decl), null_pointer_node));
142
}
143
 
144
 
145
/* Converts a missing, dummy argument into a null or zero.  */
146
 
147
void
148
gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts)
149
{
150
  tree present;
151
  tree tmp;
152
 
153
  present = gfc_conv_expr_present (arg->symtree->n.sym);
154
  tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
155
                convert (TREE_TYPE (se->expr), integer_zero_node));
156
  tmp = gfc_evaluate_now (tmp, &se->pre);
157
  se->expr = tmp;
158
  if (ts.type == BT_CHARACTER)
159
    {
160
      tmp = convert (gfc_charlen_type_node, integer_zero_node);
161
      tmp = build3 (COND_EXPR, gfc_charlen_type_node, present,
162
                    se->string_length, tmp);
163
      tmp = gfc_evaluate_now (tmp, &se->pre);
164
      se->string_length = tmp;
165
    }
166
  return;
167
}
168
 
169
 
170
/* Get the character length of an expression, looking through gfc_refs
171
   if necessary.  */
172
 
173
tree
174
gfc_get_expr_charlen (gfc_expr *e)
175
{
176
  gfc_ref *r;
177
  tree length;
178
 
179
  gcc_assert (e->expr_type == EXPR_VARIABLE
180
              && e->ts.type == BT_CHARACTER);
181
 
182
  length = NULL; /* To silence compiler warning.  */
183
 
184
  /* First candidate: if the variable is of type CHARACTER, the
185
     expression's length could be the length of the character
186
     variable.  */
187
  if (e->symtree->n.sym->ts.type == BT_CHARACTER)
188
    length = e->symtree->n.sym->ts.cl->backend_decl;
189
 
190
  /* Look through the reference chain for component references.  */
191
  for (r = e->ref; r; r = r->next)
192
    {
193
      switch (r->type)
194
        {
195
        case REF_COMPONENT:
196
          if (r->u.c.component->ts.type == BT_CHARACTER)
197
            length = r->u.c.component->ts.cl->backend_decl;
198
          break;
199
 
200
        case REF_ARRAY:
201
          /* Do nothing.  */
202
          break;
203
 
204
        default:
205
          /* We should never got substring references here.  These will be
206
             broken down by the scalarizer.  */
207
          gcc_unreachable ();
208
        }
209
    }
210
 
211
  gcc_assert (length != NULL);
212
  return length;
213
}
214
 
215
 
216
 
217
/* Generate code to initialize a string length variable. Returns the
218
   value.  */
219
 
220
void
221
gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
222
{
223
  gfc_se se;
224
  tree tmp;
225
 
226
  gfc_init_se (&se, NULL);
227
  gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
228
  gfc_add_block_to_block (pblock, &se.pre);
229
 
230
  tmp = cl->backend_decl;
231
  gfc_add_modify_expr (pblock, tmp, se.expr);
232
}
233
 
234
 
235
static void
236
gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind)
237
{
238
  tree tmp;
239
  tree type;
240
  tree var;
241
  gfc_se start;
242
  gfc_se end;
243
 
244
  type = gfc_get_character_type (kind, ref->u.ss.length);
245
  type = build_pointer_type (type);
246
 
247
  var = NULL_TREE;
248
  gfc_init_se (&start, se);
249
  gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
250
  gfc_add_block_to_block (&se->pre, &start.pre);
251
 
252
  if (integer_onep (start.expr))
253
    gfc_conv_string_parameter (se);
254
  else
255
    {
256
      /* Change the start of the string.  */
257
      if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
258
        tmp = se->expr;
259
      else
260
        tmp = gfc_build_indirect_ref (se->expr);
261
      tmp = gfc_build_array_ref (tmp, start.expr);
262
      se->expr = gfc_build_addr_expr (type, tmp);
263
    }
264
 
265
  /* Length = end + 1 - start.  */
266
  gfc_init_se (&end, se);
267
  if (ref->u.ss.end == NULL)
268
    end.expr = se->string_length;
269
  else
270
    {
271
      gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
272
      gfc_add_block_to_block (&se->pre, &end.pre);
273
    }
274
  tmp =
275
    build2 (MINUS_EXPR, gfc_charlen_type_node,
276
            fold_convert (gfc_charlen_type_node, integer_one_node),
277
            start.expr);
278
  tmp = build2 (PLUS_EXPR, gfc_charlen_type_node, end.expr, tmp);
279
  se->string_length = fold (tmp);
280
}
281
 
282
 
283
/* Convert a derived type component reference.  */
284
 
285
static void
286
gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
287
{
288
  gfc_component *c;
289
  tree tmp;
290
  tree decl;
291
  tree field;
292
 
293
  c = ref->u.c.component;
294
 
295
  gcc_assert (c->backend_decl);
296
 
297
  field = c->backend_decl;
298
  gcc_assert (TREE_CODE (field) == FIELD_DECL);
299
  decl = se->expr;
300
  tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
301
 
302
  se->expr = tmp;
303
 
304
  if (c->ts.type == BT_CHARACTER)
305
    {
306
      tmp = c->ts.cl->backend_decl;
307
      /* Components must always be constant length.  */
308
      gcc_assert (tmp && INTEGER_CST_P (tmp));
309
      se->string_length = tmp;
310
    }
311
 
312
  if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
313
    se->expr = gfc_build_indirect_ref (se->expr);
314
}
315
 
316
 
317
/* Return the contents of a variable. Also handles reference/pointer
318
   variables (all Fortran pointer references are implicit).  */
319
 
320
static void
321
gfc_conv_variable (gfc_se * se, gfc_expr * expr)
322
{
323
  gfc_ref *ref;
324
  gfc_symbol *sym;
325
 
326
  sym = expr->symtree->n.sym;
327
  if (se->ss != NULL)
328
    {
329
      /* Check that something hasn't gone horribly wrong.  */
330
      gcc_assert (se->ss != gfc_ss_terminator);
331
      gcc_assert (se->ss->expr == expr);
332
 
333
      /* A scalarized term.  We already know the descriptor.  */
334
      se->expr = se->ss->data.info.descriptor;
335
      se->string_length = se->ss->string_length;
336
      for (ref = se->ss->data.info.ref; ref; ref = ref->next)
337
        if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
338
          break;
339
    }
340
  else
341
    {
342
      tree se_expr = NULL_TREE;
343
 
344
      se->expr = gfc_get_symbol_decl (sym);
345
 
346
      /* Special case for assigning the return value of a function.
347
         Self recursive functions must have an explicit return value.  */
348
      if (se->expr == current_function_decl && sym->attr.function
349
          && (sym->result == sym))
350
        se_expr = gfc_get_fake_result_decl (sym);
351
 
352
      /* Similarly for alternate entry points.  */
353
      else if (sym->attr.function && sym->attr.entry
354
               && (sym->result == sym)
355
               && sym->ns->proc_name->backend_decl == current_function_decl)
356
        {
357
          gfc_entry_list *el = NULL;
358
 
359
          for (el = sym->ns->entries; el; el = el->next)
360
            if (sym == el->sym)
361
              {
362
                se_expr = gfc_get_fake_result_decl (sym);
363
                break;
364
              }
365
        }
366
 
367
      else if (sym->attr.result
368
               && sym->ns->proc_name->backend_decl == current_function_decl
369
               && sym->ns->proc_name->attr.entry_master
370
               && !gfc_return_by_reference (sym->ns->proc_name))
371
        se_expr = gfc_get_fake_result_decl (sym);
372
 
373
      if (se_expr)
374
        se->expr = se_expr;
375
 
376
      /* Procedure actual arguments.  */
377
      else if (sym->attr.flavor == FL_PROCEDURE
378
               && se->expr != current_function_decl)
379
        {
380
          gcc_assert (se->want_pointer);
381
          if (!sym->attr.dummy)
382
            {
383
              gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
384
              se->expr = gfc_build_addr_expr (NULL, se->expr);
385
            }
386
          return;
387
        }
388
 
389
 
390
      /* Dereference the expression, where needed. Since characters
391
         are entirely different from other types, they are treated
392
         separately.  */
393
      if (sym->ts.type == BT_CHARACTER)
394
        {
395
          /* Dereference character pointer dummy arguments
396
             or results.  */
397
          if ((sym->attr.pointer || sym->attr.allocatable)
398
              && (sym->attr.dummy
399
                  || sym->attr.function
400
                  || sym->attr.result))
401
            se->expr = gfc_build_indirect_ref (se->expr);
402
        }
403
      else
404
        {
405
          /* Dereference non-character scalar dummy arguments.  */
406
          if (sym->attr.dummy && !sym->attr.dimension)
407
            se->expr = gfc_build_indirect_ref (se->expr);
408
 
409
          /* Dereference scalar hidden result.  */
410
          if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
411
              && (sym->attr.function || sym->attr.result)
412
              && !sym->attr.dimension && !sym->attr.pointer)
413
            se->expr = gfc_build_indirect_ref (se->expr);
414
 
415
          /* Dereference non-character pointer variables.
416
             These must be dummies, results, or scalars.  */
417
          if ((sym->attr.pointer || sym->attr.allocatable)
418
              && (sym->attr.dummy
419
                  || sym->attr.function
420
                  || sym->attr.result
421
                  || !sym->attr.dimension))
422
            se->expr = gfc_build_indirect_ref (se->expr);
423
        }
424
 
425
      ref = expr->ref;
426
    }
427
 
428
  /* For character variables, also get the length.  */
429
  if (sym->ts.type == BT_CHARACTER)
430
    {
431
      /* If the character length of an entry isn't set, get the length from
432
         the master function instead.  */
433
      if (sym->attr.entry && !sym->ts.cl->backend_decl)
434
        se->string_length = sym->ns->proc_name->ts.cl->backend_decl;
435
      else
436
        se->string_length = sym->ts.cl->backend_decl;
437
      gcc_assert (se->string_length);
438
    }
439
 
440
  while (ref)
441
    {
442
      switch (ref->type)
443
        {
444
        case REF_ARRAY:
445
          /* Return the descriptor if that's what we want and this is an array
446
             section reference.  */
447
          if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
448
            return;
449
/* TODO: Pointers to single elements of array sections, eg elemental subs.  */
450
          /* Return the descriptor for array pointers and allocations.  */
451
          if (se->want_pointer
452
              && ref->next == NULL && (se->descriptor_only))
453
            return;
454
 
455
          gfc_conv_array_ref (se, &ref->u.ar);
456
          /* Return a pointer to an element.  */
457
          break;
458
 
459
        case REF_COMPONENT:
460
          gfc_conv_component_ref (se, ref);
461
          break;
462
 
463
        case REF_SUBSTRING:
464
          gfc_conv_substring (se, ref, expr->ts.kind);
465
          break;
466
 
467
        default:
468
          gcc_unreachable ();
469
          break;
470
        }
471
      ref = ref->next;
472
    }
473
  /* Pointer assignment, allocation or pass by reference.  Arrays are handled
474
     separately.  */
475
  if (se->want_pointer)
476
    {
477
      if (expr->ts.type == BT_CHARACTER)
478
        gfc_conv_string_parameter (se);
479
      else
480
        se->expr = gfc_build_addr_expr (NULL, se->expr);
481
    }
482
}
483
 
484
 
485
/* Unary ops are easy... Or they would be if ! was a valid op.  */
486
 
487
static void
488
gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
489
{
490
  gfc_se operand;
491
  tree type;
492
 
493
  gcc_assert (expr->ts.type != BT_CHARACTER);
494
  /* Initialize the operand.  */
495
  gfc_init_se (&operand, se);
496
  gfc_conv_expr_val (&operand, expr->value.op.op1);
497
  gfc_add_block_to_block (&se->pre, &operand.pre);
498
 
499
  type = gfc_typenode_for_spec (&expr->ts);
500
 
501
  /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
502
     We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
503
     All other unary operators have an equivalent GIMPLE unary operator.  */
504
  if (code == TRUTH_NOT_EXPR)
505
    se->expr = build2 (EQ_EXPR, type, operand.expr,
506
                       convert (type, integer_zero_node));
507
  else
508
    se->expr = build1 (code, type, operand.expr);
509
 
510
}
511
 
512
/* Expand power operator to optimal multiplications when a value is raised
513
   to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
514
   Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
515
   Programming", 3rd Edition, 1998.  */
516
 
517
/* This code is mostly duplicated from expand_powi in the backend.
518
   We establish the "optimal power tree" lookup table with the defined size.
519
   The items in the table are the exponents used to calculate the index
520
   exponents. Any integer n less than the value can get an "addition chain",
521
   with the first node being one.  */
522
#define POWI_TABLE_SIZE 256
523
 
524
/* The table is from builtins.c.  */
525
static const unsigned char powi_table[POWI_TABLE_SIZE] =
526
  {
527
      0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
528
      4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
529
      8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
530
     12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
531
     16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
532
     20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
533
     24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
534
     28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
535
     32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
536
     36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
537
     40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
538
     44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
539
     48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
540
     52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
541
     56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
542
     60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
543
     64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
544
     68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
545
     72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
546
     76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
547
     80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
548
     84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
549
     88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
550
     92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
551
     96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
552
    100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
553
    104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
554
    108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
555
    112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
556
    116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
557
    120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
558
    124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
559
  };
560
 
561
/* If n is larger than lookup table's max index, we use the "window
562
   method".  */
563
#define POWI_WINDOW_SIZE 3
564
 
565
/* Recursive function to expand the power operator. The temporary
566
   values are put in tmpvar. The function returns tmpvar[1] ** n.  */
567
static tree
568
gfc_conv_powi (gfc_se * se, int n, tree * tmpvar)
569
{
570
  tree op0;
571
  tree op1;
572
  tree tmp;
573
  int digit;
574
 
575
  if (n < POWI_TABLE_SIZE)
576
    {
577
      if (tmpvar[n])
578
        return tmpvar[n];
579
 
580
      op0 = gfc_conv_powi (se, n - powi_table[n], tmpvar);
581
      op1 = gfc_conv_powi (se, powi_table[n], tmpvar);
582
    }
583
  else if (n & 1)
584
    {
585
      digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
586
      op0 = gfc_conv_powi (se, n - digit, tmpvar);
587
      op1 = gfc_conv_powi (se, digit, tmpvar);
588
    }
589
  else
590
    {
591
      op0 = gfc_conv_powi (se, n >> 1, tmpvar);
592
      op1 = op0;
593
    }
594
 
595
  tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
596
  tmp = gfc_evaluate_now (tmp, &se->pre);
597
 
598
  if (n < POWI_TABLE_SIZE)
599
    tmpvar[n] = tmp;
600
 
601
  return tmp;
602
}
603
 
604
 
605
/* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
606
   return 1. Else return 0 and a call to runtime library functions
607
   will have to be built.  */
608
static int
609
gfc_conv_cst_int_power (gfc_se * se, tree lhs, tree rhs)
610
{
611
  tree cond;
612
  tree tmp;
613
  tree type;
614
  tree vartmp[POWI_TABLE_SIZE];
615
  int n;
616
  int sgn;
617
 
618
  type = TREE_TYPE (lhs);
619
  n = abs (TREE_INT_CST_LOW (rhs));
620
  sgn = tree_int_cst_sgn (rhs);
621
 
622
  if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) || optimize_size)
623
      && (n > 2 || n < -1))
624
    return 0;
625
 
626
  /* rhs == 0  */
627
  if (sgn == 0)
628
    {
629
      se->expr = gfc_build_const (type, integer_one_node);
630
      return 1;
631
    }
632
  /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1.  */
633
  if ((sgn == -1) && (TREE_CODE (type) == INTEGER_TYPE))
634
    {
635
      tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
636
                    fold_convert (TREE_TYPE (lhs), integer_minus_one_node));
637
      cond = build2 (EQ_EXPR, boolean_type_node, lhs,
638
                     convert (TREE_TYPE (lhs), integer_one_node));
639
 
640
      /* If rhs is even,
641
         result = (lhs == 1 || lhs == -1) ? 1 : 0.  */
642
      if ((n & 1) == 0)
643
        {
644
          tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
645
          se->expr = build3 (COND_EXPR, type, tmp,
646
                             convert (type, integer_one_node),
647
                             convert (type, integer_zero_node));
648
          return 1;
649
        }
650
      /* If rhs is odd,
651
         result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0.  */
652
      tmp = build3 (COND_EXPR, type, tmp,
653
                    convert (type, integer_minus_one_node),
654
                    convert (type, integer_zero_node));
655
      se->expr = build3 (COND_EXPR, type, cond,
656
                         convert (type, integer_one_node),
657
                         tmp);
658
      return 1;
659
    }
660
 
661
  memset (vartmp, 0, sizeof (vartmp));
662
  vartmp[1] = lhs;
663
  if (sgn == -1)
664
    {
665
      tmp = gfc_build_const (type, integer_one_node);
666
      vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
667
    }
668
 
669
  se->expr = gfc_conv_powi (se, n, vartmp);
670
 
671
  return 1;
672
}
673
 
674
 
675
/* Power op (**).  Constant integer exponent has special handling.  */
676
 
677
static void
678
gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
679
{
680
  tree gfc_int4_type_node;
681
  int kind;
682
  int ikind;
683
  gfc_se lse;
684
  gfc_se rse;
685
  tree fndecl;
686
  tree tmp;
687
 
688
  gfc_init_se (&lse, se);
689
  gfc_conv_expr_val (&lse, expr->value.op.op1);
690
  lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
691
  gfc_add_block_to_block (&se->pre, &lse.pre);
692
 
693
  gfc_init_se (&rse, se);
694
  gfc_conv_expr_val (&rse, expr->value.op.op2);
695
  gfc_add_block_to_block (&se->pre, &rse.pre);
696
 
697
  if (expr->value.op.op2->ts.type == BT_INTEGER
698
         && expr->value.op.op2->expr_type == EXPR_CONSTANT)
699
    if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
700
      return;
701
 
702
  gfc_int4_type_node = gfc_get_int_type (4);
703
 
704
  kind = expr->value.op.op1->ts.kind;
705
  switch (expr->value.op.op2->ts.type)
706
    {
707
    case BT_INTEGER:
708
      ikind = expr->value.op.op2->ts.kind;
709
      switch (ikind)
710
        {
711
        case 1:
712
        case 2:
713
          rse.expr = convert (gfc_int4_type_node, rse.expr);
714
          /* Fall through.  */
715
 
716
        case 4:
717
          ikind = 0;
718
          break;
719
 
720
        case 8:
721
          ikind = 1;
722
          break;
723
 
724
        case 16:
725
          ikind = 2;
726
          break;
727
 
728
        default:
729
          gcc_unreachable ();
730
        }
731
      switch (kind)
732
        {
733
        case 1:
734
        case 2:
735
          if (expr->value.op.op1->ts.type == BT_INTEGER)
736
            lse.expr = convert (gfc_int4_type_node, lse.expr);
737
          else
738
            gcc_unreachable ();
739
          /* Fall through.  */
740
 
741
        case 4:
742
          kind = 0;
743
          break;
744
 
745
        case 8:
746
          kind = 1;
747
          break;
748
 
749
        case 10:
750
          kind = 2;
751
          break;
752
 
753
        case 16:
754
          kind = 3;
755
          break;
756
 
757
        default:
758
          gcc_unreachable ();
759
        }
760
 
761
      switch (expr->value.op.op1->ts.type)
762
        {
763
        case BT_INTEGER:
764
          if (kind == 3) /* Case 16 was not handled properly above.  */
765
            kind = 2;
766
          fndecl = gfor_fndecl_math_powi[kind][ikind].integer;
767
          break;
768
 
769
        case BT_REAL:
770
          fndecl = gfor_fndecl_math_powi[kind][ikind].real;
771
          break;
772
 
773
        case BT_COMPLEX:
774
          fndecl = gfor_fndecl_math_powi[kind][ikind].cmplx;
775
          break;
776
 
777
        default:
778
          gcc_unreachable ();
779
        }
780
      break;
781
 
782
    case BT_REAL:
783
      switch (kind)
784
        {
785
        case 4:
786
          fndecl = built_in_decls[BUILT_IN_POWF];
787
          break;
788
        case 8:
789
          fndecl = built_in_decls[BUILT_IN_POW];
790
          break;
791
        case 10:
792
        case 16:
793
          fndecl = built_in_decls[BUILT_IN_POWL];
794
          break;
795
        default:
796
          gcc_unreachable ();
797
        }
798
      break;
799
 
800
    case BT_COMPLEX:
801
      switch (kind)
802
        {
803
        case 4:
804
          fndecl = gfor_fndecl_math_cpowf;
805
          break;
806
        case 8:
807
          fndecl = gfor_fndecl_math_cpow;
808
          break;
809
        case 10:
810
          fndecl = gfor_fndecl_math_cpowl10;
811
          break;
812
        case 16:
813
          fndecl = gfor_fndecl_math_cpowl16;
814
          break;
815
        default:
816
          gcc_unreachable ();
817
        }
818
      break;
819
 
820
    default:
821
      gcc_unreachable ();
822
      break;
823
    }
824
 
825
  tmp = gfc_chainon_list (NULL_TREE, lse.expr);
826
  tmp = gfc_chainon_list (tmp, rse.expr);
827
  se->expr = fold (gfc_build_function_call (fndecl, tmp));
828
}
829
 
830
 
831
/* Generate code to allocate a string temporary.  */
832
 
833
tree
834
gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
835
{
836
  tree var;
837
  tree tmp;
838
  tree args;
839
 
840
  gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
841
 
842
  if (gfc_can_put_var_on_stack (len))
843
    {
844
      /* Create a temporary variable to hold the result.  */
845
      tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
846
                         convert (gfc_charlen_type_node, integer_one_node));
847
      tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
848
      tmp = build_array_type (gfc_character1_type_node, tmp);
849
      var = gfc_create_var (tmp, "str");
850
      var = gfc_build_addr_expr (type, var);
851
    }
852
  else
853
    {
854
      /* Allocate a temporary to hold the result.  */
855
      var = gfc_create_var (type, "pstr");
856
      args = gfc_chainon_list (NULL_TREE, len);
857
      tmp = gfc_build_function_call (gfor_fndecl_internal_malloc, args);
858
      tmp = convert (type, tmp);
859
      gfc_add_modify_expr (&se->pre, var, tmp);
860
 
861
      /* Free the temporary afterwards.  */
862
      tmp = convert (pvoid_type_node, var);
863
      args = gfc_chainon_list (NULL_TREE, tmp);
864
      tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
865
      gfc_add_expr_to_block (&se->post, tmp);
866
    }
867
 
868
  return var;
869
}
870
 
871
 
872
/* Handle a string concatenation operation.  A temporary will be allocated to
873
   hold the result.  */
874
 
875
static void
876
gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
877
{
878
  gfc_se lse;
879
  gfc_se rse;
880
  tree len;
881
  tree type;
882
  tree var;
883
  tree args;
884
  tree tmp;
885
 
886
  gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
887
          && expr->value.op.op2->ts.type == BT_CHARACTER);
888
 
889
  gfc_init_se (&lse, se);
890
  gfc_conv_expr (&lse, expr->value.op.op1);
891
  gfc_conv_string_parameter (&lse);
892
  gfc_init_se (&rse, se);
893
  gfc_conv_expr (&rse, expr->value.op.op2);
894
  gfc_conv_string_parameter (&rse);
895
 
896
  gfc_add_block_to_block (&se->pre, &lse.pre);
897
  gfc_add_block_to_block (&se->pre, &rse.pre);
898
 
899
  type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
900
  len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
901
  if (len == NULL_TREE)
902
    {
903
      len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
904
                         lse.string_length, rse.string_length);
905
    }
906
 
907
  type = build_pointer_type (type);
908
 
909
  var = gfc_conv_string_tmp (se, type, len);
910
 
911
  /* Do the actual concatenation.  */
912
  args = NULL_TREE;
913
  args = gfc_chainon_list (args, len);
914
  args = gfc_chainon_list (args, var);
915
  args = gfc_chainon_list (args, lse.string_length);
916
  args = gfc_chainon_list (args, lse.expr);
917
  args = gfc_chainon_list (args, rse.string_length);
918
  args = gfc_chainon_list (args, rse.expr);
919
  tmp = gfc_build_function_call (gfor_fndecl_concat_string, args);
920
  gfc_add_expr_to_block (&se->pre, tmp);
921
 
922
  /* Add the cleanup for the operands.  */
923
  gfc_add_block_to_block (&se->pre, &rse.post);
924
  gfc_add_block_to_block (&se->pre, &lse.post);
925
 
926
  se->expr = var;
927
  se->string_length = len;
928
}
929
 
930
/* Translates an op expression. Common (binary) cases are handled by this
931
   function, others are passed on. Recursion is used in either case.
932
   We use the fact that (op1.ts == op2.ts) (except for the power
933
   operator **).
934
   Operators need no special handling for scalarized expressions as long as
935
   they call gfc_conv_simple_val to get their operands.
936
   Character strings get special handling.  */
937
 
938
static void
939
gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
940
{
941
  enum tree_code code;
942
  gfc_se lse;
943
  gfc_se rse;
944
  tree type;
945
  tree tmp;
946
  int lop;
947
  int checkstring;
948
 
949
  checkstring = 0;
950
  lop = 0;
951
  switch (expr->value.op.operator)
952
    {
953
    case INTRINSIC_UPLUS:
954
    case INTRINSIC_PARENTHESES:
955
      gfc_conv_expr (se, expr->value.op.op1);
956
      return;
957
 
958
    case INTRINSIC_UMINUS:
959
      gfc_conv_unary_op (NEGATE_EXPR, se, expr);
960
      return;
961
 
962
    case INTRINSIC_NOT:
963
      gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
964
      return;
965
 
966
    case INTRINSIC_PLUS:
967
      code = PLUS_EXPR;
968
      break;
969
 
970
    case INTRINSIC_MINUS:
971
      code = MINUS_EXPR;
972
      break;
973
 
974
    case INTRINSIC_TIMES:
975
      code = MULT_EXPR;
976
      break;
977
 
978
    case INTRINSIC_DIVIDE:
979
      /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
980
         an integer, we must round towards zero, so we use a
981
         TRUNC_DIV_EXPR.  */
982
      if (expr->ts.type == BT_INTEGER)
983
        code = TRUNC_DIV_EXPR;
984
      else
985
        code = RDIV_EXPR;
986
      break;
987
 
988
    case INTRINSIC_POWER:
989
      gfc_conv_power_op (se, expr);
990
      return;
991
 
992
    case INTRINSIC_CONCAT:
993
      gfc_conv_concat_op (se, expr);
994
      return;
995
 
996
    case INTRINSIC_AND:
997
      code = TRUTH_ANDIF_EXPR;
998
      lop = 1;
999
      break;
1000
 
1001
    case INTRINSIC_OR:
1002
      code = TRUTH_ORIF_EXPR;
1003
      lop = 1;
1004
      break;
1005
 
1006
      /* EQV and NEQV only work on logicals, but since we represent them
1007
         as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
1008
    case INTRINSIC_EQ:
1009
    case INTRINSIC_EQV:
1010
      code = EQ_EXPR;
1011
      checkstring = 1;
1012
      lop = 1;
1013
      break;
1014
 
1015
    case INTRINSIC_NE:
1016
    case INTRINSIC_NEQV:
1017
      code = NE_EXPR;
1018
      checkstring = 1;
1019
      lop = 1;
1020
      break;
1021
 
1022
    case INTRINSIC_GT:
1023
      code = GT_EXPR;
1024
      checkstring = 1;
1025
      lop = 1;
1026
      break;
1027
 
1028
    case INTRINSIC_GE:
1029
      code = GE_EXPR;
1030
      checkstring = 1;
1031
      lop = 1;
1032
      break;
1033
 
1034
    case INTRINSIC_LT:
1035
      code = LT_EXPR;
1036
      checkstring = 1;
1037
      lop = 1;
1038
      break;
1039
 
1040
    case INTRINSIC_LE:
1041
      code = LE_EXPR;
1042
      checkstring = 1;
1043
      lop = 1;
1044
      break;
1045
 
1046
    case INTRINSIC_USER:
1047
    case INTRINSIC_ASSIGN:
1048
      /* These should be converted into function calls by the frontend.  */
1049
      gcc_unreachable ();
1050
 
1051
    default:
1052
      fatal_error ("Unknown intrinsic op");
1053
      return;
1054
    }
1055
 
1056
  /* The only exception to this is **, which is handled separately anyway.  */
1057
  gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
1058
 
1059
  if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
1060
    checkstring = 0;
1061
 
1062
  /* lhs */
1063
  gfc_init_se (&lse, se);
1064
  gfc_conv_expr (&lse, expr->value.op.op1);
1065
  gfc_add_block_to_block (&se->pre, &lse.pre);
1066
 
1067
  /* rhs */
1068
  gfc_init_se (&rse, se);
1069
  gfc_conv_expr (&rse, expr->value.op.op2);
1070
  gfc_add_block_to_block (&se->pre, &rse.pre);
1071
 
1072
  if (checkstring)
1073
    {
1074
      gfc_conv_string_parameter (&lse);
1075
      gfc_conv_string_parameter (&rse);
1076
 
1077
      lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1078
                                           rse.string_length, rse.expr);
1079
      rse.expr = integer_zero_node;
1080
      gfc_add_block_to_block (&lse.post, &rse.post);
1081
    }
1082
 
1083
  type = gfc_typenode_for_spec (&expr->ts);
1084
 
1085
  if (lop)
1086
    {
1087
      /* The result of logical ops is always boolean_type_node.  */
1088
      tmp = fold_build2 (code, type, lse.expr, rse.expr);
1089
      se->expr = convert (type, tmp);
1090
    }
1091
  else
1092
    se->expr = fold_build2 (code, type, lse.expr, rse.expr);
1093
 
1094
  /* Add the post blocks.  */
1095
  gfc_add_block_to_block (&se->post, &rse.post);
1096
  gfc_add_block_to_block (&se->post, &lse.post);
1097
}
1098
 
1099
/* If a string's length is one, we convert it to a single character.  */
1100
 
1101
static tree
1102
gfc_to_single_character (tree len, tree str)
1103
{
1104
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
1105
 
1106
  if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
1107
    && TREE_INT_CST_HIGH (len) == 0)
1108
    {
1109
      str = fold_convert (pchar_type_node, str);
1110
      return build_fold_indirect_ref (str);
1111
    }
1112
 
1113
  return NULL_TREE;
1114
}
1115
 
1116
/* Compare two strings. If they are all single characters, the result is the
1117
   subtraction of them. Otherwise, we build a library call.  */
1118
 
1119
tree
1120
gfc_build_compare_string (tree len1, tree str1, tree len2, tree str2)
1121
{
1122
  tree sc1;
1123
  tree sc2;
1124
  tree type;
1125
  tree tmp;
1126
 
1127
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1)));
1128
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2)));
1129
 
1130
  type = gfc_get_int_type (gfc_default_integer_kind);
1131
 
1132
  sc1 = gfc_to_single_character (len1, str1);
1133
  sc2 = gfc_to_single_character (len2, str2);
1134
 
1135
  /* Deal with single character specially.  */
1136
  if (sc1 != NULL_TREE && sc2 != NULL_TREE)
1137
    {
1138
      sc1 = fold_convert (type, sc1);
1139
      sc2 = fold_convert (type, sc2);
1140
      tmp = fold_build2 (MINUS_EXPR, type, sc1, sc2);
1141
    }
1142
   else
1143
    {
1144
      tmp = NULL_TREE;
1145
      tmp = gfc_chainon_list (tmp, len1);
1146
      tmp = gfc_chainon_list (tmp, str1);
1147
      tmp = gfc_chainon_list (tmp, len2);
1148
      tmp = gfc_chainon_list (tmp, str2);
1149
 
1150
      /* Build a call for the comparison.  */
1151
      tmp = build_function_call_expr (gfor_fndecl_compare_string, tmp);
1152
    }
1153
 
1154
  return tmp;
1155
}
1156
 
1157
static void
1158
gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
1159
{
1160
  tree tmp;
1161
 
1162
  if (sym->attr.dummy)
1163
    {
1164
      tmp = gfc_get_symbol_decl (sym);
1165
      gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
1166
              && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
1167
    }
1168
  else
1169
    {
1170
      if (!sym->backend_decl)
1171
        sym->backend_decl = gfc_get_extern_function_decl (sym);
1172
 
1173
      tmp = sym->backend_decl;
1174
      if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1175
        {
1176
          gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
1177
          tmp = gfc_build_addr_expr (NULL, tmp);
1178
        }
1179
    }
1180
  se->expr = tmp;
1181
}
1182
 
1183
 
1184
/* Initialize MAPPING.  */
1185
 
1186
void
1187
gfc_init_interface_mapping (gfc_interface_mapping * mapping)
1188
{
1189
  mapping->syms = NULL;
1190
  mapping->charlens = NULL;
1191
}
1192
 
1193
 
1194
/* Free all memory held by MAPPING (but not MAPPING itself).  */
1195
 
1196
void
1197
gfc_free_interface_mapping (gfc_interface_mapping * mapping)
1198
{
1199
  gfc_interface_sym_mapping *sym;
1200
  gfc_interface_sym_mapping *nextsym;
1201
  gfc_charlen *cl;
1202
  gfc_charlen *nextcl;
1203
 
1204
  for (sym = mapping->syms; sym; sym = nextsym)
1205
    {
1206
      nextsym = sym->next;
1207
      gfc_free_symbol (sym->new->n.sym);
1208
      gfc_free (sym->new);
1209
      gfc_free (sym);
1210
    }
1211
  for (cl = mapping->charlens; cl; cl = nextcl)
1212
    {
1213
      nextcl = cl->next;
1214
      gfc_free_expr (cl->length);
1215
      gfc_free (cl);
1216
    }
1217
}
1218
 
1219
 
1220
/* Return a copy of gfc_charlen CL.  Add the returned structure to
1221
   MAPPING so that it will be freed by gfc_free_interface_mapping.  */
1222
 
1223
static gfc_charlen *
1224
gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
1225
                                   gfc_charlen * cl)
1226
{
1227
  gfc_charlen *new;
1228
 
1229
  new = gfc_get_charlen ();
1230
  new->next = mapping->charlens;
1231
  new->length = gfc_copy_expr (cl->length);
1232
 
1233
  mapping->charlens = new;
1234
  return new;
1235
}
1236
 
1237
 
1238
/* A subroutine of gfc_add_interface_mapping.  Return a descriptorless
1239
   array variable that can be used as the actual argument for dummy
1240
   argument SYM.  Add any initialization code to BLOCK.  PACKED is as
1241
   for gfc_get_nodesc_array_type and DATA points to the first element
1242
   in the passed array.  */
1243
 
1244
static tree
1245
gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
1246
                                 int packed, tree data)
1247
{
1248
  tree type;
1249
  tree var;
1250
 
1251
  type = gfc_typenode_for_spec (&sym->ts);
1252
  type = gfc_get_nodesc_array_type (type, sym->as, packed);
1253
 
1254
  var = gfc_create_var (type, "ifm");
1255
  gfc_add_modify_expr (block, var, fold_convert (type, data));
1256
 
1257
  return var;
1258
}
1259
 
1260
 
1261
/* A subroutine of gfc_add_interface_mapping.  Set the stride, upper bounds
1262
   and offset of descriptorless array type TYPE given that it has the same
1263
   size as DESC.  Add any set-up code to BLOCK.  */
1264
 
1265
static void
1266
gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
1267
{
1268
  int n;
1269
  tree dim;
1270
  tree offset;
1271
  tree tmp;
1272
 
1273
  offset = gfc_index_zero_node;
1274
  for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++)
1275
    {
1276
      GFC_TYPE_ARRAY_STRIDE (type, n) = gfc_conv_array_stride (desc, n);
1277
      if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
1278
        {
1279
          dim = gfc_rank_cst[n];
1280
          tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1281
                             gfc_conv_descriptor_ubound (desc, dim),
1282
                             gfc_conv_descriptor_lbound (desc, dim));
1283
          tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1284
                             GFC_TYPE_ARRAY_LBOUND (type, n),
1285
                             tmp);
1286
          tmp = gfc_evaluate_now (tmp, block);
1287
          GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
1288
        }
1289
      tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
1290
                         GFC_TYPE_ARRAY_LBOUND (type, n),
1291
                         GFC_TYPE_ARRAY_STRIDE (type, n));
1292
      offset = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp);
1293
    }
1294
  offset = gfc_evaluate_now (offset, block);
1295
  GFC_TYPE_ARRAY_OFFSET (type) = offset;
1296
}
1297
 
1298
 
1299
/* Extend MAPPING so that it maps dummy argument SYM to the value stored
1300
   in SE.  The caller may still use se->expr and se->string_length after
1301
   calling this function.  */
1302
 
1303
void
1304
gfc_add_interface_mapping (gfc_interface_mapping * mapping,
1305
                           gfc_symbol * sym, gfc_se * se)
1306
{
1307
  gfc_interface_sym_mapping *sm;
1308
  tree desc;
1309
  tree tmp;
1310
  tree value;
1311
  gfc_symbol *new_sym;
1312
  gfc_symtree *root;
1313
  gfc_symtree *new_symtree;
1314
 
1315
  /* Create a new symbol to represent the actual argument.  */
1316
  new_sym = gfc_new_symbol (sym->name, NULL);
1317
  new_sym->ts = sym->ts;
1318
  new_sym->attr.referenced = 1;
1319
  new_sym->attr.dimension = sym->attr.dimension;
1320
  new_sym->attr.pointer = sym->attr.pointer;
1321
  new_sym->attr.flavor = sym->attr.flavor;
1322
 
1323
  /* Create a fake symtree for it.  */
1324
  root = NULL;
1325
  new_symtree = gfc_new_symtree (&root, sym->name);
1326
  new_symtree->n.sym = new_sym;
1327
  gcc_assert (new_symtree == root);
1328
 
1329
  /* Create a dummy->actual mapping.  */
1330
  sm = gfc_getmem (sizeof (*sm));
1331
  sm->next = mapping->syms;
1332
  sm->old = sym;
1333
  sm->new = new_symtree;
1334
  mapping->syms = sm;
1335
 
1336
  /* Stabilize the argument's value.  */
1337
  se->expr = gfc_evaluate_now (se->expr, &se->pre);
1338
 
1339
  if (sym->ts.type == BT_CHARACTER)
1340
    {
1341
      /* Create a copy of the dummy argument's length.  */
1342
      new_sym->ts.cl = gfc_get_interface_mapping_charlen (mapping, sym->ts.cl);
1343
 
1344
      /* If the length is specified as "*", record the length that
1345
         the caller is passing.  We should use the callee's length
1346
         in all other cases.  */
1347
      if (!new_sym->ts.cl->length)
1348
        {
1349
          se->string_length = gfc_evaluate_now (se->string_length, &se->pre);
1350
          new_sym->ts.cl->backend_decl = se->string_length;
1351
        }
1352
    }
1353
 
1354
  /* Use the passed value as-is if the argument is a function.  */
1355
  if (sym->attr.flavor == FL_PROCEDURE)
1356
    value = se->expr;
1357
 
1358
  /* If the argument is either a string or a pointer to a string,
1359
     convert it to a boundless character type.  */
1360
  else if (!sym->attr.dimension && sym->ts.type == BT_CHARACTER)
1361
    {
1362
      tmp = gfc_get_character_type_len (sym->ts.kind, NULL);
1363
      tmp = build_pointer_type (tmp);
1364
      if (sym->attr.pointer)
1365
        tmp = build_pointer_type (tmp);
1366
 
1367
      value = fold_convert (tmp, se->expr);
1368
      if (sym->attr.pointer)
1369
        value = gfc_build_indirect_ref (value);
1370
    }
1371
 
1372
  /* If the argument is a scalar or a pointer to an array, dereference it.  */
1373
  else if (!sym->attr.dimension || sym->attr.pointer)
1374
    value = gfc_build_indirect_ref (se->expr);
1375
 
1376
  /* For character(*), use the actual argument's descriptor.  */
1377
  else if (sym->ts.type == BT_CHARACTER && !new_sym->ts.cl->length)
1378
    value = build_fold_indirect_ref (se->expr);
1379
 
1380
  /* If the argument is an array descriptor, use it to determine
1381
     information about the actual argument's shape.  */
1382
  else if (POINTER_TYPE_P (TREE_TYPE (se->expr))
1383
           && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se->expr))))
1384
    {
1385
      /* Get the actual argument's descriptor.  */
1386
      desc = gfc_build_indirect_ref (se->expr);
1387
 
1388
      /* Create the replacement variable.  */
1389
      tmp = gfc_conv_descriptor_data_get (desc);
1390
      value = gfc_get_interface_mapping_array (&se->pre, sym, 0, tmp);
1391
 
1392
      /* Use DESC to work out the upper bounds, strides and offset.  */
1393
      gfc_set_interface_mapping_bounds (&se->pre, TREE_TYPE (value), desc);
1394
    }
1395
  else
1396
    /* Otherwise we have a packed array.  */
1397
    value = gfc_get_interface_mapping_array (&se->pre, sym, 2, se->expr);
1398
 
1399
  new_sym->backend_decl = value;
1400
}
1401
 
1402
 
1403
/* Called once all dummy argument mappings have been added to MAPPING,
1404
   but before the mapping is used to evaluate expressions.  Pre-evaluate
1405
   the length of each argument, adding any initialization code to PRE and
1406
   any finalization code to POST.  */
1407
 
1408
void
1409
gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
1410
                              stmtblock_t * pre, stmtblock_t * post)
1411
{
1412
  gfc_interface_sym_mapping *sym;
1413
  gfc_expr *expr;
1414
  gfc_se se;
1415
 
1416
  for (sym = mapping->syms; sym; sym = sym->next)
1417
    if (sym->new->n.sym->ts.type == BT_CHARACTER
1418
        && !sym->new->n.sym->ts.cl->backend_decl)
1419
      {
1420
        expr = sym->new->n.sym->ts.cl->length;
1421
        gfc_apply_interface_mapping_to_expr (mapping, expr);
1422
        gfc_init_se (&se, NULL);
1423
        gfc_conv_expr (&se, expr);
1424
 
1425
        se.expr = gfc_evaluate_now (se.expr, &se.pre);
1426
        gfc_add_block_to_block (pre, &se.pre);
1427
        gfc_add_block_to_block (post, &se.post);
1428
 
1429
        sym->new->n.sym->ts.cl->backend_decl = se.expr;
1430
      }
1431
}
1432
 
1433
 
1434
/* Like gfc_apply_interface_mapping_to_expr, but applied to
1435
   constructor C.  */
1436
 
1437
static void
1438
gfc_apply_interface_mapping_to_cons (gfc_interface_mapping * mapping,
1439
                                     gfc_constructor * c)
1440
{
1441
  for (; c; c = c->next)
1442
    {
1443
      gfc_apply_interface_mapping_to_expr (mapping, c->expr);
1444
      if (c->iterator)
1445
        {
1446
          gfc_apply_interface_mapping_to_expr (mapping, c->iterator->start);
1447
          gfc_apply_interface_mapping_to_expr (mapping, c->iterator->end);
1448
          gfc_apply_interface_mapping_to_expr (mapping, c->iterator->step);
1449
        }
1450
    }
1451
}
1452
 
1453
 
1454
/* Like gfc_apply_interface_mapping_to_expr, but applied to
1455
   reference REF.  */
1456
 
1457
static void
1458
gfc_apply_interface_mapping_to_ref (gfc_interface_mapping * mapping,
1459
                                    gfc_ref * ref)
1460
{
1461
  int n;
1462
 
1463
  for (; ref; ref = ref->next)
1464
    switch (ref->type)
1465
      {
1466
      case REF_ARRAY:
1467
        for (n = 0; n < ref->u.ar.dimen; n++)
1468
          {
1469
            gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.start[n]);
1470
            gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.end[n]);
1471
            gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.stride[n]);
1472
          }
1473
        gfc_apply_interface_mapping_to_expr (mapping, ref->u.ar.offset);
1474
        break;
1475
 
1476
      case REF_COMPONENT:
1477
        break;
1478
 
1479
      case REF_SUBSTRING:
1480
        gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.start);
1481
        gfc_apply_interface_mapping_to_expr (mapping, ref->u.ss.end);
1482
        break;
1483
      }
1484
}
1485
 
1486
 
1487
/* EXPR is a copy of an expression that appeared in the interface
1488
   associated with MAPPING.  Walk it recursively looking for references to
1489
   dummy arguments that MAPPING maps to actual arguments.  Replace each such
1490
   reference with a reference to the associated actual argument.  */
1491
 
1492
static void
1493
gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
1494
                                     gfc_expr * expr)
1495
{
1496
  gfc_interface_sym_mapping *sym;
1497
  gfc_actual_arglist *actual;
1498
 
1499
  if (!expr)
1500
    return;
1501
 
1502
  /* Copying an expression does not copy its length, so do that here.  */
1503
  if (expr->ts.type == BT_CHARACTER && expr->ts.cl)
1504
    {
1505
      expr->ts.cl = gfc_get_interface_mapping_charlen (mapping, expr->ts.cl);
1506
      gfc_apply_interface_mapping_to_expr (mapping, expr->ts.cl->length);
1507
    }
1508
 
1509
  /* Apply the mapping to any references.  */
1510
  gfc_apply_interface_mapping_to_ref (mapping, expr->ref);
1511
 
1512
  /* ...and to the expression's symbol, if it has one.  */
1513
  if (expr->symtree)
1514
    for (sym = mapping->syms; sym; sym = sym->next)
1515
      if (sym->old == expr->symtree->n.sym)
1516
        expr->symtree = sym->new;
1517
 
1518
  /* ...and to subexpressions in expr->value.  */
1519
  switch (expr->expr_type)
1520
    {
1521
    case EXPR_VARIABLE:
1522
    case EXPR_CONSTANT:
1523
    case EXPR_NULL:
1524
    case EXPR_SUBSTRING:
1525
      break;
1526
 
1527
    case EXPR_OP:
1528
      gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op1);
1529
      gfc_apply_interface_mapping_to_expr (mapping, expr->value.op.op2);
1530
      break;
1531
 
1532
    case EXPR_FUNCTION:
1533
      for (sym = mapping->syms; sym; sym = sym->next)
1534
        if (sym->old == expr->value.function.esym)
1535
          expr->value.function.esym = sym->new->n.sym;
1536
 
1537
      for (actual = expr->value.function.actual; actual; actual = actual->next)
1538
        gfc_apply_interface_mapping_to_expr (mapping, actual->expr);
1539
      break;
1540
 
1541
    case EXPR_ARRAY:
1542
    case EXPR_STRUCTURE:
1543
      gfc_apply_interface_mapping_to_cons (mapping, expr->value.constructor);
1544
      break;
1545
    }
1546
}
1547
 
1548
 
1549
/* Evaluate interface expression EXPR using MAPPING.  Store the result
1550
   in SE.  */
1551
 
1552
void
1553
gfc_apply_interface_mapping (gfc_interface_mapping * mapping,
1554
                             gfc_se * se, gfc_expr * expr)
1555
{
1556
  expr = gfc_copy_expr (expr);
1557
  gfc_apply_interface_mapping_to_expr (mapping, expr);
1558
  gfc_conv_expr (se, expr);
1559
  se->expr = gfc_evaluate_now (se->expr, &se->pre);
1560
  gfc_free_expr (expr);
1561
}
1562
 
1563
/* Returns a reference to a temporary array into which a component of
1564
   an actual argument derived type array is copied and then returned
1565
   after the function call.
1566
   TODO Get rid of this kludge, when array descriptors are capable of
1567
   handling aliased arrays.  */
1568
 
1569
static void
1570
gfc_conv_aliased_arg (gfc_se * parmse, gfc_expr * expr, int g77)
1571
{
1572
  gfc_se lse;
1573
  gfc_se rse;
1574
  gfc_ss *lss;
1575
  gfc_ss *rss;
1576
  gfc_loopinfo loop;
1577
  gfc_loopinfo loop2;
1578
  gfc_ss_info *info;
1579
  tree offset;
1580
  tree tmp_index;
1581
  tree tmp;
1582
  tree base_type;
1583
  stmtblock_t body;
1584
  int n;
1585
 
1586
  gcc_assert (expr->expr_type == EXPR_VARIABLE);
1587
 
1588
  gfc_init_se (&lse, NULL);
1589
  gfc_init_se (&rse, NULL);
1590
 
1591
  /* Walk the argument expression.  */
1592
  rss = gfc_walk_expr (expr);
1593
 
1594
  gcc_assert (rss != gfc_ss_terminator);
1595
 
1596
  /* Initialize the scalarizer.  */
1597
  gfc_init_loopinfo (&loop);
1598
  gfc_add_ss_to_loop (&loop, rss);
1599
 
1600
  /* Calculate the bounds of the scalarization.  */
1601
  gfc_conv_ss_startstride (&loop);
1602
 
1603
  /* Build an ss for the temporary.  */
1604
  base_type = gfc_typenode_for_spec (&expr->ts);
1605
  if (GFC_ARRAY_TYPE_P (base_type)
1606
                || GFC_DESCRIPTOR_TYPE_P (base_type))
1607
    base_type = gfc_get_element_type (base_type);
1608
 
1609
  loop.temp_ss = gfc_get_ss ();;
1610
  loop.temp_ss->type = GFC_SS_TEMP;
1611
  loop.temp_ss->data.temp.type = base_type;
1612
 
1613
  if (expr->ts.type == BT_CHARACTER)
1614
    loop.temp_ss->string_length = expr->ts.cl->backend_decl;
1615
 
1616
  loop.temp_ss->data.temp.dimen = loop.dimen;
1617
  loop.temp_ss->next = gfc_ss_terminator;
1618
 
1619
  /* Associate the SS with the loop.  */
1620
  gfc_add_ss_to_loop (&loop, loop.temp_ss);
1621
 
1622
  /* Setup the scalarizing loops.  */
1623
  gfc_conv_loop_setup (&loop);
1624
 
1625
  /* Pass the temporary descriptor back to the caller.  */
1626
  info = &loop.temp_ss->data.info;
1627
  parmse->expr = info->descriptor;
1628
 
1629
  /* Setup the gfc_se structures.  */
1630
  gfc_copy_loopinfo_to_se (&lse, &loop);
1631
  gfc_copy_loopinfo_to_se (&rse, &loop);
1632
 
1633
  rse.ss = rss;
1634
  lse.ss = loop.temp_ss;
1635
  gfc_mark_ss_chain_used (rss, 1);
1636
  gfc_mark_ss_chain_used (loop.temp_ss, 1);
1637
 
1638
  /* Start the scalarized loop body.  */
1639
  gfc_start_scalarized_body (&loop, &body);
1640
 
1641
  /* Translate the expression.  */
1642
  gfc_conv_expr (&rse, expr);
1643
 
1644
  gfc_conv_tmp_array_ref (&lse);
1645
  gfc_advance_se_ss_chain (&lse);
1646
 
1647
  tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
1648
  gfc_add_expr_to_block (&body, tmp);
1649
 
1650
  gcc_assert (rse.ss == gfc_ss_terminator);
1651
 
1652
  gfc_trans_scalarizing_loops (&loop, &body);
1653
 
1654
  /* Add the post block after the second loop, so that any
1655
     freeing of allocated memory is done at the right time.  */
1656
  gfc_add_block_to_block (&parmse->pre, &loop.pre);
1657
 
1658
  /**********Copy the temporary back again.*********/
1659
 
1660
  gfc_init_se (&lse, NULL);
1661
  gfc_init_se (&rse, NULL);
1662
 
1663
  /* Walk the argument expression.  */
1664
  lss = gfc_walk_expr (expr);
1665
  rse.ss = loop.temp_ss;
1666
  lse.ss = lss;
1667
 
1668
  /* Initialize the scalarizer.  */
1669
  gfc_init_loopinfo (&loop2);
1670
  gfc_add_ss_to_loop (&loop2, lss);
1671
 
1672
  /* Calculate the bounds of the scalarization.  */
1673
  gfc_conv_ss_startstride (&loop2);
1674
 
1675
  /* Setup the scalarizing loops.  */
1676
  gfc_conv_loop_setup (&loop2);
1677
 
1678
  gfc_copy_loopinfo_to_se (&lse, &loop2);
1679
  gfc_copy_loopinfo_to_se (&rse, &loop2);
1680
 
1681
  gfc_mark_ss_chain_used (lss, 1);
1682
  gfc_mark_ss_chain_used (loop.temp_ss, 1);
1683
 
1684
  /* Declare the variable to hold the temporary offset and start the
1685
     scalarized loop body.  */
1686
  offset = gfc_create_var (gfc_array_index_type, NULL);
1687
  gfc_start_scalarized_body (&loop2, &body);
1688
 
1689
  /* Build the offsets for the temporary from the loop variables.  The
1690
     temporary array has lbounds of zero and strides of one in all
1691
     dimensions, so this is very simple.  The offset is only computed
1692
     outside the innermost loop, so the overall transfer could be
1693
     optimised further.  */
1694
  info = &rse.ss->data.info;
1695
 
1696
  tmp_index = gfc_index_zero_node;
1697
  for (n = info->dimen - 1; n > 0; n--)
1698
    {
1699
      tree tmp_str;
1700
      tmp = rse.loop->loopvar[n];
1701
      tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1702
                         tmp, rse.loop->from[n]);
1703
      tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1704
                         tmp, tmp_index);
1705
 
1706
      tmp_str = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1707
                             rse.loop->to[n-1], rse.loop->from[n-1]);
1708
      tmp_str = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1709
                             tmp_str, gfc_index_one_node);
1710
 
1711
      tmp_index = fold_build2 (MULT_EXPR, gfc_array_index_type,
1712
                               tmp, tmp_str);
1713
    }
1714
 
1715
  tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1716
                           tmp_index, rse.loop->from[0]);
1717
  gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
1718
 
1719
  tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1720
                           rse.loop->loopvar[0], offset);
1721
 
1722
  /* Now use the offset for the reference.  */
1723
  tmp = build_fold_indirect_ref (info->data);
1724
  rse.expr = gfc_build_array_ref (tmp, tmp_index);
1725
 
1726
  if (expr->ts.type == BT_CHARACTER)
1727
    rse.string_length = expr->ts.cl->backend_decl;
1728
 
1729
  gfc_conv_expr (&lse, expr);
1730
 
1731
  gcc_assert (lse.ss == gfc_ss_terminator);
1732
 
1733
  tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
1734
  gfc_add_expr_to_block (&body, tmp);
1735
 
1736
  /* Generate the copying loops.  */
1737
  gfc_trans_scalarizing_loops (&loop2, &body);
1738
 
1739
  /* Wrap the whole thing up by adding the second loop to the post-block
1740
     and following it by the post-block of the fist loop.  In this way,
1741
     if the temporary needs freeing, it is done after use!  */
1742
  gfc_add_block_to_block (&parmse->post, &loop2.pre);
1743
  gfc_add_block_to_block (&parmse->post, &loop2.post);
1744
 
1745
  gfc_add_block_to_block (&parmse->post, &loop.post);
1746
 
1747
  gfc_cleanup_loop (&loop);
1748
  gfc_cleanup_loop (&loop2);
1749
 
1750
  /* Pass the string length to the argument expression.  */
1751
  if (expr->ts.type == BT_CHARACTER)
1752
    parmse->string_length = expr->ts.cl->backend_decl;
1753
 
1754
  /* We want either the address for the data or the address of the descriptor,
1755
     depending on the mode of passing array arguments.  */
1756
  if (g77)
1757
    parmse->expr = gfc_conv_descriptor_data_get (parmse->expr);
1758
  else
1759
    parmse->expr = build_fold_addr_expr (parmse->expr);
1760
 
1761
  return;
1762
}
1763
 
1764
/* Is true if the last array reference is followed by a component reference.  */
1765
 
1766
static bool
1767
is_aliased_array (gfc_expr * e)
1768
{
1769
  gfc_ref * ref;
1770
  bool seen_array;
1771
 
1772
  seen_array = false;
1773
  for (ref = e->ref; ref; ref = ref->next)
1774
    {
1775
      if (ref->type == REF_ARRAY)
1776
        seen_array = true;
1777
 
1778
      if (ref->next == NULL && ref->type == REF_COMPONENT)
1779
        return seen_array;
1780
    }
1781
  return false;
1782
}
1783
 
1784
/* Generate code for a procedure call.  Note can return se->post != NULL.
1785
   If se->direct_byref is set then se->expr contains the return parameter.
1786
   Return nonzero, if the call has alternate specifiers.  */
1787
 
1788
int
1789
gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
1790
                        gfc_actual_arglist * arg)
1791
{
1792
  gfc_interface_mapping mapping;
1793
  tree arglist;
1794
  tree retargs;
1795
  tree tmp;
1796
  tree fntype;
1797
  gfc_se parmse;
1798
  gfc_ss *argss;
1799
  gfc_ss_info *info;
1800
  int byref;
1801
  tree type;
1802
  tree var;
1803
  tree len;
1804
  tree stringargs;
1805
  gfc_formal_arglist *formal;
1806
  int has_alternate_specifier = 0;
1807
  bool need_interface_mapping;
1808
  gfc_typespec ts;
1809
  gfc_charlen cl;
1810
  gfc_expr *e;
1811
  gfc_symbol *fsym;
1812
  stmtblock_t post;
1813
 
1814
  arglist = NULL_TREE;
1815
  retargs = NULL_TREE;
1816
  stringargs = NULL_TREE;
1817
  var = NULL_TREE;
1818
  len = NULL_TREE;
1819
 
1820
  if (se->ss != NULL)
1821
    {
1822
      if (!sym->attr.elemental)
1823
        {
1824
          gcc_assert (se->ss->type == GFC_SS_FUNCTION);
1825
          if (se->ss->useflags)
1826
            {
1827
              gcc_assert (gfc_return_by_reference (sym)
1828
                      && sym->result->attr.dimension);
1829
              gcc_assert (se->loop != NULL);
1830
 
1831
              /* Access the previously obtained result.  */
1832
              gfc_conv_tmp_array_ref (se);
1833
              gfc_advance_se_ss_chain (se);
1834
              return 0;
1835
            }
1836
        }
1837
      info = &se->ss->data.info;
1838
    }
1839
  else
1840
    info = NULL;
1841
 
1842
  gfc_init_block (&post);
1843
  gfc_init_interface_mapping (&mapping);
1844
  need_interface_mapping = ((sym->ts.type == BT_CHARACTER
1845
                                  && sym->ts.cl->length
1846
                                  && sym->ts.cl->length->expr_type
1847
                                                != EXPR_CONSTANT)
1848
                              || sym->attr.dimension);
1849
  formal = sym->formal;
1850
  /* Evaluate the arguments.  */
1851
  for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
1852
    {
1853
      e = arg->expr;
1854
      fsym = formal ? formal->sym : NULL;
1855
      if (e == NULL)
1856
        {
1857
 
1858
          if (se->ignore_optional)
1859
            {
1860
              /* Some intrinsics have already been resolved to the correct
1861
                 parameters.  */
1862
              continue;
1863
            }
1864
          else if (arg->label)
1865
            {
1866
              has_alternate_specifier = 1;
1867
              continue;
1868
            }
1869
          else
1870
            {
1871
              /* Pass a NULL pointer for an absent arg.  */
1872
              gfc_init_se (&parmse, NULL);
1873
              parmse.expr = null_pointer_node;
1874
              if (arg->missing_arg_type == BT_CHARACTER)
1875
                parmse.string_length = convert (gfc_charlen_type_node,
1876
                                                integer_zero_node);
1877
            }
1878
        }
1879
      else if (se->ss && se->ss->useflags)
1880
        {
1881
          /* An elemental function inside a scalarized loop.  */
1882
          gfc_init_se (&parmse, se);
1883
          gfc_conv_expr_reference (&parmse, e);
1884
        }
1885
      else
1886
        {
1887
          /* A scalar or transformational function.  */
1888
          gfc_init_se (&parmse, NULL);
1889
          argss = gfc_walk_expr (e);
1890
 
1891
          if (argss == gfc_ss_terminator)
1892
            {
1893
              gfc_conv_expr_reference (&parmse, e);
1894
              if (fsym && fsym->attr.pointer
1895
                  && e->expr_type != EXPR_NULL)
1896
                {
1897
                  /* Scalar pointer dummy args require an extra level of
1898
                  indirection. The null pointer already contains
1899
                  this level of indirection.  */
1900
                  parmse.expr = gfc_build_addr_expr (NULL, parmse.expr);
1901
                }
1902
            }
1903
          else
1904
            {
1905
              /* If the procedure requires an explicit interface, the
1906
                 actual argument is passed according to the
1907
                 corresponding formal argument.  If the corresponding
1908
                 formal argument is a POINTER or assumed shape, we do
1909
                 not use g77's calling convention, and pass the
1910
                 address of the array descriptor instead. Otherwise we
1911
                 use g77's calling convention.  */
1912
              int f;
1913
              f = (fsym != NULL)
1914
                  && !fsym->attr.pointer
1915
                  && fsym->as->type != AS_ASSUMED_SHAPE;
1916
              f = f || !sym->attr.always_explicit;
1917
              if (e->expr_type == EXPR_VARIABLE
1918
                    && is_aliased_array (e))
1919
                /* The actual argument is a component reference to an
1920
                   array of derived types.  In this case, the argument
1921
                   is converted to a temporary, which is passed and then
1922
                   written back after the procedure call.  */
1923
                gfc_conv_aliased_arg (&parmse, e, f);
1924
              else
1925
                gfc_conv_array_parameter (&parmse, e, argss, f);
1926
            }
1927
        }
1928
 
1929
      /* If an optional argument is itself an optional dummy argument,
1930
         check its presence and substitute a null if absent.  */
1931
      if (e && e->expr_type == EXPR_VARIABLE
1932
            && e->symtree->n.sym->attr.optional
1933
            && fsym && fsym->attr.optional)
1934
        gfc_conv_missing_dummy (&parmse, e, fsym->ts);
1935
 
1936
      if (fsym && need_interface_mapping)
1937
        gfc_add_interface_mapping (&mapping, fsym, &parmse);
1938
 
1939
      gfc_add_block_to_block (&se->pre, &parmse.pre);
1940
      gfc_add_block_to_block (&post, &parmse.post);
1941
 
1942
      /* Character strings are passed as two parameters, a length and a
1943
         pointer.  */
1944
      if (parmse.string_length != NULL_TREE)
1945
        stringargs = gfc_chainon_list (stringargs, parmse.string_length);
1946
 
1947
      arglist = gfc_chainon_list (arglist, parmse.expr);
1948
    }
1949
  gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
1950
 
1951
  ts = sym->ts;
1952
  if (ts.type == BT_CHARACTER)
1953
    {
1954
      if (sym->ts.cl->length == NULL)
1955
        {
1956
          /* Assumed character length results are not allowed by 5.1.1.5 of the
1957
             standard and are trapped in resolve.c; except in the case of SPREAD
1958
             (and other intrinsics?).  In this case, we take the character length
1959
             of the first argument for the result.  */
1960
          cl.backend_decl = TREE_VALUE (stringargs);
1961
        }
1962
      else
1963
        {
1964
          /* Calculate the length of the returned string.  */
1965
          gfc_init_se (&parmse, NULL);
1966
          if (need_interface_mapping)
1967
            gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
1968
          else
1969
            gfc_conv_expr (&parmse, sym->ts.cl->length);
1970
          gfc_add_block_to_block (&se->pre, &parmse.pre);
1971
          gfc_add_block_to_block (&se->post, &parmse.post);
1972
          cl.backend_decl = fold_convert (gfc_charlen_type_node, parmse.expr);
1973
        }
1974
 
1975
      /* Set up a charlen structure for it.  */
1976
      cl.next = NULL;
1977
      cl.length = NULL;
1978
      ts.cl = &cl;
1979
 
1980
      len = cl.backend_decl;
1981
    }
1982
 
1983
  byref = gfc_return_by_reference (sym);
1984
  if (byref)
1985
    {
1986
      if (se->direct_byref)
1987
        retargs = gfc_chainon_list (retargs, se->expr);
1988
      else if (sym->result->attr.dimension)
1989
        {
1990
          gcc_assert (se->loop && info);
1991
 
1992
          /* Set the type of the array.  */
1993
          tmp = gfc_typenode_for_spec (&ts);
1994
          info->dimen = se->loop->dimen;
1995
 
1996
          /* Evaluate the bounds of the result, if known.  */
1997
          gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
1998
 
1999
          /* Allocate a temporary to store the result.  In case the function
2000
             returns a pointer, the temporary will be a shallow copy and
2001
             mustn't be deallocated.  */
2002
          gfc_trans_allocate_temp_array (&se->pre, &se->post, se->loop, info,
2003
                                         tmp, false, !sym->attr.pointer);
2004
 
2005
          /* Zero the first stride to indicate a temporary.  */
2006
          tmp = gfc_conv_descriptor_stride (info->descriptor, gfc_rank_cst[0]);
2007
          gfc_add_modify_expr (&se->pre, tmp,
2008
                               convert (TREE_TYPE (tmp), integer_zero_node));
2009
 
2010
          /* Pass the temporary as the first argument.  */
2011
          tmp = info->descriptor;
2012
          tmp = gfc_build_addr_expr (NULL, tmp);
2013
          retargs = gfc_chainon_list (retargs, tmp);
2014
        }
2015
      else if (ts.type == BT_CHARACTER)
2016
        {
2017
          /* Pass the string length.  */
2018
          type = gfc_get_character_type (ts.kind, ts.cl);
2019
          type = build_pointer_type (type);
2020
 
2021
          /* Return an address to a char[0:len-1]* temporary for
2022
             character pointers.  */
2023
          if (sym->attr.pointer || sym->attr.allocatable)
2024
            {
2025
              /* Build char[0:len-1] * pstr.  */
2026
              tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2027
                                 build_int_cst (gfc_charlen_type_node, 1));
2028
              tmp = build_range_type (gfc_array_index_type,
2029
                                      gfc_index_zero_node, tmp);
2030
              tmp = build_array_type (gfc_character1_type_node, tmp);
2031
              var = gfc_create_var (build_pointer_type (tmp), "pstr");
2032
 
2033
              /* Provide an address expression for the function arguments.  */
2034
              var = gfc_build_addr_expr (NULL, var);
2035
            }
2036
          else
2037
            var = gfc_conv_string_tmp (se, type, len);
2038
 
2039
          retargs = gfc_chainon_list (retargs, var);
2040
        }
2041
      else
2042
        {
2043
          gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2044
 
2045
          type = gfc_get_complex_type (ts.kind);
2046
          var = gfc_build_addr_expr (NULL, gfc_create_var (type, "cmplx"));
2047
          retargs = gfc_chainon_list (retargs, var);
2048
        }
2049
 
2050
      /* Add the string length to the argument list.  */
2051
      if (ts.type == BT_CHARACTER)
2052
        retargs = gfc_chainon_list (retargs, len);
2053
    }
2054
  gfc_free_interface_mapping (&mapping);
2055
 
2056
  /* Add the return arguments.  */
2057
  arglist = chainon (retargs, arglist);
2058
 
2059
  /* Add the hidden string length parameters to the arguments.  */
2060
  arglist = chainon (arglist, stringargs);
2061
 
2062
  /* Generate the actual call.  */
2063
  gfc_conv_function_val (se, sym);
2064
  /* If there are alternate return labels, function type should be
2065
     integer.  Can't modify the type in place though, since it can be shared
2066
     with other functions.  */
2067
  if (has_alternate_specifier
2068
      && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2069
    {
2070
      gcc_assert (! sym->attr.dummy);
2071
      TREE_TYPE (sym->backend_decl)
2072
        = build_function_type (integer_type_node,
2073
                               TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
2074
      se->expr = gfc_build_addr_expr (NULL, sym->backend_decl);
2075
    }
2076
 
2077
  fntype = TREE_TYPE (TREE_TYPE (se->expr));
2078
  se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
2079
                     arglist, NULL_TREE);
2080
 
2081
  /* If we have a pointer function, but we don't want a pointer, e.g.
2082
     something like
2083
        x = f()
2084
     where f is pointer valued, we have to dereference the result.  */
2085
  if (!se->want_pointer && !byref && sym->attr.pointer)
2086
    se->expr = gfc_build_indirect_ref (se->expr);
2087
 
2088
  /* f2c calling conventions require a scalar default real function to
2089
     return a double precision result.  Convert this back to default
2090
     real.  We only care about the cases that can happen in Fortran 77.
2091
  */
2092
  if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2093
      && sym->ts.kind == gfc_default_real_kind
2094
      && !sym->attr.always_explicit)
2095
    se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2096
 
2097
  /* A pure function may still have side-effects - it may modify its
2098
     parameters.  */
2099
  TREE_SIDE_EFFECTS (se->expr) = 1;
2100
#if 0
2101
  if (!sym->attr.pure)
2102
    TREE_SIDE_EFFECTS (se->expr) = 1;
2103
#endif
2104
 
2105
  if (byref)
2106
    {
2107
      /* Add the function call to the pre chain.  There is no expression.  */
2108
      gfc_add_expr_to_block (&se->pre, se->expr);
2109
      se->expr = NULL_TREE;
2110
 
2111
      if (!se->direct_byref)
2112
        {
2113
          if (sym->attr.dimension)
2114
            {
2115
              if (flag_bounds_check)
2116
                {
2117
                  /* Check the data pointer hasn't been modified.  This would
2118
                     happen in a function returning a pointer.  */
2119
                  tmp = gfc_conv_descriptor_data_get (info->descriptor);
2120
                  tmp = build2 (NE_EXPR, boolean_type_node, tmp, info->data);
2121
                  gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
2122
                }
2123
              se->expr = info->descriptor;
2124
              /* Bundle in the string length.  */
2125
              se->string_length = len;
2126
            }
2127
          else if (sym->ts.type == BT_CHARACTER)
2128
            {
2129
              /* Dereference for character pointer results.  */
2130
              if (sym->attr.pointer || sym->attr.allocatable)
2131
                se->expr = gfc_build_indirect_ref (var);
2132
              else
2133
                se->expr = var;
2134
 
2135
              se->string_length = len;
2136
            }
2137
          else
2138
            {
2139
              gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
2140
              se->expr = gfc_build_indirect_ref (var);
2141
            }
2142
        }
2143
    }
2144
 
2145
  /* Follow the function call with the argument post block.  */
2146
  if (byref)
2147
    gfc_add_block_to_block (&se->pre, &post);
2148
  else
2149
    gfc_add_block_to_block (&se->post, &post);
2150
 
2151
  return has_alternate_specifier;
2152
}
2153
 
2154
 
2155
/* Generate code to copy a string.  */
2156
 
2157
static void
2158
gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
2159
                       tree slen, tree src)
2160
{
2161
  tree tmp;
2162
  tree dsc;
2163
  tree ssc;
2164
 
2165
  /* Deal with single character specially.  */
2166
  dsc = gfc_to_single_character (dlen, dest);
2167
  ssc = gfc_to_single_character (slen, src);
2168
  if (dsc != NULL_TREE && ssc != NULL_TREE)
2169
    {
2170
      gfc_add_modify_expr (block, dsc, ssc);
2171
      return;
2172
    }
2173
 
2174
  tmp = NULL_TREE;
2175
  tmp = gfc_chainon_list (tmp, dlen);
2176
  tmp = gfc_chainon_list (tmp, dest);
2177
  tmp = gfc_chainon_list (tmp, slen);
2178
  tmp = gfc_chainon_list (tmp, src);
2179
  tmp = gfc_build_function_call (gfor_fndecl_copy_string, tmp);
2180
  gfc_add_expr_to_block (block, tmp);
2181
}
2182
 
2183
 
2184
/* Translate a statement function.
2185
   The value of a statement function reference is obtained by evaluating the
2186
   expression using the values of the actual arguments for the values of the
2187
   corresponding dummy arguments.  */
2188
 
2189
static void
2190
gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2191
{
2192
  gfc_symbol *sym;
2193
  gfc_symbol *fsym;
2194
  gfc_formal_arglist *fargs;
2195
  gfc_actual_arglist *args;
2196
  gfc_se lse;
2197
  gfc_se rse;
2198
  gfc_saved_var *saved_vars;
2199
  tree *temp_vars;
2200
  tree type;
2201
  tree tmp;
2202
  int n;
2203
 
2204
  sym = expr->symtree->n.sym;
2205
  args = expr->value.function.actual;
2206
  gfc_init_se (&lse, NULL);
2207
  gfc_init_se (&rse, NULL);
2208
 
2209
  n = 0;
2210
  for (fargs = sym->formal; fargs; fargs = fargs->next)
2211
    n++;
2212
  saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2213
  temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2214
 
2215
  for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2216
    {
2217
      /* Each dummy shall be specified, explicitly or implicitly, to be
2218
         scalar.  */
2219
      gcc_assert (fargs->sym->attr.dimension == 0);
2220
      fsym = fargs->sym;
2221
 
2222
      /* Create a temporary to hold the value.  */
2223
      type = gfc_typenode_for_spec (&fsym->ts);
2224
      temp_vars[n] = gfc_create_var (type, fsym->name);
2225
 
2226
      if (fsym->ts.type == BT_CHARACTER)
2227
        {
2228
          /* Copy string arguments.  */
2229
          tree arglen;
2230
 
2231
          gcc_assert (fsym->ts.cl && fsym->ts.cl->length
2232
                  && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2233
 
2234
          arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2235
          tmp = gfc_build_addr_expr (build_pointer_type (type),
2236
                                     temp_vars[n]);
2237
 
2238
          gfc_conv_expr (&rse, args->expr);
2239
          gfc_conv_string_parameter (&rse);
2240
          gfc_add_block_to_block (&se->pre, &lse.pre);
2241
          gfc_add_block_to_block (&se->pre, &rse.pre);
2242
 
2243
          gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2244
                                 rse.expr);
2245
          gfc_add_block_to_block (&se->pre, &lse.post);
2246
          gfc_add_block_to_block (&se->pre, &rse.post);
2247
        }
2248
      else
2249
        {
2250
          /* For everything else, just evaluate the expression.  */
2251
          gfc_conv_expr (&lse, args->expr);
2252
 
2253
          gfc_add_block_to_block (&se->pre, &lse.pre);
2254
          gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
2255
          gfc_add_block_to_block (&se->pre, &lse.post);
2256
        }
2257
 
2258
      args = args->next;
2259
    }
2260
 
2261
  /* Use the temporary variables in place of the real ones.  */
2262
  for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2263
    gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2264
 
2265
  gfc_conv_expr (se, sym->value);
2266
 
2267
  if (sym->ts.type == BT_CHARACTER)
2268
    {
2269
      gfc_conv_const_charlen (sym->ts.cl);
2270
 
2271
      /* Force the expression to the correct length.  */
2272
      if (!INTEGER_CST_P (se->string_length)
2273
          || tree_int_cst_lt (se->string_length,
2274
                              sym->ts.cl->backend_decl))
2275
        {
2276
          type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2277
          tmp = gfc_create_var (type, sym->name);
2278
          tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2279
          gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2280
                                 se->string_length, se->expr);
2281
          se->expr = tmp;
2282
        }
2283
      se->string_length = sym->ts.cl->backend_decl;
2284
    }
2285
 
2286
  /* Restore the original variables.  */
2287
  for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2288
    gfc_restore_sym (fargs->sym, &saved_vars[n]);
2289
  gfc_free (saved_vars);
2290
}
2291
 
2292
 
2293
/* Translate a function expression.  */
2294
 
2295
static void
2296
gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2297
{
2298
  gfc_symbol *sym;
2299
 
2300
  if (expr->value.function.isym)
2301
    {
2302
      gfc_conv_intrinsic_function (se, expr);
2303
      return;
2304
    }
2305
 
2306
  /* We distinguish statement functions from general functions to improve
2307
     runtime performance.  */
2308
  if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2309
    {
2310
      gfc_conv_statement_function (se, expr);
2311
      return;
2312
    }
2313
 
2314
  /* expr.value.function.esym is the resolved (specific) function symbol for
2315
     most functions.  However this isn't set for dummy procedures.  */
2316
  sym = expr->value.function.esym;
2317
  if (!sym)
2318
    sym = expr->symtree->n.sym;
2319
  gfc_conv_function_call (se, sym, expr->value.function.actual);
2320
}
2321
 
2322
 
2323
static void
2324
gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2325
{
2326
  gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2327
  gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
2328
 
2329
  gfc_conv_tmp_array_ref (se);
2330
  gfc_advance_se_ss_chain (se);
2331
}
2332
 
2333
 
2334
/* Build a static initializer.  EXPR is the expression for the initial value.
2335
   The other parameters describe the variable of the component being
2336
   initialized. EXPR may be null.  */
2337
 
2338
tree
2339
gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2340
                      bool array, bool pointer)
2341
{
2342
  gfc_se se;
2343
 
2344
  if (!(expr || pointer))
2345
    return NULL_TREE;
2346
 
2347
  if (array)
2348
    {
2349
      /* Arrays need special handling.  */
2350
      if (pointer)
2351
        return gfc_build_null_descriptor (type);
2352
      else
2353
        return gfc_conv_array_initializer (type, expr);
2354
    }
2355
  else if (pointer)
2356
    return fold_convert (type, null_pointer_node);
2357
  else
2358
    {
2359
      switch (ts->type)
2360
        {
2361
        case BT_DERIVED:
2362
          gfc_init_se (&se, NULL);
2363
          gfc_conv_structure (&se, expr, 1);
2364
          return se.expr;
2365
 
2366
        case BT_CHARACTER:
2367
          return gfc_conv_string_init (ts->cl->backend_decl,expr);
2368
 
2369
        default:
2370
          gfc_init_se (&se, NULL);
2371
          gfc_conv_constant (&se, expr);
2372
          return se.expr;
2373
        }
2374
    }
2375
}
2376
 
2377
static tree
2378
gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2379
{
2380
  gfc_se rse;
2381
  gfc_se lse;
2382
  gfc_ss *rss;
2383
  gfc_ss *lss;
2384
  stmtblock_t body;
2385
  stmtblock_t block;
2386
  gfc_loopinfo loop;
2387
  int n;
2388
  tree tmp;
2389
 
2390
  gfc_start_block (&block);
2391
 
2392
  /* Initialize the scalarizer.  */
2393
  gfc_init_loopinfo (&loop);
2394
 
2395
  gfc_init_se (&lse, NULL);
2396
  gfc_init_se (&rse, NULL);
2397
 
2398
  /* Walk the rhs.  */
2399
  rss = gfc_walk_expr (expr);
2400
  if (rss == gfc_ss_terminator)
2401
    {
2402
      /* The rhs is scalar.  Add a ss for the expression.  */
2403
      rss = gfc_get_ss ();
2404
      rss->next = gfc_ss_terminator;
2405
      rss->type = GFC_SS_SCALAR;
2406
      rss->expr = expr;
2407
    }
2408
 
2409
  /* Create a SS for the destination.  */
2410
  lss = gfc_get_ss ();
2411
  lss->type = GFC_SS_COMPONENT;
2412
  lss->expr = NULL;
2413
  lss->shape = gfc_get_shape (cm->as->rank);
2414
  lss->next = gfc_ss_terminator;
2415
  lss->data.info.dimen = cm->as->rank;
2416
  lss->data.info.descriptor = dest;
2417
  lss->data.info.data = gfc_conv_array_data (dest);
2418
  lss->data.info.offset = gfc_conv_array_offset (dest);
2419
  for (n = 0; n < cm->as->rank; n++)
2420
    {
2421
      lss->data.info.dim[n] = n;
2422
      lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2423
      lss->data.info.stride[n] = gfc_index_one_node;
2424
 
2425
      mpz_init (lss->shape[n]);
2426
      mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2427
               cm->as->lower[n]->value.integer);
2428
      mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2429
    }
2430
 
2431
  /* Associate the SS with the loop.  */
2432
  gfc_add_ss_to_loop (&loop, lss);
2433
  gfc_add_ss_to_loop (&loop, rss);
2434
 
2435
  /* Calculate the bounds of the scalarization.  */
2436
  gfc_conv_ss_startstride (&loop);
2437
 
2438
  /* Setup the scalarizing loops.  */
2439
  gfc_conv_loop_setup (&loop);
2440
 
2441
  /* Setup the gfc_se structures.  */
2442
  gfc_copy_loopinfo_to_se (&lse, &loop);
2443
  gfc_copy_loopinfo_to_se (&rse, &loop);
2444
 
2445
  rse.ss = rss;
2446
  gfc_mark_ss_chain_used (rss, 1);
2447
  lse.ss = lss;
2448
  gfc_mark_ss_chain_used (lss, 1);
2449
 
2450
  /* Start the scalarized loop body.  */
2451
  gfc_start_scalarized_body (&loop, &body);
2452
 
2453
  gfc_conv_tmp_array_ref (&lse);
2454
  if (cm->ts.type == BT_CHARACTER)
2455
    lse.string_length = cm->ts.cl->backend_decl;
2456
 
2457
  gfc_conv_expr (&rse, expr);
2458
 
2459
  tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts.type);
2460
  gfc_add_expr_to_block (&body, tmp);
2461
 
2462
  gcc_assert (rse.ss == gfc_ss_terminator);
2463
 
2464
  /* Generate the copying loops.  */
2465
  gfc_trans_scalarizing_loops (&loop, &body);
2466
 
2467
  /* Wrap the whole thing up.  */
2468
  gfc_add_block_to_block (&block, &loop.pre);
2469
  gfc_add_block_to_block (&block, &loop.post);
2470
 
2471
  for (n = 0; n < cm->as->rank; n++)
2472
    mpz_clear (lss->shape[n]);
2473
  gfc_free (lss->shape);
2474
 
2475
  gfc_cleanup_loop (&loop);
2476
 
2477
  return gfc_finish_block (&block);
2478
}
2479
 
2480
/* Assign a single component of a derived type constructor.  */
2481
 
2482
static tree
2483
gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2484
{
2485
  gfc_se se;
2486
  gfc_ss *rss;
2487
  stmtblock_t block;
2488
  tree tmp;
2489
 
2490
  gfc_start_block (&block);
2491
  if (cm->pointer)
2492
    {
2493
      gfc_init_se (&se, NULL);
2494
      /* Pointer component.  */
2495
      if (cm->dimension)
2496
        {
2497
          /* Array pointer.  */
2498
          if (expr->expr_type == EXPR_NULL)
2499
            gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
2500
          else
2501
            {
2502
              rss = gfc_walk_expr (expr);
2503
              se.direct_byref = 1;
2504
              se.expr = dest;
2505
              gfc_conv_expr_descriptor (&se, expr, rss);
2506
              gfc_add_block_to_block (&block, &se.pre);
2507
              gfc_add_block_to_block (&block, &se.post);
2508
            }
2509
        }
2510
      else
2511
        {
2512
          /* Scalar pointers.  */
2513
          se.want_pointer = 1;
2514
          gfc_conv_expr (&se, expr);
2515
          gfc_add_block_to_block (&block, &se.pre);
2516
          gfc_add_modify_expr (&block, dest,
2517
                               fold_convert (TREE_TYPE (dest), se.expr));
2518
          gfc_add_block_to_block (&block, &se.post);
2519
        }
2520
    }
2521
  else if (cm->dimension)
2522
    {
2523
      tmp = gfc_trans_subarray_assign (dest, cm, expr);
2524
      gfc_add_expr_to_block (&block, tmp);
2525
    }
2526
  else if (expr->ts.type == BT_DERIVED)
2527
    {
2528
      /* Nested derived type.  */
2529
      tmp = gfc_trans_structure_assign (dest, expr);
2530
      gfc_add_expr_to_block (&block, tmp);
2531
    }
2532
  else
2533
    {
2534
      /* Scalar component.  */
2535
      gfc_se lse;
2536
 
2537
      gfc_init_se (&se, NULL);
2538
      gfc_init_se (&lse, NULL);
2539
 
2540
      gfc_conv_expr (&se, expr);
2541
      if (cm->ts.type == BT_CHARACTER)
2542
        lse.string_length = cm->ts.cl->backend_decl;
2543
      lse.expr = dest;
2544
      tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts.type);
2545
      gfc_add_expr_to_block (&block, tmp);
2546
    }
2547
  return gfc_finish_block (&block);
2548
}
2549
 
2550
/* Assign a derived type constructor to a variable.  */
2551
 
2552
static tree
2553
gfc_trans_structure_assign (tree dest, gfc_expr * expr)
2554
{
2555
  gfc_constructor *c;
2556
  gfc_component *cm;
2557
  stmtblock_t block;
2558
  tree field;
2559
  tree tmp;
2560
 
2561
  gfc_start_block (&block);
2562
  cm = expr->ts.derived->components;
2563
  for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
2564
    {
2565
      /* Skip absent members in default initializers.  */
2566
      if (!c->expr)
2567
        continue;
2568
 
2569
      field = cm->backend_decl;
2570
      tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
2571
      tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
2572
      gfc_add_expr_to_block (&block, tmp);
2573
    }
2574
  return gfc_finish_block (&block);
2575
}
2576
 
2577
/* Build an expression for a constructor. If init is nonzero then
2578
   this is part of a static variable initializer.  */
2579
 
2580
void
2581
gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
2582
{
2583
  gfc_constructor *c;
2584
  gfc_component *cm;
2585
  tree val;
2586
  tree type;
2587
  tree tmp;
2588
  VEC(constructor_elt,gc) *v = NULL;
2589
 
2590
  gcc_assert (se->ss == NULL);
2591
  gcc_assert (expr->expr_type == EXPR_STRUCTURE);
2592
  type = gfc_typenode_for_spec (&expr->ts);
2593
 
2594
  if (!init)
2595
    {
2596
      /* Create a temporary variable and fill it in.  */
2597
      se->expr = gfc_create_var (type, expr->ts.derived->name);
2598
      tmp = gfc_trans_structure_assign (se->expr, expr);
2599
      gfc_add_expr_to_block (&se->pre, tmp);
2600
      return;
2601
    }
2602
 
2603
  cm = expr->ts.derived->components;
2604
  for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
2605
    {
2606
      /* Skip absent members in default initializers.  */
2607
      if (!c->expr)
2608
        continue;
2609
 
2610
      val = gfc_conv_initializer (c->expr, &cm->ts,
2611
          TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
2612
 
2613
      /* Append it to the constructor list.  */
2614
      CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
2615
    }
2616
  se->expr = build_constructor (type, v);
2617
}
2618
 
2619
 
2620
/* Translate a substring expression.  */
2621
 
2622
static void
2623
gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
2624
{
2625
  gfc_ref *ref;
2626
 
2627
  ref = expr->ref;
2628
 
2629
  gcc_assert (ref->type == REF_SUBSTRING);
2630
 
2631
  se->expr = gfc_build_string_const(expr->value.character.length,
2632
                                    expr->value.character.string);
2633
  se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
2634
  TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
2635
 
2636
  gfc_conv_substring(se,ref,expr->ts.kind);
2637
}
2638
 
2639
 
2640
/* Entry point for expression translation.  Evaluates a scalar quantity.
2641
   EXPR is the expression to be translated, and SE is the state structure if
2642
   called from within the scalarized.  */
2643
 
2644
void
2645
gfc_conv_expr (gfc_se * se, gfc_expr * expr)
2646
{
2647
  if (se->ss && se->ss->expr == expr
2648
      && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
2649
    {
2650
      /* Substitute a scalar expression evaluated outside the scalarization
2651
         loop.  */
2652
      se->expr = se->ss->data.scalar.expr;
2653
      se->string_length = se->ss->string_length;
2654
      gfc_advance_se_ss_chain (se);
2655
      return;
2656
    }
2657
 
2658
  switch (expr->expr_type)
2659
    {
2660
    case EXPR_OP:
2661
      gfc_conv_expr_op (se, expr);
2662
      break;
2663
 
2664
    case EXPR_FUNCTION:
2665
      gfc_conv_function_expr (se, expr);
2666
      break;
2667
 
2668
    case EXPR_CONSTANT:
2669
      gfc_conv_constant (se, expr);
2670
      break;
2671
 
2672
    case EXPR_VARIABLE:
2673
      gfc_conv_variable (se, expr);
2674
      break;
2675
 
2676
    case EXPR_NULL:
2677
      se->expr = null_pointer_node;
2678
      break;
2679
 
2680
    case EXPR_SUBSTRING:
2681
      gfc_conv_substring_expr (se, expr);
2682
      break;
2683
 
2684
    case EXPR_STRUCTURE:
2685
      gfc_conv_structure (se, expr, 0);
2686
      break;
2687
 
2688
    case EXPR_ARRAY:
2689
      gfc_conv_array_constructor_expr (se, expr);
2690
      break;
2691
 
2692
    default:
2693
      gcc_unreachable ();
2694
      break;
2695
    }
2696
}
2697
 
2698
/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
2699
   of an assignment.  */
2700
void
2701
gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
2702
{
2703
  gfc_conv_expr (se, expr);
2704
  /* All numeric lvalues should have empty post chains.  If not we need to
2705
     figure out a way of rewriting an lvalue so that it has no post chain.  */
2706
  gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
2707
}
2708
 
2709
/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
2710
   numeric expressions.  Used for scalar values whee inserting cleanup code
2711
   is inconvenient.  */
2712
void
2713
gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
2714
{
2715
  tree val;
2716
 
2717
  gcc_assert (expr->ts.type != BT_CHARACTER);
2718
  gfc_conv_expr (se, expr);
2719
  if (se->post.head)
2720
    {
2721
      val = gfc_create_var (TREE_TYPE (se->expr), NULL);
2722
      gfc_add_modify_expr (&se->pre, val, se->expr);
2723
      se->expr = val;
2724
      gfc_add_block_to_block (&se->pre, &se->post);
2725
    }
2726
}
2727
 
2728
/* Helper to translate and expression and convert it to a particular type.  */
2729
void
2730
gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
2731
{
2732
  gfc_conv_expr_val (se, expr);
2733
  se->expr = convert (type, se->expr);
2734
}
2735
 
2736
 
2737
/* Converts an expression so that it can be passed by reference.  Scalar
2738
   values only.  */
2739
 
2740
void
2741
gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
2742
{
2743
  tree var;
2744
 
2745
  if (se->ss && se->ss->expr == expr
2746
      && se->ss->type == GFC_SS_REFERENCE)
2747
    {
2748
      se->expr = se->ss->data.scalar.expr;
2749
      se->string_length = se->ss->string_length;
2750
      gfc_advance_se_ss_chain (se);
2751
      return;
2752
    }
2753
 
2754
  if (expr->ts.type == BT_CHARACTER)
2755
    {
2756
      gfc_conv_expr (se, expr);
2757
      gfc_conv_string_parameter (se);
2758
      return;
2759
    }
2760
 
2761
  if (expr->expr_type == EXPR_VARIABLE)
2762
    {
2763
      se->want_pointer = 1;
2764
      gfc_conv_expr (se, expr);
2765
      if (se->post.head)
2766
        {
2767
          var = gfc_create_var (TREE_TYPE (se->expr), NULL);
2768
          gfc_add_modify_expr (&se->pre, var, se->expr);
2769
          gfc_add_block_to_block (&se->pre, &se->post);
2770
          se->expr = var;
2771
        }
2772
      return;
2773
    }
2774
 
2775
  gfc_conv_expr (se, expr);
2776
 
2777
  /* Create a temporary var to hold the value.  */
2778
  if (TREE_CONSTANT (se->expr))
2779
    {
2780
      var = build_decl (CONST_DECL, NULL, TREE_TYPE (se->expr));
2781
      DECL_INITIAL (var) = se->expr;
2782
      pushdecl (var);
2783
    }
2784
  else
2785
    {
2786
      var = gfc_create_var (TREE_TYPE (se->expr), NULL);
2787
      gfc_add_modify_expr (&se->pre, var, se->expr);
2788
    }
2789
  gfc_add_block_to_block (&se->pre, &se->post);
2790
 
2791
  /* Take the address of that value.  */
2792
  se->expr = gfc_build_addr_expr (NULL, var);
2793
}
2794
 
2795
 
2796
tree
2797
gfc_trans_pointer_assign (gfc_code * code)
2798
{
2799
  return gfc_trans_pointer_assignment (code->expr, code->expr2);
2800
}
2801
 
2802
 
2803
/* Generate code for a pointer assignment.  */
2804
 
2805
tree
2806
gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
2807
{
2808
  gfc_se lse;
2809
  gfc_se rse;
2810
  gfc_ss *lss;
2811
  gfc_ss *rss;
2812
  stmtblock_t block;
2813
  tree desc;
2814
  tree tmp;
2815
 
2816
  gfc_start_block (&block);
2817
 
2818
  gfc_init_se (&lse, NULL);
2819
 
2820
  lss = gfc_walk_expr (expr1);
2821
  rss = gfc_walk_expr (expr2);
2822
  if (lss == gfc_ss_terminator)
2823
    {
2824
      /* Scalar pointers.  */
2825
      lse.want_pointer = 1;
2826
      gfc_conv_expr (&lse, expr1);
2827
      gcc_assert (rss == gfc_ss_terminator);
2828
      gfc_init_se (&rse, NULL);
2829
      rse.want_pointer = 1;
2830
      gfc_conv_expr (&rse, expr2);
2831
      gfc_add_block_to_block (&block, &lse.pre);
2832
      gfc_add_block_to_block (&block, &rse.pre);
2833
      gfc_add_modify_expr (&block, lse.expr,
2834
                           fold_convert (TREE_TYPE (lse.expr), rse.expr));
2835
      gfc_add_block_to_block (&block, &rse.post);
2836
      gfc_add_block_to_block (&block, &lse.post);
2837
    }
2838
  else
2839
    {
2840
      /* Array pointer.  */
2841
      gfc_conv_expr_descriptor (&lse, expr1, lss);
2842
      switch (expr2->expr_type)
2843
        {
2844
        case EXPR_NULL:
2845
          /* Just set the data pointer to null.  */
2846
          gfc_conv_descriptor_data_set (&block, lse.expr, null_pointer_node);
2847
          break;
2848
 
2849
        case EXPR_VARIABLE:
2850
          /* Assign directly to the pointer's descriptor.  */
2851
          lse.direct_byref = 1;
2852
          gfc_conv_expr_descriptor (&lse, expr2, rss);
2853
          break;
2854
 
2855
        default:
2856
          /* Assign to a temporary descriptor and then copy that
2857
             temporary to the pointer.  */
2858
          desc = lse.expr;
2859
          tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
2860
 
2861
          lse.expr = tmp;
2862
          lse.direct_byref = 1;
2863
          gfc_conv_expr_descriptor (&lse, expr2, rss);
2864
          gfc_add_modify_expr (&lse.pre, desc, tmp);
2865
          break;
2866
        }
2867
      gfc_add_block_to_block (&block, &lse.pre);
2868
      gfc_add_block_to_block (&block, &lse.post);
2869
    }
2870
  return gfc_finish_block (&block);
2871
}
2872
 
2873
 
2874
/* Makes sure se is suitable for passing as a function string parameter.  */
2875
/* TODO: Need to check all callers fo this function.  It may be abused.  */
2876
 
2877
void
2878
gfc_conv_string_parameter (gfc_se * se)
2879
{
2880
  tree type;
2881
 
2882
  if (TREE_CODE (se->expr) == STRING_CST)
2883
    {
2884
      se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
2885
      return;
2886
    }
2887
 
2888
  type = TREE_TYPE (se->expr);
2889
  if (TYPE_STRING_FLAG (type))
2890
    {
2891
      gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
2892
      se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
2893
    }
2894
 
2895
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
2896
  gcc_assert (se->string_length
2897
          && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
2898
}
2899
 
2900
 
2901
/* Generate code for assignment of scalar variables.  Includes character
2902
   strings.  */
2903
 
2904
tree
2905
gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, bt type)
2906
{
2907
  stmtblock_t block;
2908
 
2909
  gfc_init_block (&block);
2910
 
2911
  if (type == BT_CHARACTER)
2912
    {
2913
      gcc_assert (lse->string_length != NULL_TREE
2914
              && rse->string_length != NULL_TREE);
2915
 
2916
      gfc_conv_string_parameter (lse);
2917
      gfc_conv_string_parameter (rse);
2918
 
2919
      gfc_add_block_to_block (&block, &lse->pre);
2920
      gfc_add_block_to_block (&block, &rse->pre);
2921
 
2922
      gfc_trans_string_copy (&block, lse->string_length, lse->expr,
2923
                             rse->string_length, rse->expr);
2924
    }
2925
  else
2926
    {
2927
      gfc_add_block_to_block (&block, &lse->pre);
2928
      gfc_add_block_to_block (&block, &rse->pre);
2929
 
2930
      gfc_add_modify_expr (&block, lse->expr,
2931
                           fold_convert (TREE_TYPE (lse->expr), rse->expr));
2932
    }
2933
 
2934
  gfc_add_block_to_block (&block, &lse->post);
2935
  gfc_add_block_to_block (&block, &rse->post);
2936
 
2937
  return gfc_finish_block (&block);
2938
}
2939
 
2940
 
2941
/* Try to translate array(:) = func (...), where func is a transformational
2942
   array function, without using a temporary.  Returns NULL is this isn't the
2943
   case.  */
2944
 
2945
static tree
2946
gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
2947
{
2948
  gfc_se se;
2949
  gfc_ss *ss;
2950
  gfc_ref * ref;
2951
  bool seen_array_ref;
2952
 
2953
  /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION.  */
2954
  if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
2955
    return NULL;
2956
 
2957
  /* Elemental functions don't need a temporary anyway.  */
2958
  if (expr2->value.function.esym != NULL
2959
      && expr2->value.function.esym->attr.elemental)
2960
    return NULL;
2961
 
2962
  /* Fail if EXPR1 can't be expressed as a descriptor.  */
2963
  if (gfc_ref_needs_temporary_p (expr1->ref))
2964
    return NULL;
2965
 
2966
  /* Functions returning pointers need temporaries.  */
2967
  if (expr2->symtree->n.sym->attr.pointer)
2968
    return NULL;
2969
 
2970
  /* Check that no LHS component references appear during an array
2971
     reference. This is needed because we do not have the means to
2972
     span any arbitrary stride with an array descriptor. This check
2973
     is not needed for the rhs because the function result has to be
2974
     a complete type.  */
2975
  seen_array_ref = false;
2976
  for (ref = expr1->ref; ref; ref = ref->next)
2977
    {
2978
      if (ref->type == REF_ARRAY)
2979
        seen_array_ref= true;
2980
      else if (ref->type == REF_COMPONENT && seen_array_ref)
2981
        return NULL;
2982
    }
2983
 
2984
  /* Check for a dependency.  */
2985
  if (gfc_check_fncall_dependency (expr1, expr2))
2986
    return NULL;
2987
 
2988
  /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
2989
     functions.  */
2990
  gcc_assert (expr2->value.function.isym
2991
              || (gfc_return_by_reference (expr2->value.function.esym)
2992
              && expr2->value.function.esym->result->attr.dimension));
2993
 
2994
  ss = gfc_walk_expr (expr1);
2995
  gcc_assert (ss != gfc_ss_terminator);
2996
  gfc_init_se (&se, NULL);
2997
  gfc_start_block (&se.pre);
2998
  se.want_pointer = 1;
2999
 
3000
  gfc_conv_array_parameter (&se, expr1, ss, 0);
3001
 
3002
  se.direct_byref = 1;
3003
  se.ss = gfc_walk_expr (expr2);
3004
  gcc_assert (se.ss != gfc_ss_terminator);
3005
  gfc_conv_function_expr (&se, expr2);
3006
  gfc_add_block_to_block (&se.pre, &se.post);
3007
 
3008
  return gfc_finish_block (&se.pre);
3009
}
3010
 
3011
 
3012
/* Translate an assignment.  Most of the code is concerned with
3013
   setting up the scalarizer.  */
3014
 
3015
tree
3016
gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2)
3017
{
3018
  gfc_se lse;
3019
  gfc_se rse;
3020
  gfc_ss *lss;
3021
  gfc_ss *lss_section;
3022
  gfc_ss *rss;
3023
  gfc_loopinfo loop;
3024
  tree tmp;
3025
  stmtblock_t block;
3026
  stmtblock_t body;
3027
 
3028
  /* Special case a single function returning an array.  */
3029
  if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
3030
    {
3031
      tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
3032
      if (tmp)
3033
        return tmp;
3034
    }
3035
 
3036
  /* Assignment of the form lhs = rhs.  */
3037
  gfc_start_block (&block);
3038
 
3039
  gfc_init_se (&lse, NULL);
3040
  gfc_init_se (&rse, NULL);
3041
 
3042
  /* Walk the lhs.  */
3043
  lss = gfc_walk_expr (expr1);
3044
  rss = NULL;
3045
  if (lss != gfc_ss_terminator)
3046
    {
3047
      /* The assignment needs scalarization.  */
3048
      lss_section = lss;
3049
 
3050
      /* Find a non-scalar SS from the lhs.  */
3051
      while (lss_section != gfc_ss_terminator
3052
             && lss_section->type != GFC_SS_SECTION)
3053
        lss_section = lss_section->next;
3054
 
3055
      gcc_assert (lss_section != gfc_ss_terminator);
3056
 
3057
      /* Initialize the scalarizer.  */
3058
      gfc_init_loopinfo (&loop);
3059
 
3060
      /* Walk the rhs.  */
3061
      rss = gfc_walk_expr (expr2);
3062
      if (rss == gfc_ss_terminator)
3063
        {
3064
          /* The rhs is scalar.  Add a ss for the expression.  */
3065
          rss = gfc_get_ss ();
3066
          rss->next = gfc_ss_terminator;
3067
          rss->type = GFC_SS_SCALAR;
3068
          rss->expr = expr2;
3069
        }
3070
      /* Associate the SS with the loop.  */
3071
      gfc_add_ss_to_loop (&loop, lss);
3072
      gfc_add_ss_to_loop (&loop, rss);
3073
 
3074
      /* Calculate the bounds of the scalarization.  */
3075
      gfc_conv_ss_startstride (&loop);
3076
      /* Resolve any data dependencies in the statement.  */
3077
      gfc_conv_resolve_dependencies (&loop, lss, rss);
3078
      /* Setup the scalarizing loops.  */
3079
      gfc_conv_loop_setup (&loop);
3080
 
3081
      /* Setup the gfc_se structures.  */
3082
      gfc_copy_loopinfo_to_se (&lse, &loop);
3083
      gfc_copy_loopinfo_to_se (&rse, &loop);
3084
 
3085
      rse.ss = rss;
3086
      gfc_mark_ss_chain_used (rss, 1);
3087
      if (loop.temp_ss == NULL)
3088
        {
3089
          lse.ss = lss;
3090
          gfc_mark_ss_chain_used (lss, 1);
3091
        }
3092
      else
3093
        {
3094
          lse.ss = loop.temp_ss;
3095
          gfc_mark_ss_chain_used (lss, 3);
3096
          gfc_mark_ss_chain_used (loop.temp_ss, 3);
3097
        }
3098
 
3099
      /* Start the scalarized loop body.  */
3100
      gfc_start_scalarized_body (&loop, &body);
3101
    }
3102
  else
3103
    gfc_init_block (&body);
3104
 
3105
  /* Translate the expression.  */
3106
  gfc_conv_expr (&rse, expr2);
3107
 
3108
  if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
3109
    {
3110
      gfc_conv_tmp_array_ref (&lse);
3111
      gfc_advance_se_ss_chain (&lse);
3112
    }
3113
  else
3114
    gfc_conv_expr (&lse, expr1);
3115
 
3116
  tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
3117
  gfc_add_expr_to_block (&body, tmp);
3118
 
3119
  if (lss == gfc_ss_terminator)
3120
    {
3121
      /* Use the scalar assignment as is.  */
3122
      gfc_add_block_to_block (&block, &body);
3123
    }
3124
  else
3125
    {
3126
      gcc_assert (lse.ss == gfc_ss_terminator
3127
                  && rse.ss == gfc_ss_terminator);
3128
 
3129
      if (loop.temp_ss != NULL)
3130
        {
3131
          gfc_trans_scalarized_loop_boundary (&loop, &body);
3132
 
3133
          /* We need to copy the temporary to the actual lhs.  */
3134
          gfc_init_se (&lse, NULL);
3135
          gfc_init_se (&rse, NULL);
3136
          gfc_copy_loopinfo_to_se (&lse, &loop);
3137
          gfc_copy_loopinfo_to_se (&rse, &loop);
3138
 
3139
          rse.ss = loop.temp_ss;
3140
          lse.ss = lss;
3141
 
3142
          gfc_conv_tmp_array_ref (&rse);
3143
          gfc_advance_se_ss_chain (&rse);
3144
          gfc_conv_expr (&lse, expr1);
3145
 
3146
          gcc_assert (lse.ss == gfc_ss_terminator
3147
                      && rse.ss == gfc_ss_terminator);
3148
 
3149
          tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
3150
          gfc_add_expr_to_block (&body, tmp);
3151
        }
3152
      /* Generate the copying loops.  */
3153
      gfc_trans_scalarizing_loops (&loop, &body);
3154
 
3155
      /* Wrap the whole thing up.  */
3156
      gfc_add_block_to_block (&block, &loop.pre);
3157
      gfc_add_block_to_block (&block, &loop.post);
3158
 
3159
      gfc_cleanup_loop (&loop);
3160
    }
3161
 
3162
  return gfc_finish_block (&block);
3163
}
3164
 
3165
tree
3166
gfc_trans_assign (gfc_code * code)
3167
{
3168
  return gfc_trans_assignment (code->expr, code->expr2);
3169
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.