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