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