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