]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/trans-expr.c
t-slibgcc-darwin (SHLIB_LINK): Don't munge stmp-lipo.
[gcc.git] / gcc / fortran / trans-expr.c
CommitLineData
6de9cd9a 1/* Expression translation
0ad77f55 2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
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.
6de9cd9a 12
9fc4d79b
TS
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.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
9fc4d79b 19along with GCC; see the file COPYING. If not, write to the Free
ab57747b
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
6de9cd9a
DN
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"
6de9cd9a
DN
30#include "ggc.h"
31#include "toplev.h"
32#include "real.h"
eadf906f 33#include "tree-gimple.h"
b3eb1e0e 34#include "langhooks.h"
6de9cd9a 35#include "flags.h"
6de9cd9a
DN
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"
7a70c12d 43#include "dependency.h"
6de9cd9a 44
e9cfef64 45static tree gfc_trans_structure_assign (tree dest, gfc_expr * expr);
62ab4a54
RS
46static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping *,
47 gfc_expr *);
6de9cd9a
DN
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
f8d0aee5 59/* Initialize a simple expression holder.
6de9cd9a
DN
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
f8d0aee5 80 se->ss = se->ss->next because all the parents needs to be kept in sync.
6de9cd9a
DN
81 See gfc_init_se. */
82
83void
84gfc_advance_se_ss_chain (gfc_se * se)
85{
86 gfc_se *p;
87
6e45f57b 88 gcc_assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
6de9cd9a
DN
89
90 p = se;
91 /* Walk down the parent chain. */
92 while (p != NULL)
93 {
f8d0aee5 94 /* Simple consistency check. */
6e45f57b 95 gcc_assert (p->parent == NULL || p->parent->ss == p->ss);
6de9cd9a
DN
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
6615c446 112 if (CONSTANT_CLASS_P (se->expr))
6de9cd9a
DN
113 return;
114
f8d0aee5 115 /* We need a temporary for this result. */
6de9cd9a
DN
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
1a7bfcc3
PB
122/* Return an expression which determines if a dummy parameter is present.
123 Also used for arguments to procedures with multiple entry points. */
6de9cd9a
DN
124
125tree
126gfc_conv_expr_present (gfc_symbol * sym)
127{
128 tree decl;
129
1a7bfcc3 130 gcc_assert (sym->attr.dummy);
6de9cd9a
DN
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. */
6e45f57b 137 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
6de9cd9a
DN
138 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
139 decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
140 }
923ab88c
TS
141 return build2 (NE_EXPR, boolean_type_node, decl,
142 fold_convert (TREE_TYPE (decl), null_pointer_node));
6de9cd9a
DN
143}
144
145
e15e9be3
PT
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,
c3238e32 156 build_int_cst (TREE_TYPE (se->expr), 0));
e15e9be3
PT
157 tmp = gfc_evaluate_now (tmp, &se->pre);
158 se->expr = tmp;
159 if (ts.type == BT_CHARACTER)
160 {
c3238e32 161 tmp = build_int_cst (gfc_charlen_type_node, 0);
e15e9be3
PT
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
ca2940c3
TS
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
f7b529fa 187 variable. */
ca2940c3
TS
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
6de9cd9a
DN
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);
d7177ab2 228 gfc_conv_expr_type (&se, cl->length, gfc_charlen_type_node);
6de9cd9a
DN
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
f8d0aee5 235
6de9cd9a
DN
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);
d7177ab2 250 gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node);
6de9cd9a
DN
251 gfc_add_block_to_block (&se->pre, &start.pre);
252
253 if (integer_onep (start.expr))
7ab92584 254 gfc_conv_string_parameter (se);
6de9cd9a
DN
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
38611275 261 tmp = build_fold_indirect_ref (se->expr);
6de9cd9a
DN
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 {
d7177ab2 272 gfc_conv_expr_type (&end, ref->u.ss.end, gfc_charlen_type_node);
6de9cd9a
DN
273 gfc_add_block_to_block (&se->pre, &end.pre);
274 }
93fc8073
RG
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);
549033f3
FXC
279 tmp = fold_build2 (MAX_EXPR, gfc_charlen_type_node, tmp,
280 build_int_cst (gfc_charlen_type_node, 0));
93fc8073 281 se->string_length = tmp;
6de9cd9a
DN
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
6e45f57b 297 gcc_assert (c->backend_decl);
6de9cd9a
DN
298
299 field = c->backend_decl;
6e45f57b 300 gcc_assert (TREE_CODE (field) == FIELD_DECL);
6de9cd9a 301 decl = se->expr;
923ab88c 302 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
6de9cd9a
DN
303
304 se->expr = tmp;
305
306 if (c->ts.type == BT_CHARACTER)
307 {
308 tmp = c->ts.cl->backend_decl;
40f20186 309 /* Components must always be constant length. */
6e45f57b 310 gcc_assert (tmp && INTEGER_CST_P (tmp));
6de9cd9a
DN
311 se->string_length = tmp;
312 }
313
2b052ce2 314 if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
38611275 315 se->expr = build_fold_indirect_ref (se->expr);
6de9cd9a
DN
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;
5f20c93a
PT
327 tree parent_decl;
328 int parent_flag;
329 bool return_value;
330 bool alternate_entry;
331 bool entry_master;
6de9cd9a
DN
332
333 sym = expr->symtree->n.sym;
334 if (se->ss != NULL)
335 {
336 /* Check that something hasn't gone horribly wrong. */
6e45f57b
PB
337 gcc_assert (se->ss != gfc_ss_terminator);
338 gcc_assert (se->ss->expr == expr);
6de9cd9a
DN
339
340 /* A scalarized term. We already know the descriptor. */
341 se->expr = se->ss->data.info.descriptor;
40f20186 342 se->string_length = se->ss->string_length;
068e7338
RS
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;
6de9cd9a
DN
346 }
347 else
348 {
d198b59a
JJ
349 tree se_expr = NULL_TREE;
350
b122dc6a 351 se->expr = gfc_get_symbol_decl (sym);
6de9cd9a 352
5f20c93a
PT
353 /* Deal with references to a parent results or entries by storing
354 the current_function_decl and moving to the parent_decl. */
5f20c93a
PT
355 return_value = sym->attr.function && sym->result == sym;
356 alternate_entry = sym->attr.function && sym->attr.entry
11a5f608 357 && sym->result == sym;
5f20c93a 358 entry_master = sym->attr.result
11a5f608
JJ
359 && sym->ns->proc_name->attr.entry_master
360 && !gfc_return_by_reference (sym->ns->proc_name);
5f20c93a
PT
361 parent_decl = DECL_CONTEXT (current_function_decl);
362
363 if ((se->expr == parent_decl && return_value)
11a5f608 364 || (sym->ns && sym->ns->proc_name
1a492601 365 && parent_decl
11a5f608
JJ
366 && sym->ns->proc_name->backend_decl == parent_decl
367 && (alternate_entry || entry_master)))
5f20c93a
PT
368 parent_flag = 1;
369 else
370 parent_flag = 0;
371
d198b59a
JJ
372 /* Special case for assigning the return value of a function.
373 Self recursive functions must have an explicit return value. */
11a5f608 374 if (return_value && (se->expr == current_function_decl || parent_flag))
5f20c93a 375 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
376
377 /* Similarly for alternate entry points. */
5f20c93a 378 else if (alternate_entry
11a5f608
JJ
379 && (sym->ns->proc_name->backend_decl == current_function_decl
380 || parent_flag))
d198b59a
JJ
381 {
382 gfc_entry_list *el = NULL;
383
384 for (el = sym->ns->entries; el; el = el->next)
385 if (sym == el->sym)
386 {
5f20c93a 387 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
388 break;
389 }
390 }
391
5f20c93a 392 else if (entry_master
11a5f608
JJ
393 && (sym->ns->proc_name->backend_decl == current_function_decl
394 || parent_flag))
5f20c93a 395 se_expr = gfc_get_fake_result_decl (sym, parent_flag);
d198b59a
JJ
396
397 if (se_expr)
398 se->expr = se_expr;
399
6de9cd9a 400 /* Procedure actual arguments. */
d198b59a
JJ
401 else if (sym->attr.flavor == FL_PROCEDURE
402 && se->expr != current_function_decl)
6de9cd9a 403 {
6e45f57b 404 gcc_assert (se->want_pointer);
6de9cd9a
DN
405 if (!sym->attr.dummy)
406 {
6e45f57b 407 gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
488ce07b 408 se->expr = build_fold_addr_expr (se->expr);
6de9cd9a
DN
409 }
410 return;
ec09945c
KH
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
72caba17 420 or results. */
ec09945c 421 if ((sym->attr.pointer || sym->attr.allocatable)
13a9737c
PT
422 && (sym->attr.dummy
423 || sym->attr.function
424 || sym->attr.result))
38611275 425 se->expr = build_fold_indirect_ref (se->expr);
ec09945c
KH
426 }
427 else
428 {
897f1a8b 429 /* Dereference non-character scalar dummy arguments. */
13a9737c 430 if (sym->attr.dummy && !sym->attr.dimension)
38611275 431 se->expr = build_fold_indirect_ref (se->expr);
ec09945c 432
72caba17 433 /* Dereference scalar hidden result. */
13a9737c 434 if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
ec09945c 435 && (sym->attr.function || sym->attr.result)
b49a3de7 436 && !sym->attr.dimension && !sym->attr.pointer)
38611275 437 se->expr = build_fold_indirect_ref (se->expr);
ec09945c
KH
438
439 /* Dereference non-character pointer variables.
897f1a8b 440 These must be dummies, results, or scalars. */
ec09945c 441 if ((sym->attr.pointer || sym->attr.allocatable)
13a9737c
PT
442 && (sym->attr.dummy
443 || sym->attr.function
444 || sym->attr.result
445 || !sym->attr.dimension))
38611275 446 se->expr = build_fold_indirect_ref (se->expr);
ec09945c
KH
447 }
448
6de9cd9a
DN
449 ref = expr->ref;
450 }
451
452 /* For character variables, also get the length. */
453 if (sym->ts.type == BT_CHARACTER)
454 {
d48734ef
EE
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;
6e45f57b 461 gcc_assert (se->string_length);
6de9cd9a
DN
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
dd18a33b 479 gfc_conv_array_ref (se, &ref->u.ar, sym, &expr->where);
6de9cd9a
DN
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:
6e45f57b 492 gcc_unreachable ();
6de9cd9a
DN
493 break;
494 }
495 ref = ref->next;
496 }
497 /* Pointer assignment, allocation or pass by reference. Arrays are handled
f8d0aee5 498 separately. */
6de9cd9a
DN
499 if (se->want_pointer)
500 {
501 if (expr->ts.type == BT_CHARACTER)
502 gfc_conv_string_parameter (se);
503 else
488ce07b 504 se->expr = build_fold_addr_expr (se->expr);
6de9cd9a 505 }
6de9cd9a
DN
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
6e45f57b 517 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
518 /* Initialize the operand. */
519 gfc_init_se (&operand, se);
58b03ab2 520 gfc_conv_expr_val (&operand, expr->value.op.op1);
6de9cd9a
DN
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)).
f8d0aee5 527 All other unary operators have an equivalent GIMPLE unary operator. */
6de9cd9a 528 if (code == TRUTH_NOT_EXPR)
923ab88c 529 se->expr = build2 (EQ_EXPR, type, operand.expr,
c3238e32 530 build_int_cst (type, 0));
6de9cd9a
DN
531 else
532 se->expr = build1 (code, type, operand.expr);
533
534}
535
5b200ac2 536/* Expand power operator to optimal multiplications when a value is raised
f8d0aee5 537 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
5b200ac2
FW
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
f8d0aee5 548/* The table is from builtins.c. */
5b200ac2
FW
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
f8d0aee5
TS
585/* If n is larger than lookup table's max index, we use the "window
586 method". */
5b200ac2
FW
587#define POWI_WINDOW_SIZE 3
588
f8d0aee5
TS
589/* Recursive function to expand the power operator. The temporary
590 values are put in tmpvar. The function returns tmpvar[1] ** n. */
5b200ac2
FW
591static tree
592gfc_conv_powi (gfc_se * se, int n, tree * tmpvar)
6de9cd9a 593{
5b200ac2
FW
594 tree op0;
595 tree op1;
6de9cd9a 596 tree tmp;
5b200ac2 597 int digit;
6de9cd9a 598
5b200ac2 599 if (n < POWI_TABLE_SIZE)
6de9cd9a 600 {
5b200ac2
FW
601 if (tmpvar[n])
602 return tmpvar[n];
6de9cd9a 603
5b200ac2
FW
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);
6de9cd9a
DN
612 }
613 else
614 {
5b200ac2
FW
615 op0 = gfc_conv_powi (se, n >> 1, tmpvar);
616 op1 = op0;
6de9cd9a
DN
617 }
618
10c7a96f 619 tmp = fold_build2 (MULT_EXPR, TREE_TYPE (op0), op0, op1);
5b200ac2 620 tmp = gfc_evaluate_now (tmp, &se->pre);
6de9cd9a 621
5b200ac2
FW
622 if (n < POWI_TABLE_SIZE)
623 tmpvar[n] = tmp;
6de9cd9a 624
5b200ac2
FW
625 return tmp;
626}
6de9cd9a 627
f8d0aee5
TS
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. */
5b200ac2
FW
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;
6de9cd9a 641
5b200ac2
FW
642 type = TREE_TYPE (lhs);
643 n = abs (TREE_INT_CST_LOW (rhs));
644 sgn = tree_int_cst_sgn (rhs);
6de9cd9a 645
201a97b4
AP
646 if (((FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations) || optimize_size)
647 && (n > 2 || n < -1))
5b200ac2 648 return 0;
6de9cd9a 649
5b200ac2
FW
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 {
923ab88c 659 tmp = build2 (EQ_EXPR, boolean_type_node, lhs,
c3238e32 660 build_int_cst (TREE_TYPE (lhs), -1));
923ab88c 661 cond = build2 (EQ_EXPR, boolean_type_node, lhs,
c3238e32 662 build_int_cst (TREE_TYPE (lhs), 1));
5b200ac2 663
f8d0aee5 664 /* If rhs is even,
7ab92584 665 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
5b200ac2
FW
666 if ((n & 1) == 0)
667 {
923ab88c 668 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node, tmp, cond);
c3238e32
FXC
669 se->expr = build3 (COND_EXPR, type, tmp, build_int_cst (type, 1),
670 build_int_cst (type, 0));
5b200ac2
FW
671 return 1;
672 }
f8d0aee5 673 /* If rhs is odd,
5b200ac2 674 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
c3238e32
FXC
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);
5b200ac2
FW
678 return 1;
679 }
6de9cd9a 680
5b200ac2
FW
681 memset (vartmp, 0, sizeof (vartmp));
682 vartmp[1] = lhs;
5b200ac2
FW
683 if (sgn == -1)
684 {
685 tmp = gfc_build_const (type, integer_one_node);
923ab88c 686 vartmp[1] = build2 (RDIV_EXPR, type, tmp, vartmp[1]);
5b200ac2 687 }
293155b0
TM
688
689 se->expr = gfc_conv_powi (se, n, vartmp);
690
5b200ac2 691 return 1;
6de9cd9a
DN
692}
693
694
5b200ac2 695/* Power op (**). Constant integer exponent has special handling. */
6de9cd9a
DN
696
697static void
698gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
699{
e2cad04b 700 tree gfc_int4_type_node;
6de9cd9a 701 int kind;
5b200ac2 702 int ikind;
6de9cd9a
DN
703 gfc_se lse;
704 gfc_se rse;
705 tree fndecl;
706 tree tmp;
6de9cd9a
DN
707
708 gfc_init_se (&lse, se);
58b03ab2 709 gfc_conv_expr_val (&lse, expr->value.op.op1);
20fe2233 710 lse.expr = gfc_evaluate_now (lse.expr, &lse.pre);
6de9cd9a
DN
711 gfc_add_block_to_block (&se->pre, &lse.pre);
712
713 gfc_init_se (&rse, se);
58b03ab2 714 gfc_conv_expr_val (&rse, expr->value.op.op2);
6de9cd9a
DN
715 gfc_add_block_to_block (&se->pre, &rse.pre);
716
58b03ab2
TS
717 if (expr->value.op.op2->ts.type == BT_INTEGER
718 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
5b200ac2
FW
719 if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
720 return;
6de9cd9a 721
e2cad04b
RH
722 gfc_int4_type_node = gfc_get_int_type (4);
723
58b03ab2
TS
724 kind = expr->value.op.op1->ts.kind;
725 switch (expr->value.op.op2->ts.type)
6de9cd9a
DN
726 {
727 case BT_INTEGER:
58b03ab2 728 ikind = expr->value.op.op2->ts.kind;
5b200ac2
FW
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
644cb69f
FXC
744 case 16:
745 ikind = 2;
746 break;
747
5b200ac2 748 default:
6e45f57b 749 gcc_unreachable ();
5b200ac2
FW
750 }
751 switch (kind)
752 {
753 case 1:
754 case 2:
58b03ab2 755 if (expr->value.op.op1->ts.type == BT_INTEGER)
5b200ac2
FW
756 lse.expr = convert (gfc_int4_type_node, lse.expr);
757 else
6e45f57b 758 gcc_unreachable ();
5b200ac2
FW
759 /* Fall through. */
760
761 case 4:
762 kind = 0;
763 break;
764
765 case 8:
766 kind = 1;
767 break;
768
644cb69f
FXC
769 case 10:
770 kind = 2;
771 break;
772
773 case 16:
774 kind = 3;
775 break;
776
5b200ac2 777 default:
6e45f57b 778 gcc_unreachable ();
5b200ac2
FW
779 }
780
58b03ab2 781 switch (expr->value.op.op1->ts.type)
5b200ac2
FW
782 {
783 case BT_INTEGER:
644cb69f
FXC
784 if (kind == 3) /* Case 16 was not handled properly above. */
785 kind = 2;
5b200ac2
FW
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:
6e45f57b 798 gcc_unreachable ();
5b200ac2
FW
799 }
800 break;
6de9cd9a
DN
801
802 case BT_REAL:
803 switch (kind)
804 {
805 case 4:
5b200ac2 806 fndecl = built_in_decls[BUILT_IN_POWF];
6de9cd9a
DN
807 break;
808 case 8:
5b200ac2 809 fndecl = built_in_decls[BUILT_IN_POW];
6de9cd9a 810 break;
644cb69f
FXC
811 case 10:
812 case 16:
813 fndecl = built_in_decls[BUILT_IN_POWL];
814 break;
6de9cd9a 815 default:
6e45f57b 816 gcc_unreachable ();
6de9cd9a
DN
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;
644cb69f
FXC
829 case 10:
830 fndecl = gfor_fndecl_math_cpowl10;
831 break;
832 case 16:
833 fndecl = gfor_fndecl_math_cpowl16;
834 break;
6de9cd9a 835 default:
6e45f57b 836 gcc_unreachable ();
6de9cd9a
DN
837 }
838 break;
839
840 default:
6e45f57b 841 gcc_unreachable ();
6de9cd9a
DN
842 break;
843 }
844
845 tmp = gfc_chainon_list (NULL_TREE, lse.expr);
846 tmp = gfc_chainon_list (tmp, rse.expr);
3380b802 847 se->expr = build_function_call_expr (fndecl, tmp);
6de9cd9a
DN
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
6e45f57b 860 gcc_assert (TREE_TYPE (len) == gfc_charlen_type_node);
7ab92584 861
6de9cd9a
DN
862 if (gfc_can_put_var_on_stack (len))
863 {
864 /* Create a temporary variable to hold the result. */
10c7a96f 865 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
c3238e32 866 build_int_cst (gfc_charlen_type_node, 1));
7ab92584 867 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
6de9cd9a
DN
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);
3380b802 877 tmp = build_function_call_expr (gfor_fndecl_internal_malloc, args);
6de9cd9a
DN
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);
3380b802 884 tmp = build_function_call_expr (gfor_fndecl_internal_free, args);
6de9cd9a
DN
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
58b03ab2
TS
906 gcc_assert (expr->value.op.op1->ts.type == BT_CHARACTER
907 && expr->value.op.op2->ts.type == BT_CHARACTER);
6de9cd9a
DN
908
909 gfc_init_se (&lse, se);
58b03ab2 910 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
911 gfc_conv_string_parameter (&lse);
912 gfc_init_se (&rse, se);
58b03ab2 913 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
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 {
10c7a96f
SB
923 len = fold_build2 (PLUS_EXPR, TREE_TYPE (lse.string_length),
924 lse.string_length, rse.string_length);
6de9cd9a
DN
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);
3380b802 939 tmp = build_function_call_expr (gfor_fndecl_concat_string, args);
6de9cd9a
DN
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
6de9cd9a
DN
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
f8d0aee5 953 operator **).
6de9cd9a 954 Operators need no special handling for scalarized expressions as long as
f8d0aee5 955 they call gfc_conv_simple_val to get their operands.
6de9cd9a
DN
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;
58b03ab2 971 switch (expr->value.op.operator)
6de9cd9a
DN
972 {
973 case INTRINSIC_UPLUS:
2414e1d6 974 case INTRINSIC_PARENTHESES:
58b03ab2 975 gfc_conv_expr (se, expr->value.op.op1);
6de9cd9a
DN
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
eadf906f 1027 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
6de9cd9a
DN
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. */
6e45f57b 1069 gcc_unreachable ();
6de9cd9a
DN
1070
1071 default:
1072 fatal_error ("Unknown intrinsic op");
1073 return;
1074 }
1075
f8d0aee5 1076 /* The only exception to this is **, which is handled separately anyway. */
58b03ab2 1077 gcc_assert (expr->value.op.op1->ts.type == expr->value.op.op2->ts.type);
6de9cd9a 1078
58b03ab2 1079 if (checkstring && expr->value.op.op1->ts.type != BT_CHARACTER)
6de9cd9a
DN
1080 checkstring = 0;
1081
1082 /* lhs */
1083 gfc_init_se (&lse, se);
58b03ab2 1084 gfc_conv_expr (&lse, expr->value.op.op1);
6de9cd9a
DN
1085 gfc_add_block_to_block (&se->pre, &lse.pre);
1086
1087 /* rhs */
1088 gfc_init_se (&rse, se);
58b03ab2 1089 gfc_conv_expr (&rse, expr->value.op.op2);
6de9cd9a
DN
1090 gfc_add_block_to_block (&se->pre, &rse.pre);
1091
6de9cd9a
DN
1092 if (checkstring)
1093 {
1094 gfc_conv_string_parameter (&lse);
1095 gfc_conv_string_parameter (&rse);
6de9cd9a 1096
0a821a92
FW
1097 lse.expr = gfc_build_compare_string (lse.string_length, lse.expr,
1098 rse.string_length, rse.expr);
6de9cd9a 1099 rse.expr = integer_zero_node;
0a821a92 1100 gfc_add_block_to_block (&lse.post, &rse.post);
6de9cd9a
DN
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. */
10c7a96f 1108 tmp = fold_build2 (code, type, lse.expr, rse.expr);
6de9cd9a
DN
1109 se->expr = convert (type, tmp);
1110 }
1111 else
10c7a96f 1112 se->expr = fold_build2 (code, type, lse.expr, rse.expr);
6de9cd9a 1113
6de9cd9a
DN
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
0a821a92
FW
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}
f8d0aee5 1176
6de9cd9a
DN
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);
6e45f57b 1185 gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
6de9cd9a 1186 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
6de9cd9a
DN
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;
7074ea72
AL
1194 if (sym->attr.cray_pointee)
1195 tmp = convert (build_pointer_type (TREE_TYPE (tmp)),
1196 gfc_get_symbol_decl (sym->cp_pointer));
0348d6fd
RS
1197 if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
1198 {
1199 gcc_assert (TREE_CODE (tmp) == FUNCTION_DECL);
488ce07b 1200 tmp = build_fold_addr_expr (tmp);
0348d6fd
RS
1201 }
1202 }
1203 se->expr = tmp;
1204}
1205
1206
0348d6fd
RS
1207/* Initialize MAPPING. */
1208
62ab4a54 1209void
0348d6fd
RS
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
62ab4a54 1219void
0348d6fd
RS
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);
6de9cd9a
DN
1239 }
1240}
1241
1242
0348d6fd
RS
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
20236f90 1277 var = gfc_create_var (type, "ifm");
0348d6fd
RS
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
62ab4a54 1326void
0348d6fd
RS
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;
17029ac2 1344 new_sym->attr.allocatable = sym->attr.allocatable;
0348d6fd
RS
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)
38611275 1393 value = build_fold_indirect_ref (value);
0348d6fd
RS
1394 }
1395
17029ac2
EE
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)
38611275 1399 value = build_fold_indirect_ref (se->expr);
ed78a116
PT
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);
0348d6fd
RS
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. */
38611275 1411 desc = build_fold_indirect_ref (se->expr);
0348d6fd
RS
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
62ab4a54 1433void
0348d6fd
RS
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
62ab4a54 1577void
0348d6fd
RS
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
68ea355b
PT
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
1855915a
PT
1595gfc_conv_aliased_arg (gfc_se * parmse, gfc_expr * expr,
1596 int g77, sym_intent intent)
68ea355b
PT
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)
1855915a
PT
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 }
68ea355b
PT
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
1855915a
PT
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 }
68ea355b
PT
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
b82feea5 1750 optimized further. */
68ea355b
PT
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
1855915a 1797 and following it by the post-block of the first loop. In this way,
68ea355b 1798 if the temporary needs freeing, it is done after use! */
1855915a
PT
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 }
68ea355b
PT
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
1855915a
PT
1838 if (ref->next == NULL
1839 && ref->type != REF_ARRAY)
68ea355b
PT
1840 return seen_array;
1841 }
1842 return false;
1843}
0348d6fd 1844
6de9cd9a 1845/* Generate code for a procedure call. Note can return se->post != NULL.
dda895f9 1846 If se->direct_byref is set then se->expr contains the return parameter.
49de9e73 1847 Return nonzero, if the call has alternate specifiers. */
6de9cd9a 1848
dda895f9 1849int
6de9cd9a
DN
1850gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
1851 gfc_actual_arglist * arg)
1852{
0348d6fd 1853 gfc_interface_mapping mapping;
6de9cd9a 1854 tree arglist;
0348d6fd 1855 tree retargs;
6de9cd9a
DN
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;
dda895f9 1867 int has_alternate_specifier = 0;
0348d6fd 1868 bool need_interface_mapping;
8e119f1b 1869 bool callee_alloc;
0348d6fd
RS
1870 gfc_typespec ts;
1871 gfc_charlen cl;
e15e9be3
PT
1872 gfc_expr *e;
1873 gfc_symbol *fsym;
f5f701ad 1874 stmtblock_t post;
6de9cd9a
DN
1875
1876 arglist = NULL_TREE;
0348d6fd 1877 retargs = NULL_TREE;
6de9cd9a
DN
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 {
6e45f57b 1886 gcc_assert (se->ss->type == GFC_SS_FUNCTION);
6de9cd9a
DN
1887 if (se->ss->useflags)
1888 {
6e45f57b 1889 gcc_assert (gfc_return_by_reference (sym)
6de9cd9a 1890 && sym->result->attr.dimension);
6e45f57b 1891 gcc_assert (se->loop != NULL);
6de9cd9a
DN
1892
1893 /* Access the previously obtained result. */
1894 gfc_conv_tmp_array_ref (se);
1895 gfc_advance_se_ss_chain (se);
dda895f9 1896 return 0;
6de9cd9a
DN
1897 }
1898 }
1899 info = &se->ss->data.info;
1900 }
1901 else
1902 info = NULL;
1903
f5f701ad 1904 gfc_init_block (&post);
0348d6fd 1905 gfc_init_interface_mapping (&mapping);
62ab4a54 1906 need_interface_mapping = ((sym->ts.type == BT_CHARACTER
20236f90
PT
1907 && sym->ts.cl->length
1908 && sym->ts.cl->length->expr_type
1909 != EXPR_CONSTANT)
1910 || sym->attr.dimension);
6de9cd9a
DN
1911 formal = sym->formal;
1912 /* Evaluate the arguments. */
1913 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
1914 {
e15e9be3
PT
1915 e = arg->expr;
1916 fsym = formal ? formal->sym : NULL;
1917 if (e == NULL)
6de9cd9a
DN
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;
1600fe22 1936 if (arg->missing_arg_type == BT_CHARACTER)
c3238e32 1937 parmse.string_length = build_int_cst (gfc_charlen_type_node, 0);
6de9cd9a
DN
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);
e15e9be3 1944 gfc_conv_expr_reference (&parmse, e);
6de9cd9a
DN
1945 }
1946 else
1947 {
1948 /* A scalar or transformational function. */
1949 gfc_init_se (&parmse, NULL);
e15e9be3 1950 argss = gfc_walk_expr (e);
6de9cd9a
DN
1951
1952 if (argss == gfc_ss_terminator)
1953 {
e15e9be3
PT
1954 gfc_conv_expr_reference (&parmse, e);
1955 if (fsym && fsym->attr.pointer
1956 && e->expr_type != EXPR_NULL)
6de9cd9a
DN
1957 {
1958 /* Scalar pointer dummy args require an extra level of
72caba17
PT
1959 indirection. The null pointer already contains
1960 this level of indirection. */
488ce07b 1961 parmse.expr = build_fold_addr_expr (parmse.expr);
6de9cd9a
DN
1962 }
1963 }
1964 else
1965 {
aa08038d
EE
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. */
6de9cd9a 1972 int f;
e15e9be3
PT
1973 f = (fsym != NULL)
1974 && !(fsym->attr.pointer || fsym->attr.allocatable)
1975 && fsym->as->type != AS_ASSUMED_SHAPE;
6de9cd9a 1976 f = f || !sym->attr.always_explicit;
1855915a 1977
e15e9be3
PT
1978 if (e->expr_type == EXPR_VARIABLE
1979 && is_aliased_array (e))
68ea355b
PT
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. */
1855915a 1984 gfc_conv_aliased_arg (&parmse, e, f, fsym->attr.intent);
68ea355b 1985 else
e15e9be3 1986 gfc_conv_array_parameter (&parmse, e, argss, f);
42a0e16c
PT
1987
1988 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
1989 allocated on entry, it must be deallocated. */
e15e9be3
PT
1990 if (fsym && fsym->attr.allocatable
1991 && fsym->attr.intent == INTENT_OUT)
42a0e16c 1992 {
e15e9be3
PT
1993 tmp = e->symtree->n.sym->backend_decl;
1994 if (e->symtree->n.sym->attr.dummy)
763ccd45
EE
1995 tmp = build_fold_indirect_ref (tmp);
1996 tmp = gfc_trans_dealloc_allocated (tmp);
42a0e16c
PT
1997 gfc_add_expr_to_block (&se->pre, tmp);
1998 }
1999
6de9cd9a
DN
2000 }
2001 }
2002
e15e9be3
PT
2003 /* If an optional argument is itself an optional dummy argument,
2004 check its presence and substitute a null if absent. */
2005 if (e && e->expr_type == EXPR_VARIABLE
2006 && e->symtree->n.sym->attr.optional
2007 && fsym && fsym->attr.optional)
2008 gfc_conv_missing_dummy (&parmse, e, fsym->ts);
2009
2010 if (fsym && need_interface_mapping)
2011 gfc_add_interface_mapping (&mapping, fsym, &parmse);
0348d6fd 2012
6de9cd9a 2013 gfc_add_block_to_block (&se->pre, &parmse.pre);
f5f701ad 2014 gfc_add_block_to_block (&post, &parmse.post);
6de9cd9a 2015
e7dc5b4f 2016 /* Character strings are passed as two parameters, a length and a
6de9cd9a
DN
2017 pointer. */
2018 if (parmse.string_length != NULL_TREE)
2019 stringargs = gfc_chainon_list (stringargs, parmse.string_length);
2020
2021 arglist = gfc_chainon_list (arglist, parmse.expr);
2022 }
0348d6fd
RS
2023 gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
2024
2025 ts = sym->ts;
2026 if (ts.type == BT_CHARACTER)
2027 {
20236f90
PT
2028 if (sym->ts.cl->length == NULL)
2029 {
2030 /* Assumed character length results are not allowed by 5.1.1.5 of the
2031 standard and are trapped in resolve.c; except in the case of SPREAD
2032 (and other intrinsics?). In this case, we take the character length
2033 of the first argument for the result. */
2034 cl.backend_decl = TREE_VALUE (stringargs);
2035 }
0348d6fd 2036 else
20236f90
PT
2037 {
2038 /* Calculate the length of the returned string. */
2039 gfc_init_se (&parmse, NULL);
2040 if (need_interface_mapping)
2041 gfc_apply_interface_mapping (&mapping, &parmse, sym->ts.cl->length);
2042 else
2043 gfc_conv_expr (&parmse, sym->ts.cl->length);
2044 gfc_add_block_to_block (&se->pre, &parmse.pre);
2045 gfc_add_block_to_block (&se->post, &parmse.post);
2046 cl.backend_decl = fold_convert (gfc_charlen_type_node, parmse.expr);
2047 }
0348d6fd
RS
2048
2049 /* Set up a charlen structure for it. */
2050 cl.next = NULL;
2051 cl.length = NULL;
0348d6fd
RS
2052 ts.cl = &cl;
2053
2054 len = cl.backend_decl;
2055 }
0348d6fd
RS
2056
2057 byref = gfc_return_by_reference (sym);
2058 if (byref)
2059 {
2060 if (se->direct_byref)
2061 retargs = gfc_chainon_list (retargs, se->expr);
2062 else if (sym->result->attr.dimension)
2063 {
2064 gcc_assert (se->loop && info);
2065
2066 /* Set the type of the array. */
2067 tmp = gfc_typenode_for_spec (&ts);
2068 info->dimen = se->loop->dimen;
2069
62ab4a54
RS
2070 /* Evaluate the bounds of the result, if known. */
2071 gfc_set_loop_bounds_from_array_spec (&mapping, se, sym->result->as);
2072
8e119f1b
EE
2073 /* Create a temporary to store the result. In case the function
2074 returns a pointer, the temporary will be a shallow copy and
2075 mustn't be deallocated. */
2076 callee_alloc = sym->attr.allocatable || sym->attr.pointer;
2077 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
da4340a1
TK
2078 false, !sym->attr.pointer, callee_alloc,
2079 true);
0348d6fd 2080
0348d6fd
RS
2081 /* Pass the temporary as the first argument. */
2082 tmp = info->descriptor;
488ce07b 2083 tmp = build_fold_addr_expr (tmp);
0348d6fd
RS
2084 retargs = gfc_chainon_list (retargs, tmp);
2085 }
2086 else if (ts.type == BT_CHARACTER)
2087 {
2088 /* Pass the string length. */
2089 type = gfc_get_character_type (ts.kind, ts.cl);
2090 type = build_pointer_type (type);
2091
2092 /* Return an address to a char[0:len-1]* temporary for
2093 character pointers. */
2094 if (sym->attr.pointer || sym->attr.allocatable)
2095 {
2096 /* Build char[0:len-1] * pstr. */
2097 tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
2098 build_int_cst (gfc_charlen_type_node, 1));
2099 tmp = build_range_type (gfc_array_index_type,
2100 gfc_index_zero_node, tmp);
2101 tmp = build_array_type (gfc_character1_type_node, tmp);
2102 var = gfc_create_var (build_pointer_type (tmp), "pstr");
2103
2104 /* Provide an address expression for the function arguments. */
488ce07b 2105 var = build_fold_addr_expr (var);
0348d6fd
RS
2106 }
2107 else
2108 var = gfc_conv_string_tmp (se, type, len);
2109
2110 retargs = gfc_chainon_list (retargs, var);
2111 }
2112 else
2113 {
2114 gcc_assert (gfc_option.flag_f2c && ts.type == BT_COMPLEX);
2115
2116 type = gfc_get_complex_type (ts.kind);
488ce07b 2117 var = build_fold_addr_expr (gfc_create_var (type, "cmplx"));
0348d6fd
RS
2118 retargs = gfc_chainon_list (retargs, var);
2119 }
2120
2121 /* Add the string length to the argument list. */
2122 if (ts.type == BT_CHARACTER)
2123 retargs = gfc_chainon_list (retargs, len);
2124 }
62ab4a54 2125 gfc_free_interface_mapping (&mapping);
0348d6fd
RS
2126
2127 /* Add the return arguments. */
2128 arglist = chainon (retargs, arglist);
6de9cd9a
DN
2129
2130 /* Add the hidden string length parameters to the arguments. */
2131 arglist = chainon (arglist, stringargs);
2132
2133 /* Generate the actual call. */
2134 gfc_conv_function_val (se, sym);
2135 /* If there are alternate return labels, function type should be
dda895f9
JJ
2136 integer. Can't modify the type in place though, since it can be shared
2137 with other functions. */
2138 if (has_alternate_specifier
2139 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) != integer_type_node)
2140 {
2141 gcc_assert (! sym->attr.dummy);
2142 TREE_TYPE (sym->backend_decl)
2143 = build_function_type (integer_type_node,
2144 TYPE_ARG_TYPES (TREE_TYPE (sym->backend_decl)));
488ce07b 2145 se->expr = build_fold_addr_expr (sym->backend_decl);
dda895f9 2146 }
6de9cd9a
DN
2147
2148 fntype = TREE_TYPE (TREE_TYPE (se->expr));
923ab88c
TS
2149 se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
2150 arglist, NULL_TREE);
6de9cd9a 2151
6d1c50cc
TS
2152 /* If we have a pointer function, but we don't want a pointer, e.g.
2153 something like
2154 x = f()
2155 where f is pointer valued, we have to dereference the result. */
973ff4c0 2156 if (!se->want_pointer && !byref && sym->attr.pointer)
38611275 2157 se->expr = build_fold_indirect_ref (se->expr);
6d1c50cc 2158
973ff4c0
TS
2159 /* f2c calling conventions require a scalar default real function to
2160 return a double precision result. Convert this back to default
2161 real. We only care about the cases that can happen in Fortran 77.
2162 */
2163 if (gfc_option.flag_f2c && sym->ts.type == BT_REAL
2164 && sym->ts.kind == gfc_default_real_kind
2165 && !sym->attr.always_explicit)
2166 se->expr = fold_convert (gfc_get_real_type (sym->ts.kind), se->expr);
2167
f8d0aee5
TS
2168 /* A pure function may still have side-effects - it may modify its
2169 parameters. */
6de9cd9a
DN
2170 TREE_SIDE_EFFECTS (se->expr) = 1;
2171#if 0
2172 if (!sym->attr.pure)
2173 TREE_SIDE_EFFECTS (se->expr) = 1;
2174#endif
2175
fc90a8f2 2176 if (byref)
6de9cd9a 2177 {
fc90a8f2 2178 /* Add the function call to the pre chain. There is no expression. */
6de9cd9a 2179 gfc_add_expr_to_block (&se->pre, se->expr);
fc90a8f2 2180 se->expr = NULL_TREE;
6de9cd9a 2181
fc90a8f2 2182 if (!se->direct_byref)
6de9cd9a 2183 {
09e7f686 2184 if (sym->attr.dimension)
6de9cd9a 2185 {
fc90a8f2
PB
2186 if (flag_bounds_check)
2187 {
2188 /* Check the data pointer hasn't been modified. This would
2189 happen in a function returning a pointer. */
4c73896d 2190 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3f2ec06a
RG
2191 tmp = fold_build2 (NE_EXPR, boolean_type_node,
2192 tmp, info->data);
dd18a33b 2193 gfc_trans_runtime_check (tmp, gfc_msg_fault, &se->pre, NULL);
fc90a8f2
PB
2194 }
2195 se->expr = info->descriptor;
72caba17
PT
2196 /* Bundle in the string length. */
2197 se->string_length = len;
6de9cd9a 2198 }
fc90a8f2 2199 else if (sym->ts.type == BT_CHARACTER)
ec09945c 2200 {
72caba17
PT
2201 /* Dereference for character pointer results. */
2202 if (sym->attr.pointer || sym->attr.allocatable)
38611275 2203 se->expr = build_fold_indirect_ref (var);
ec09945c 2204 else
72caba17
PT
2205 se->expr = var;
2206
fc90a8f2
PB
2207 se->string_length = len;
2208 }
2209 else
973ff4c0
TS
2210 {
2211 gcc_assert (sym->ts.type == BT_COMPLEX && gfc_option.flag_f2c);
38611275 2212 se->expr = build_fold_indirect_ref (var);
973ff4c0 2213 }
6de9cd9a 2214 }
6de9cd9a 2215 }
dda895f9 2216
f5f701ad
PT
2217 /* Follow the function call with the argument post block. */
2218 if (byref)
2219 gfc_add_block_to_block (&se->pre, &post);
2220 else
2221 gfc_add_block_to_block (&se->post, &post);
2222
dda895f9 2223 return has_alternate_specifier;
6de9cd9a
DN
2224}
2225
2226
7b5b57b7
PB
2227/* Generate code to copy a string. */
2228
2229static void
2230gfc_trans_string_copy (stmtblock_t * block, tree dlen, tree dest,
2231 tree slen, tree src)
2232{
2233 tree tmp;
0a821a92
FW
2234 tree dsc;
2235 tree ssc;
549033f3 2236 tree cond;
b3eb1e0e
FXC
2237 tree cond2;
2238 tree tmp2;
2239 tree tmp3;
2240 tree tmp4;
2241 stmtblock_t tempblock;
0a821a92
FW
2242
2243 /* Deal with single character specially. */
2244 dsc = gfc_to_single_character (dlen, dest);
2245 ssc = gfc_to_single_character (slen, src);
2246 if (dsc != NULL_TREE && ssc != NULL_TREE)
2247 {
2248 gfc_add_modify_expr (block, dsc, ssc);
2249 return;
2250 }
7b5b57b7 2251
b3eb1e0e 2252 /* Do nothing if the destination length is zero. */
549033f3
FXC
2253 cond = fold_build2 (GT_EXPR, boolean_type_node, dlen,
2254 build_int_cst (gfc_charlen_type_node, 0));
2255
b3eb1e0e
FXC
2256 /* The following code was previously in _gfortran_copy_string:
2257
2258 // The two strings may overlap so we use memmove.
2259 void
2260 copy_string (GFC_INTEGER_4 destlen, char * dest,
2261 GFC_INTEGER_4 srclen, const char * src)
2262 {
2263 if (srclen >= destlen)
2264 {
2265 // This will truncate if too long.
2266 memmove (dest, src, destlen);
2267 }
2268 else
2269 {
2270 memmove (dest, src, srclen);
2271 // Pad with spaces.
2272 memset (&dest[srclen], ' ', destlen - srclen);
2273 }
2274 }
2275
2276 We're now doing it here for better optimization, but the logic
2277 is the same. */
2278
2279 /* Truncate string if source is too long. */
2280 cond2 = fold_build2 (GE_EXPR, boolean_type_node, slen, dlen);
2281 tmp2 = gfc_chainon_list (NULL_TREE, dest);
2282 tmp2 = gfc_chainon_list (tmp2, src);
2283 tmp2 = gfc_chainon_list (tmp2, dlen);
2284 tmp2 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp2);
2285
2286 /* Else copy and pad with spaces. */
2287 tmp3 = gfc_chainon_list (NULL_TREE, dest);
2288 tmp3 = gfc_chainon_list (tmp3, src);
2289 tmp3 = gfc_chainon_list (tmp3, slen);
2290 tmp3 = build_function_call_expr (built_in_decls[BUILT_IN_MEMMOVE], tmp3);
2291
2292 tmp4 = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
2293 fold_convert (pchar_type_node, slen));
2294 tmp4 = gfc_chainon_list (NULL_TREE, tmp4);
2295 tmp4 = gfc_chainon_list (tmp4, build_int_cst
2296 (gfc_get_int_type (gfc_c_int_kind),
2297 lang_hooks.to_target_charset (' ')));
2298 tmp4 = gfc_chainon_list (tmp4, fold_build2 (MINUS_EXPR, TREE_TYPE(dlen),
2299 dlen, slen));
2300 tmp4 = build_function_call_expr (built_in_decls[BUILT_IN_MEMSET], tmp4);
2301
2302 gfc_init_block (&tempblock);
2303 gfc_add_expr_to_block (&tempblock, tmp3);
2304 gfc_add_expr_to_block (&tempblock, tmp4);
2305 tmp3 = gfc_finish_block (&tempblock);
2306
2307 /* The whole copy_string function is there. */
2308 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
549033f3 2309 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
7b5b57b7
PB
2310 gfc_add_expr_to_block (block, tmp);
2311}
2312
2313
6de9cd9a
DN
2314/* Translate a statement function.
2315 The value of a statement function reference is obtained by evaluating the
2316 expression using the values of the actual arguments for the values of the
2317 corresponding dummy arguments. */
2318
2319static void
2320gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
2321{
2322 gfc_symbol *sym;
2323 gfc_symbol *fsym;
2324 gfc_formal_arglist *fargs;
2325 gfc_actual_arglist *args;
2326 gfc_se lse;
2327 gfc_se rse;
7b5b57b7
PB
2328 gfc_saved_var *saved_vars;
2329 tree *temp_vars;
2330 tree type;
2331 tree tmp;
2332 int n;
6de9cd9a
DN
2333
2334 sym = expr->symtree->n.sym;
2335 args = expr->value.function.actual;
2336 gfc_init_se (&lse, NULL);
2337 gfc_init_se (&rse, NULL);
2338
7b5b57b7 2339 n = 0;
6de9cd9a 2340 for (fargs = sym->formal; fargs; fargs = fargs->next)
7b5b57b7
PB
2341 n++;
2342 saved_vars = (gfc_saved_var *)gfc_getmem (n * sizeof (gfc_saved_var));
2343 temp_vars = (tree *)gfc_getmem (n * sizeof (tree));
2344
2345 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
6de9cd9a
DN
2346 {
2347 /* Each dummy shall be specified, explicitly or implicitly, to be
2348 scalar. */
6e45f57b 2349 gcc_assert (fargs->sym->attr.dimension == 0);
6de9cd9a 2350 fsym = fargs->sym;
6de9cd9a 2351
7b5b57b7
PB
2352 /* Create a temporary to hold the value. */
2353 type = gfc_typenode_for_spec (&fsym->ts);
2354 temp_vars[n] = gfc_create_var (type, fsym->name);
2355
2356 if (fsym->ts.type == BT_CHARACTER)
6de9cd9a 2357 {
7b5b57b7
PB
2358 /* Copy string arguments. */
2359 tree arglen;
6de9cd9a 2360
6e45f57b 2361 gcc_assert (fsym->ts.cl && fsym->ts.cl->length
6de9cd9a
DN
2362 && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
2363
7b5b57b7
PB
2364 arglen = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
2365 tmp = gfc_build_addr_expr (build_pointer_type (type),
2366 temp_vars[n]);
6de9cd9a
DN
2367
2368 gfc_conv_expr (&rse, args->expr);
2369 gfc_conv_string_parameter (&rse);
6de9cd9a
DN
2370 gfc_add_block_to_block (&se->pre, &lse.pre);
2371 gfc_add_block_to_block (&se->pre, &rse.pre);
2372
7b5b57b7
PB
2373 gfc_trans_string_copy (&se->pre, arglen, tmp, rse.string_length,
2374 rse.expr);
6de9cd9a
DN
2375 gfc_add_block_to_block (&se->pre, &lse.post);
2376 gfc_add_block_to_block (&se->pre, &rse.post);
2377 }
2378 else
2379 {
2380 /* For everything else, just evaluate the expression. */
6de9cd9a
DN
2381 gfc_conv_expr (&lse, args->expr);
2382
2383 gfc_add_block_to_block (&se->pre, &lse.pre);
7b5b57b7 2384 gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
6de9cd9a
DN
2385 gfc_add_block_to_block (&se->pre, &lse.post);
2386 }
7b5b57b7 2387
6de9cd9a
DN
2388 args = args->next;
2389 }
7b5b57b7
PB
2390
2391 /* Use the temporary variables in place of the real ones. */
2392 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2393 gfc_shadow_sym (fargs->sym, temp_vars[n], &saved_vars[n]);
2394
6de9cd9a 2395 gfc_conv_expr (se, sym->value);
7b5b57b7
PB
2396
2397 if (sym->ts.type == BT_CHARACTER)
2398 {
2399 gfc_conv_const_charlen (sym->ts.cl);
2400
2401 /* Force the expression to the correct length. */
2402 if (!INTEGER_CST_P (se->string_length)
2403 || tree_int_cst_lt (se->string_length,
2404 sym->ts.cl->backend_decl))
2405 {
2406 type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
2407 tmp = gfc_create_var (type, sym->name);
2408 tmp = gfc_build_addr_expr (build_pointer_type (type), tmp);
2409 gfc_trans_string_copy (&se->pre, sym->ts.cl->backend_decl, tmp,
2410 se->string_length, se->expr);
2411 se->expr = tmp;
2412 }
2413 se->string_length = sym->ts.cl->backend_decl;
2414 }
2415
f8d0aee5 2416 /* Restore the original variables. */
7b5b57b7
PB
2417 for (fargs = sym->formal, n = 0; fargs; fargs = fargs->next, n++)
2418 gfc_restore_sym (fargs->sym, &saved_vars[n]);
2419 gfc_free (saved_vars);
6de9cd9a
DN
2420}
2421
2422
2423/* Translate a function expression. */
2424
2425static void
2426gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
2427{
2428 gfc_symbol *sym;
2429
2430 if (expr->value.function.isym)
2431 {
2432 gfc_conv_intrinsic_function (se, expr);
2433 return;
2434 }
2435
f8d0aee5 2436 /* We distinguish statement functions from general functions to improve
6de9cd9a
DN
2437 runtime performance. */
2438 if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
2439 {
2440 gfc_conv_statement_function (se, expr);
2441 return;
2442 }
2443
2444 /* expr.value.function.esym is the resolved (specific) function symbol for
2445 most functions. However this isn't set for dummy procedures. */
2446 sym = expr->value.function.esym;
2447 if (!sym)
2448 sym = expr->symtree->n.sym;
2449 gfc_conv_function_call (se, sym, expr->value.function.actual);
2450}
2451
f8d0aee5 2452
6de9cd9a
DN
2453static void
2454gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
2455{
6e45f57b
PB
2456 gcc_assert (se->ss != NULL && se->ss != gfc_ss_terminator);
2457 gcc_assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
6de9cd9a
DN
2458
2459 gfc_conv_tmp_array_ref (se);
2460 gfc_advance_se_ss_chain (se);
2461}
2462
2463
597073ac 2464/* Build a static initializer. EXPR is the expression for the initial value.
f8d0aee5
TS
2465 The other parameters describe the variable of the component being
2466 initialized. EXPR may be null. */
6de9cd9a 2467
597073ac
PB
2468tree
2469gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
2470 bool array, bool pointer)
2471{
2472 gfc_se se;
2473
2474 if (!(expr || pointer))
2475 return NULL_TREE;
2476
2477 if (array)
2478 {
2479 /* Arrays need special handling. */
2480 if (pointer)
2481 return gfc_build_null_descriptor (type);
2482 else
2483 return gfc_conv_array_initializer (type, expr);
2484 }
2485 else if (pointer)
2486 return fold_convert (type, null_pointer_node);
2487 else
2488 {
2489 switch (ts->type)
2490 {
2491 case BT_DERIVED:
2492 gfc_init_se (&se, NULL);
2493 gfc_conv_structure (&se, expr, 1);
2494 return se.expr;
2495
2496 case BT_CHARACTER:
2497 return gfc_conv_string_init (ts->cl->backend_decl,expr);
2498
2499 default:
2500 gfc_init_se (&se, NULL);
2501 gfc_conv_constant (&se, expr);
2502 return se.expr;
2503 }
2504 }
2505}
2506
e9cfef64
PB
2507static tree
2508gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2509{
2510 gfc_se rse;
2511 gfc_se lse;
2512 gfc_ss *rss;
2513 gfc_ss *lss;
2514 stmtblock_t body;
2515 stmtblock_t block;
2516 gfc_loopinfo loop;
2517 int n;
2518 tree tmp;
2519
2520 gfc_start_block (&block);
2521
2522 /* Initialize the scalarizer. */
2523 gfc_init_loopinfo (&loop);
2524
2525 gfc_init_se (&lse, NULL);
2526 gfc_init_se (&rse, NULL);
2527
2528 /* Walk the rhs. */
2529 rss = gfc_walk_expr (expr);
2530 if (rss == gfc_ss_terminator)
2531 {
2532 /* The rhs is scalar. Add a ss for the expression. */
2533 rss = gfc_get_ss ();
2534 rss->next = gfc_ss_terminator;
2535 rss->type = GFC_SS_SCALAR;
2536 rss->expr = expr;
2537 }
2538
2539 /* Create a SS for the destination. */
2540 lss = gfc_get_ss ();
2541 lss->type = GFC_SS_COMPONENT;
2542 lss->expr = NULL;
2543 lss->shape = gfc_get_shape (cm->as->rank);
2544 lss->next = gfc_ss_terminator;
2545 lss->data.info.dimen = cm->as->rank;
2546 lss->data.info.descriptor = dest;
2547 lss->data.info.data = gfc_conv_array_data (dest);
2548 lss->data.info.offset = gfc_conv_array_offset (dest);
2549 for (n = 0; n < cm->as->rank; n++)
2550 {
2551 lss->data.info.dim[n] = n;
2552 lss->data.info.start[n] = gfc_conv_array_lbound (dest, n);
2553 lss->data.info.stride[n] = gfc_index_one_node;
2554
2555 mpz_init (lss->shape[n]);
2556 mpz_sub (lss->shape[n], cm->as->upper[n]->value.integer,
2557 cm->as->lower[n]->value.integer);
2558 mpz_add_ui (lss->shape[n], lss->shape[n], 1);
2559 }
2560
2561 /* Associate the SS with the loop. */
2562 gfc_add_ss_to_loop (&loop, lss);
2563 gfc_add_ss_to_loop (&loop, rss);
2564
2565 /* Calculate the bounds of the scalarization. */
2566 gfc_conv_ss_startstride (&loop);
2567
2568 /* Setup the scalarizing loops. */
2569 gfc_conv_loop_setup (&loop);
2570
2571 /* Setup the gfc_se structures. */
2572 gfc_copy_loopinfo_to_se (&lse, &loop);
2573 gfc_copy_loopinfo_to_se (&rse, &loop);
2574
2575 rse.ss = rss;
2576 gfc_mark_ss_chain_used (rss, 1);
2577 lse.ss = lss;
2578 gfc_mark_ss_chain_used (lss, 1);
2579
2580 /* Start the scalarized loop body. */
2581 gfc_start_scalarized_body (&loop, &body);
2582
2583 gfc_conv_tmp_array_ref (&lse);
2b052ce2
PT
2584 if (cm->ts.type == BT_CHARACTER)
2585 lse.string_length = cm->ts.cl->backend_decl;
2586
e9cfef64
PB
2587 gfc_conv_expr (&rse, expr);
2588
2589 tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts.type);
2590 gfc_add_expr_to_block (&body, tmp);
2591
6e45f57b 2592 gcc_assert (rse.ss == gfc_ss_terminator);
e9cfef64
PB
2593
2594 /* Generate the copying loops. */
2595 gfc_trans_scalarizing_loops (&loop, &body);
2596
2597 /* Wrap the whole thing up. */
2598 gfc_add_block_to_block (&block, &loop.pre);
2599 gfc_add_block_to_block (&block, &loop.post);
2600
e9cfef64
PB
2601 for (n = 0; n < cm->as->rank; n++)
2602 mpz_clear (lss->shape[n]);
2603 gfc_free (lss->shape);
2604
96654664
PB
2605 gfc_cleanup_loop (&loop);
2606
e9cfef64
PB
2607 return gfc_finish_block (&block);
2608}
2609
2610/* Assign a single component of a derived type constructor. */
2611
2612static tree
2613gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
2614{
2615 gfc_se se;
2616 gfc_ss *rss;
2617 stmtblock_t block;
2618 tree tmp;
2619
2620 gfc_start_block (&block);
2621 if (cm->pointer)
2622 {
2623 gfc_init_se (&se, NULL);
2624 /* Pointer component. */
2625 if (cm->dimension)
2626 {
2627 /* Array pointer. */
2628 if (expr->expr_type == EXPR_NULL)
4c73896d 2629 gfc_conv_descriptor_data_set (&block, dest, null_pointer_node);
e9cfef64
PB
2630 else
2631 {
2632 rss = gfc_walk_expr (expr);
2633 se.direct_byref = 1;
2634 se.expr = dest;
2635 gfc_conv_expr_descriptor (&se, expr, rss);
2636 gfc_add_block_to_block (&block, &se.pre);
2637 gfc_add_block_to_block (&block, &se.post);
2638 }
2639 }
2640 else
2641 {
2642 /* Scalar pointers. */
2643 se.want_pointer = 1;
2644 gfc_conv_expr (&se, expr);
2645 gfc_add_block_to_block (&block, &se.pre);
2646 gfc_add_modify_expr (&block, dest,
2647 fold_convert (TREE_TYPE (dest), se.expr));
2648 gfc_add_block_to_block (&block, &se.post);
2649 }
2650 }
2651 else if (cm->dimension)
2652 {
2653 tmp = gfc_trans_subarray_assign (dest, cm, expr);
2654 gfc_add_expr_to_block (&block, tmp);
2655 }
2656 else if (expr->ts.type == BT_DERIVED)
2657 {
13795658 2658 /* Nested derived type. */
e9cfef64
PB
2659 tmp = gfc_trans_structure_assign (dest, expr);
2660 gfc_add_expr_to_block (&block, tmp);
2661 }
2662 else
2663 {
2664 /* Scalar component. */
2665 gfc_se lse;
2666
2667 gfc_init_se (&se, NULL);
2668 gfc_init_se (&lse, NULL);
2669
2670 gfc_conv_expr (&se, expr);
2671 if (cm->ts.type == BT_CHARACTER)
2672 lse.string_length = cm->ts.cl->backend_decl;
2673 lse.expr = dest;
2674 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts.type);
2675 gfc_add_expr_to_block (&block, tmp);
2676 }
2677 return gfc_finish_block (&block);
2678}
2679
13795658 2680/* Assign a derived type constructor to a variable. */
e9cfef64
PB
2681
2682static tree
2683gfc_trans_structure_assign (tree dest, gfc_expr * expr)
2684{
2685 gfc_constructor *c;
2686 gfc_component *cm;
2687 stmtblock_t block;
2688 tree field;
2689 tree tmp;
2690
2691 gfc_start_block (&block);
2692 cm = expr->ts.derived->components;
2693 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
2694 {
2695 /* Skip absent members in default initializers. */
2696 if (!c->expr)
2697 continue;
2698
2699 field = cm->backend_decl;
923ab88c 2700 tmp = build3 (COMPONENT_REF, TREE_TYPE (field), dest, field, NULL_TREE);
e9cfef64
PB
2701 tmp = gfc_trans_subcomponent_assign (tmp, cm, c->expr);
2702 gfc_add_expr_to_block (&block, tmp);
2703 }
2704 return gfc_finish_block (&block);
2705}
2706
6de9cd9a
DN
2707/* Build an expression for a constructor. If init is nonzero then
2708 this is part of a static variable initializer. */
2709
2710void
2711gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
2712{
2713 gfc_constructor *c;
2714 gfc_component *cm;
6de9cd9a 2715 tree val;
6de9cd9a 2716 tree type;
e9cfef64 2717 tree tmp;
4038c495 2718 VEC(constructor_elt,gc) *v = NULL;
6de9cd9a 2719
6e45f57b
PB
2720 gcc_assert (se->ss == NULL);
2721 gcc_assert (expr->expr_type == EXPR_STRUCTURE);
6de9cd9a 2722 type = gfc_typenode_for_spec (&expr->ts);
e9cfef64
PB
2723
2724 if (!init)
2725 {
2726 /* Create a temporary variable and fill it in. */
2727 se->expr = gfc_create_var (type, expr->ts.derived->name);
2728 tmp = gfc_trans_structure_assign (se->expr, expr);
2729 gfc_add_expr_to_block (&se->pre, tmp);
2730 return;
2731 }
2732
6de9cd9a
DN
2733 cm = expr->ts.derived->components;
2734 for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
2735 {
2736 /* Skip absent members in default initializers. */
2737 if (!c->expr)
2738 continue;
2739
e9cfef64
PB
2740 val = gfc_conv_initializer (c->expr, &cm->ts,
2741 TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
6de9cd9a 2742
4038c495
GB
2743 /* Append it to the constructor list. */
2744 CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
6de9cd9a 2745 }
4038c495 2746 se->expr = build_constructor (type, v);
6de9cd9a
DN
2747}
2748
2749
f8d0aee5 2750/* Translate a substring expression. */
6de9cd9a
DN
2751
2752static void
2753gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
2754{
2755 gfc_ref *ref;
2756
2757 ref = expr->ref;
2758
6e45f57b 2759 gcc_assert (ref->type == REF_SUBSTRING);
6de9cd9a
DN
2760
2761 se->expr = gfc_build_string_const(expr->value.character.length,
2762 expr->value.character.string);
2763 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
2764 TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
2765
2766 gfc_conv_substring(se,ref,expr->ts.kind);
2767}
2768
2769
a4f5cd44
PB
2770/* Entry point for expression translation. Evaluates a scalar quantity.
2771 EXPR is the expression to be translated, and SE is the state structure if
2772 called from within the scalarized. */
6de9cd9a
DN
2773
2774void
2775gfc_conv_expr (gfc_se * se, gfc_expr * expr)
2776{
2777 if (se->ss && se->ss->expr == expr
2778 && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
2779 {
e9cfef64 2780 /* Substitute a scalar expression evaluated outside the scalarization
6de9cd9a
DN
2781 loop. */
2782 se->expr = se->ss->data.scalar.expr;
40f20186 2783 se->string_length = se->ss->string_length;
6de9cd9a
DN
2784 gfc_advance_se_ss_chain (se);
2785 return;
2786 }
2787
2788 switch (expr->expr_type)
2789 {
2790 case EXPR_OP:
2791 gfc_conv_expr_op (se, expr);
2792 break;
2793
2794 case EXPR_FUNCTION:
2795 gfc_conv_function_expr (se, expr);
2796 break;
2797
2798 case EXPR_CONSTANT:
2799 gfc_conv_constant (se, expr);
2800 break;
2801
2802 case EXPR_VARIABLE:
2803 gfc_conv_variable (se, expr);
2804 break;
2805
2806 case EXPR_NULL:
2807 se->expr = null_pointer_node;
2808 break;
2809
2810 case EXPR_SUBSTRING:
2811 gfc_conv_substring_expr (se, expr);
2812 break;
2813
2814 case EXPR_STRUCTURE:
2815 gfc_conv_structure (se, expr, 0);
2816 break;
2817
2818 case EXPR_ARRAY:
2819 gfc_conv_array_constructor_expr (se, expr);
2820 break;
2821
2822 default:
6e45f57b 2823 gcc_unreachable ();
6de9cd9a
DN
2824 break;
2825 }
2826}
2827
a4f5cd44
PB
2828/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
2829 of an assignment. */
6de9cd9a
DN
2830void
2831gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
2832{
2833 gfc_conv_expr (se, expr);
a4f5cd44 2834 /* All numeric lvalues should have empty post chains. If not we need to
6de9cd9a 2835 figure out a way of rewriting an lvalue so that it has no post chain. */
a4f5cd44 2836 gcc_assert (expr->ts.type == BT_CHARACTER || !se->post.head);
6de9cd9a
DN
2837}
2838
a4f5cd44 2839/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
417ab240 2840 numeric expressions. Used for scalar values where inserting cleanup code
a4f5cd44 2841 is inconvenient. */
6de9cd9a
DN
2842void
2843gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
2844{
2845 tree val;
2846
6e45f57b 2847 gcc_assert (expr->ts.type != BT_CHARACTER);
6de9cd9a
DN
2848 gfc_conv_expr (se, expr);
2849 if (se->post.head)
2850 {
2851 val = gfc_create_var (TREE_TYPE (se->expr), NULL);
2852 gfc_add_modify_expr (&se->pre, val, se->expr);
a4f5cd44
PB
2853 se->expr = val;
2854 gfc_add_block_to_block (&se->pre, &se->post);
6de9cd9a
DN
2855 }
2856}
2857
a4f5cd44 2858/* Helper to translate and expression and convert it to a particular type. */
6de9cd9a
DN
2859void
2860gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
2861{
2862 gfc_conv_expr_val (se, expr);
2863 se->expr = convert (type, se->expr);
2864}
2865
2866
f8d0aee5 2867/* Converts an expression so that it can be passed by reference. Scalar
6de9cd9a
DN
2868 values only. */
2869
2870void
2871gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
2872{
2873 tree var;
2874
2875 if (se->ss && se->ss->expr == expr
2876 && se->ss->type == GFC_SS_REFERENCE)
2877 {
2878 se->expr = se->ss->data.scalar.expr;
40f20186 2879 se->string_length = se->ss->string_length;
6de9cd9a
DN
2880 gfc_advance_se_ss_chain (se);
2881 return;
2882 }
2883
2884 if (expr->ts.type == BT_CHARACTER)
2885 {
2886 gfc_conv_expr (se, expr);
2887 gfc_conv_string_parameter (se);
2888 return;
2889 }
2890
2891 if (expr->expr_type == EXPR_VARIABLE)
2892 {
2893 se->want_pointer = 1;
2894 gfc_conv_expr (se, expr);
2895 if (se->post.head)
2896 {
2897 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
2898 gfc_add_modify_expr (&se->pre, var, se->expr);
2899 gfc_add_block_to_block (&se->pre, &se->post);
2900 se->expr = var;
2901 }
2902 return;
2903 }
2904
2905 gfc_conv_expr (se, expr);
2906
2907 /* Create a temporary var to hold the value. */
0534fa56
RH
2908 if (TREE_CONSTANT (se->expr))
2909 {
2910 var = build_decl (CONST_DECL, NULL, TREE_TYPE (se->expr));
2911 DECL_INITIAL (var) = se->expr;
2912 pushdecl (var);
2913 }
2914 else
2915 {
2916 var = gfc_create_var (TREE_TYPE (se->expr), NULL);
2917 gfc_add_modify_expr (&se->pre, var, se->expr);
2918 }
6de9cd9a
DN
2919 gfc_add_block_to_block (&se->pre, &se->post);
2920
2921 /* Take the address of that value. */
488ce07b 2922 se->expr = build_fold_addr_expr (var);
6de9cd9a
DN
2923}
2924
2925
2926tree
2927gfc_trans_pointer_assign (gfc_code * code)
2928{
2929 return gfc_trans_pointer_assignment (code->expr, code->expr2);
2930}
2931
2932
fc90a8f2
PB
2933/* Generate code for a pointer assignment. */
2934
6de9cd9a
DN
2935tree
2936gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
2937{
2938 gfc_se lse;
2939 gfc_se rse;
2940 gfc_ss *lss;
2941 gfc_ss *rss;
2942 stmtblock_t block;
8aeca7fd
RS
2943 tree desc;
2944 tree tmp;
6de9cd9a
DN
2945
2946 gfc_start_block (&block);
2947
2948 gfc_init_se (&lse, NULL);
2949
2950 lss = gfc_walk_expr (expr1);
2951 rss = gfc_walk_expr (expr2);
2952 if (lss == gfc_ss_terminator)
2953 {
fc90a8f2 2954 /* Scalar pointers. */
6de9cd9a
DN
2955 lse.want_pointer = 1;
2956 gfc_conv_expr (&lse, expr1);
6e45f57b 2957 gcc_assert (rss == gfc_ss_terminator);
6de9cd9a
DN
2958 gfc_init_se (&rse, NULL);
2959 rse.want_pointer = 1;
2960 gfc_conv_expr (&rse, expr2);
2961 gfc_add_block_to_block (&block, &lse.pre);
2962 gfc_add_block_to_block (&block, &rse.pre);
7ab92584
SB
2963 gfc_add_modify_expr (&block, lse.expr,
2964 fold_convert (TREE_TYPE (lse.expr), rse.expr));
6de9cd9a
DN
2965 gfc_add_block_to_block (&block, &rse.post);
2966 gfc_add_block_to_block (&block, &lse.post);
2967 }
2968 else
2969 {
fc90a8f2 2970 /* Array pointer. */
6de9cd9a 2971 gfc_conv_expr_descriptor (&lse, expr1, lss);
8aeca7fd
RS
2972 switch (expr2->expr_type)
2973 {
2974 case EXPR_NULL:
2975 /* Just set the data pointer to null. */
2976 gfc_conv_descriptor_data_set (&block, lse.expr, null_pointer_node);
2977 break;
2978
2979 case EXPR_VARIABLE:
2980 /* Assign directly to the pointer's descriptor. */
6de9cd9a 2981 lse.direct_byref = 1;
8aeca7fd
RS
2982 gfc_conv_expr_descriptor (&lse, expr2, rss);
2983 break;
2984
2985 default:
2986 /* Assign to a temporary descriptor and then copy that
2987 temporary to the pointer. */
2988 desc = lse.expr;
2989 tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
2990
2991 lse.expr = tmp;
2992 lse.direct_byref = 1;
2993 gfc_conv_expr_descriptor (&lse, expr2, rss);
2994 gfc_add_modify_expr (&lse.pre, desc, tmp);
2995 break;
6de9cd9a
DN
2996 }
2997 gfc_add_block_to_block (&block, &lse.pre);
2998 gfc_add_block_to_block (&block, &lse.post);
2999 }
3000 return gfc_finish_block (&block);
3001}
3002
3003
3004/* Makes sure se is suitable for passing as a function string parameter. */
3005/* TODO: Need to check all callers fo this function. It may be abused. */
3006
3007void
3008gfc_conv_string_parameter (gfc_se * se)
3009{
3010 tree type;
3011
3012 if (TREE_CODE (se->expr) == STRING_CST)
3013 {
3014 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3015 return;
3016 }
3017
3018 type = TREE_TYPE (se->expr);
3019 if (TYPE_STRING_FLAG (type))
3020 {
6e45f57b 3021 gcc_assert (TREE_CODE (se->expr) != INDIRECT_REF);
6de9cd9a
DN
3022 se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
3023 }
3024
6e45f57b
PB
3025 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
3026 gcc_assert (se->string_length
6de9cd9a
DN
3027 && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
3028}
3029
3030
3031/* Generate code for assignment of scalar variables. Includes character
3032 strings. */
3033
3034tree
3035gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, bt type)
3036{
6de9cd9a
DN
3037 stmtblock_t block;
3038
3039 gfc_init_block (&block);
3040
6de9cd9a
DN
3041 if (type == BT_CHARACTER)
3042 {
6e45f57b 3043 gcc_assert (lse->string_length != NULL_TREE
6de9cd9a
DN
3044 && rse->string_length != NULL_TREE);
3045
3046 gfc_conv_string_parameter (lse);
3047 gfc_conv_string_parameter (rse);
3048
3049 gfc_add_block_to_block (&block, &lse->pre);
3050 gfc_add_block_to_block (&block, &rse->pre);
3051
7b5b57b7
PB
3052 gfc_trans_string_copy (&block, lse->string_length, lse->expr,
3053 rse->string_length, rse->expr);
6de9cd9a
DN
3054 }
3055 else
3056 {
3057 gfc_add_block_to_block (&block, &lse->pre);
3058 gfc_add_block_to_block (&block, &rse->pre);
3059
7ab92584
SB
3060 gfc_add_modify_expr (&block, lse->expr,
3061 fold_convert (TREE_TYPE (lse->expr), rse->expr));
6de9cd9a
DN
3062 }
3063
3064 gfc_add_block_to_block (&block, &lse->post);
3065 gfc_add_block_to_block (&block, &rse->post);
3066
3067 return gfc_finish_block (&block);
3068}
3069
3070
3071/* Try to translate array(:) = func (...), where func is a transformational
3072 array function, without using a temporary. Returns NULL is this isn't the
3073 case. */
3074
3075static tree
3076gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
3077{
3078 gfc_se se;
3079 gfc_ss *ss;
2853e512
PT
3080 gfc_ref * ref;
3081 bool seen_array_ref;
6de9cd9a
DN
3082
3083 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
3084 if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
3085 return NULL;
3086
3087 /* Elemental functions don't need a temporary anyway. */
c4abe010
EE
3088 if (expr2->value.function.esym != NULL
3089 && expr2->value.function.esym->attr.elemental)
6de9cd9a
DN
3090 return NULL;
3091
7a70c12d
RS
3092 /* Fail if EXPR1 can't be expressed as a descriptor. */
3093 if (gfc_ref_needs_temporary_p (expr1->ref))
3094 return NULL;
3095
5b0b7251 3096 /* Functions returning pointers need temporaries. */
8e119f1b
EE
3097 if (expr2->symtree->n.sym->attr.pointer
3098 || expr2->symtree->n.sym->attr.allocatable)
5b0b7251
EE
3099 return NULL;
3100
2853e512
PT
3101 /* Check that no LHS component references appear during an array
3102 reference. This is needed because we do not have the means to
3103 span any arbitrary stride with an array descriptor. This check
3104 is not needed for the rhs because the function result has to be
3105 a complete type. */
3106 seen_array_ref = false;
3107 for (ref = expr1->ref; ref; ref = ref->next)
3108 {
3109 if (ref->type == REF_ARRAY)
3110 seen_array_ref= true;
3111 else if (ref->type == REF_COMPONENT && seen_array_ref)
3112 return NULL;
3113 }
3114
6de9cd9a 3115 /* Check for a dependency. */
1524f80b
RS
3116 if (gfc_check_fncall_dependency (expr1, INTENT_OUT,
3117 expr2->value.function.esym,
3118 expr2->value.function.actual))
6de9cd9a
DN
3119 return NULL;
3120
3121 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3122 functions. */
6e45f57b 3123 gcc_assert (expr2->value.function.isym
c0c07d7b
TS
3124 || (gfc_return_by_reference (expr2->value.function.esym)
3125 && expr2->value.function.esym->result->attr.dimension));
6de9cd9a
DN
3126
3127 ss = gfc_walk_expr (expr1);
6e45f57b 3128 gcc_assert (ss != gfc_ss_terminator);
6de9cd9a
DN
3129 gfc_init_se (&se, NULL);
3130 gfc_start_block (&se.pre);
3131 se.want_pointer = 1;
3132
3133 gfc_conv_array_parameter (&se, expr1, ss, 0);
3134
3135 se.direct_byref = 1;
3136 se.ss = gfc_walk_expr (expr2);
6e45f57b 3137 gcc_assert (se.ss != gfc_ss_terminator);
6de9cd9a 3138 gfc_conv_function_expr (&se, expr2);
6de9cd9a
DN
3139 gfc_add_block_to_block (&se.pre, &se.post);
3140
3141 return gfc_finish_block (&se.pre);
3142}
3143
3144
3145/* Translate an assignment. Most of the code is concerned with
3146 setting up the scalarizer. */
3147
3148tree
3149gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2)
3150{
3151 gfc_se lse;
3152 gfc_se rse;
3153 gfc_ss *lss;
3154 gfc_ss *lss_section;
3155 gfc_ss *rss;
3156 gfc_loopinfo loop;
3157 tree tmp;
3158 stmtblock_t block;
3159 stmtblock_t body;
3160
3161 /* Special case a single function returning an array. */
3162 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
3163 {
3164 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
3165 if (tmp)
3166 return tmp;
3167 }
3168
3169 /* Assignment of the form lhs = rhs. */
3170 gfc_start_block (&block);
3171
3172 gfc_init_se (&lse, NULL);
3173 gfc_init_se (&rse, NULL);
3174
3175 /* Walk the lhs. */
3176 lss = gfc_walk_expr (expr1);
3177 rss = NULL;
3178 if (lss != gfc_ss_terminator)
3179 {
3180 /* The assignment needs scalarization. */
3181 lss_section = lss;
3182
3183 /* Find a non-scalar SS from the lhs. */
3184 while (lss_section != gfc_ss_terminator
3185 && lss_section->type != GFC_SS_SECTION)
3186 lss_section = lss_section->next;
3187
6e45f57b 3188 gcc_assert (lss_section != gfc_ss_terminator);
6de9cd9a
DN
3189
3190 /* Initialize the scalarizer. */
3191 gfc_init_loopinfo (&loop);
3192
3193 /* Walk the rhs. */
3194 rss = gfc_walk_expr (expr2);
3195 if (rss == gfc_ss_terminator)
3196 {
3197 /* The rhs is scalar. Add a ss for the expression. */
3198 rss = gfc_get_ss ();
3199 rss->next = gfc_ss_terminator;
3200 rss->type = GFC_SS_SCALAR;
3201 rss->expr = expr2;
3202 }
3203 /* Associate the SS with the loop. */
3204 gfc_add_ss_to_loop (&loop, lss);
3205 gfc_add_ss_to_loop (&loop, rss);
3206
3207 /* Calculate the bounds of the scalarization. */
3208 gfc_conv_ss_startstride (&loop);
3209 /* Resolve any data dependencies in the statement. */
eca18fb4 3210 gfc_conv_resolve_dependencies (&loop, lss, rss);
6de9cd9a
DN
3211 /* Setup the scalarizing loops. */
3212 gfc_conv_loop_setup (&loop);
3213
3214 /* Setup the gfc_se structures. */
3215 gfc_copy_loopinfo_to_se (&lse, &loop);
3216 gfc_copy_loopinfo_to_se (&rse, &loop);
3217
3218 rse.ss = rss;
3219 gfc_mark_ss_chain_used (rss, 1);
3220 if (loop.temp_ss == NULL)
3221 {
3222 lse.ss = lss;
3223 gfc_mark_ss_chain_used (lss, 1);
3224 }
3225 else
3226 {
3227 lse.ss = loop.temp_ss;
3228 gfc_mark_ss_chain_used (lss, 3);
3229 gfc_mark_ss_chain_used (loop.temp_ss, 3);
3230 }
3231
3232 /* Start the scalarized loop body. */
3233 gfc_start_scalarized_body (&loop, &body);
3234 }
3235 else
3236 gfc_init_block (&body);
3237
3238 /* Translate the expression. */
3239 gfc_conv_expr (&rse, expr2);
3240
3241 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
3242 {
3243 gfc_conv_tmp_array_ref (&lse);
3244 gfc_advance_se_ss_chain (&lse);
3245 }
3246 else
3247 gfc_conv_expr (&lse, expr1);
ec09945c 3248
6de9cd9a
DN
3249 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
3250 gfc_add_expr_to_block (&body, tmp);
3251
3252 if (lss == gfc_ss_terminator)
3253 {
3254 /* Use the scalar assignment as is. */
3255 gfc_add_block_to_block (&block, &body);
3256 }
3257 else
3258 {
6e45f57b
PB
3259 gcc_assert (lse.ss == gfc_ss_terminator
3260 && rse.ss == gfc_ss_terminator);
6de9cd9a
DN
3261
3262 if (loop.temp_ss != NULL)
3263 {
3264 gfc_trans_scalarized_loop_boundary (&loop, &body);
3265
3266 /* We need to copy the temporary to the actual lhs. */
3267 gfc_init_se (&lse, NULL);
3268 gfc_init_se (&rse, NULL);
3269 gfc_copy_loopinfo_to_se (&lse, &loop);
3270 gfc_copy_loopinfo_to_se (&rse, &loop);
3271
3272 rse.ss = loop.temp_ss;
3273 lse.ss = lss;
3274
3275 gfc_conv_tmp_array_ref (&rse);
3276 gfc_advance_se_ss_chain (&rse);
3277 gfc_conv_expr (&lse, expr1);
3278
6e45f57b
PB
3279 gcc_assert (lse.ss == gfc_ss_terminator
3280 && rse.ss == gfc_ss_terminator);
6de9cd9a
DN
3281
3282 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
3283 gfc_add_expr_to_block (&body, tmp);
3284 }
3285 /* Generate the copying loops. */
3286 gfc_trans_scalarizing_loops (&loop, &body);
3287
3288 /* Wrap the whole thing up. */
3289 gfc_add_block_to_block (&block, &loop.pre);
3290 gfc_add_block_to_block (&block, &loop.post);
3291
3292 gfc_cleanup_loop (&loop);
3293 }
3294
3295 return gfc_finish_block (&block);
3296}
3297
3298tree
3299gfc_trans_assign (gfc_code * code)
3300{
3301 return gfc_trans_assignment (code->expr, code->expr2);
3302}
This page took 1.117734 seconds and 5 git commands to generate.