1 /* Expression translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
28 #include "coretypes.h"
34 #include "tree-gimple.h"
35 #include "langhooks.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43 #include "trans-stmt.h"
44 #include "dependency.h"
46 static tree
gfc_trans_structure_assign (tree dest
, gfc_expr
* expr
);
47 static int gfc_apply_interface_mapping_to_expr (gfc_interface_mapping
*,
50 /* Copy the scalarization loop variables. */
53 gfc_copy_se_loopvars (gfc_se
* dest
, gfc_se
* src
)
56 dest
->loop
= src
->loop
;
60 /* Initialize a simple expression holder.
62 Care must be taken when multiple se are created with the same parent.
63 The child se must be kept in sync. The easiest way is to delay creation
64 of a child se until after after the previous se has been translated. */
67 gfc_init_se (gfc_se
* se
, gfc_se
* parent
)
69 memset (se
, 0, sizeof (gfc_se
));
70 gfc_init_block (&se
->pre
);
71 gfc_init_block (&se
->post
);
76 gfc_copy_se_loopvars (se
, parent
);
80 /* Advances to the next SS in the chain. Use this rather than setting
81 se->ss = se->ss->next because all the parents needs to be kept in sync.
85 gfc_advance_se_ss_chain (gfc_se
* se
)
89 gcc_assert (se
!= NULL
&& se
->ss
!= NULL
&& se
->ss
!= gfc_ss_terminator
);
92 /* Walk down the parent chain. */
95 /* Simple consistency check. */
96 gcc_assert (p
->parent
== NULL
|| p
->parent
->ss
== p
->ss
);
105 /* Ensures the result of the expression as either a temporary variable
106 or a constant so that it can be used repeatedly. */
109 gfc_make_safe_expr (gfc_se
* se
)
113 if (CONSTANT_CLASS_P (se
->expr
))
116 /* We need a temporary for this result. */
117 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
118 gfc_add_modify_expr (&se
->pre
, var
, se
->expr
);
123 /* Return an expression which determines if a dummy parameter is present.
124 Also used for arguments to procedures with multiple entry points. */
127 gfc_conv_expr_present (gfc_symbol
* sym
)
131 gcc_assert (sym
->attr
.dummy
);
133 decl
= gfc_get_symbol_decl (sym
);
134 if (TREE_CODE (decl
) != PARM_DECL
)
136 /* Array parameters use a temporary descriptor, we want the real
138 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
))
139 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl
)));
140 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
142 return build2 (NE_EXPR
, boolean_type_node
, decl
,
143 fold_convert (TREE_TYPE (decl
), null_pointer_node
));
147 /* Converts a missing, dummy argument into a null or zero. */
150 gfc_conv_missing_dummy (gfc_se
* se
, gfc_expr
* arg
, gfc_typespec ts
)
155 present
= gfc_conv_expr_present (arg
->symtree
->n
.sym
);
156 tmp
= build3 (COND_EXPR
, TREE_TYPE (se
->expr
), present
, se
->expr
,
157 fold_convert (TREE_TYPE (se
->expr
), integer_zero_node
));
159 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
161 if (ts
.type
== BT_CHARACTER
)
163 tmp
= build_int_cst (gfc_charlen_type_node
, 0);
164 tmp
= build3 (COND_EXPR
, gfc_charlen_type_node
, present
,
165 se
->string_length
, tmp
);
166 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
167 se
->string_length
= tmp
;
173 /* Get the character length of an expression, looking through gfc_refs
177 gfc_get_expr_charlen (gfc_expr
*e
)
182 gcc_assert (e
->expr_type
== EXPR_VARIABLE
183 && e
->ts
.type
== BT_CHARACTER
);
185 length
= NULL
; /* To silence compiler warning. */
187 /* First candidate: if the variable is of type CHARACTER, the
188 expression's length could be the length of the character
190 if (e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
)
191 length
= e
->symtree
->n
.sym
->ts
.cl
->backend_decl
;
193 /* Look through the reference chain for component references. */
194 for (r
= e
->ref
; r
; r
= r
->next
)
199 if (r
->u
.c
.component
->ts
.type
== BT_CHARACTER
)
200 length
= r
->u
.c
.component
->ts
.cl
->backend_decl
;
208 /* We should never got substring references here. These will be
209 broken down by the scalarizer. */
214 gcc_assert (length
!= NULL
);
220 /* Generate code to initialize a string length variable. Returns the
224 gfc_trans_init_string_length (gfc_charlen
* cl
, stmtblock_t
* pblock
)
229 gfc_init_se (&se
, NULL
);
230 gfc_conv_expr_type (&se
, cl
->length
, gfc_charlen_type_node
);
231 se
.expr
= fold_build2 (MAX_EXPR
, gfc_charlen_type_node
, se
.expr
,
232 build_int_cst (gfc_charlen_type_node
, 0));
233 gfc_add_block_to_block (pblock
, &se
.pre
);
235 tmp
= cl
->backend_decl
;
236 gfc_add_modify_expr (pblock
, tmp
, se
.expr
);
241 gfc_conv_substring (gfc_se
* se
, gfc_ref
* ref
, int kind
,
242 const char *name
, locus
*where
)
252 type
= gfc_get_character_type (kind
, ref
->u
.ss
.length
);
253 type
= build_pointer_type (type
);
256 gfc_init_se (&start
, se
);
257 gfc_conv_expr_type (&start
, ref
->u
.ss
.start
, gfc_charlen_type_node
);
258 gfc_add_block_to_block (&se
->pre
, &start
.pre
);
260 if (integer_onep (start
.expr
))
261 gfc_conv_string_parameter (se
);
264 /* Avoid multiple evaluation of substring start. */
265 if (!CONSTANT_CLASS_P (start
.expr
) && !DECL_P (start
.expr
))
266 start
.expr
= gfc_evaluate_now (start
.expr
, &se
->pre
);
268 /* Change the start of the string. */
269 if (TYPE_STRING_FLAG (TREE_TYPE (se
->expr
)))
272 tmp
= build_fold_indirect_ref (se
->expr
);
273 tmp
= gfc_build_array_ref (tmp
, start
.expr
);
274 se
->expr
= gfc_build_addr_expr (type
, tmp
);
277 /* Length = end + 1 - start. */
278 gfc_init_se (&end
, se
);
279 if (ref
->u
.ss
.end
== NULL
)
280 end
.expr
= se
->string_length
;
283 gfc_conv_expr_type (&end
, ref
->u
.ss
.end
, gfc_charlen_type_node
);
284 gfc_add_block_to_block (&se
->pre
, &end
.pre
);
286 if (!CONSTANT_CLASS_P (end
.expr
) && !DECL_P (end
.expr
))
287 end
.expr
= gfc_evaluate_now (end
.expr
, &se
->pre
);
289 if (flag_bounds_check
)
291 tree nonempty
= fold_build2 (LE_EXPR
, boolean_type_node
,
292 start
.expr
, end
.expr
);
294 /* Check lower bound. */
295 fault
= fold_build2 (LT_EXPR
, boolean_type_node
, start
.expr
,
296 build_int_cst (gfc_charlen_type_node
, 1));
297 fault
= fold_build2 (TRUTH_ANDIF_EXPR
, boolean_type_node
,
300 asprintf (&msg
, "Substring out of bounds: lower bound of '%s' "
301 "is less than one", name
);
303 asprintf (&msg
, "Substring out of bounds: lower bound "
305 gfc_trans_runtime_check (fault
, msg
, &se
->pre
, where
);
308 /* Check upper bound. */
309 fault
= fold_build2 (GT_EXPR
, boolean_type_node
, end
.expr
,
311 fault
= fold_build2 (TRUTH_ANDIF_EXPR
, boolean_type_node
,
314 asprintf (&msg
, "Substring out of bounds: upper bound of '%s' "
315 "exceeds string length", name
);
317 asprintf (&msg
, "Substring out of bounds: upper bound "
318 "exceeds string length");
319 gfc_trans_runtime_check (fault
, msg
, &se
->pre
, where
);
323 tmp
= fold_build2 (MINUS_EXPR
, gfc_charlen_type_node
,
324 build_int_cst (gfc_charlen_type_node
, 1),
326 tmp
= fold_build2 (PLUS_EXPR
, gfc_charlen_type_node
, end
.expr
, tmp
);
327 tmp
= fold_build2 (MAX_EXPR
, gfc_charlen_type_node
, tmp
,
328 build_int_cst (gfc_charlen_type_node
, 0));
329 se
->string_length
= tmp
;
333 /* Convert a derived type component reference. */
336 gfc_conv_component_ref (gfc_se
* se
, gfc_ref
* ref
)
343 c
= ref
->u
.c
.component
;
345 gcc_assert (c
->backend_decl
);
347 field
= c
->backend_decl
;
348 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
350 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), decl
, field
, NULL_TREE
);
354 if (c
->ts
.type
== BT_CHARACTER
)
356 tmp
= c
->ts
.cl
->backend_decl
;
357 /* Components must always be constant length. */
358 gcc_assert (tmp
&& INTEGER_CST_P (tmp
));
359 se
->string_length
= tmp
;
362 if (c
->pointer
&& c
->dimension
== 0 && c
->ts
.type
!= BT_CHARACTER
)
363 se
->expr
= build_fold_indirect_ref (se
->expr
);
367 /* Return the contents of a variable. Also handles reference/pointer
368 variables (all Fortran pointer references are implicit). */
371 gfc_conv_variable (gfc_se
* se
, gfc_expr
* expr
)
378 bool alternate_entry
;
381 sym
= expr
->symtree
->n
.sym
;
384 /* Check that something hasn't gone horribly wrong. */
385 gcc_assert (se
->ss
!= gfc_ss_terminator
);
386 gcc_assert (se
->ss
->expr
== expr
);
388 /* A scalarized term. We already know the descriptor. */
389 se
->expr
= se
->ss
->data
.info
.descriptor
;
390 se
->string_length
= se
->ss
->string_length
;
391 for (ref
= se
->ss
->data
.info
.ref
; ref
; ref
= ref
->next
)
392 if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
397 tree se_expr
= NULL_TREE
;
399 se
->expr
= gfc_get_symbol_decl (sym
);
401 /* Deal with references to a parent results or entries by storing
402 the current_function_decl and moving to the parent_decl. */
403 return_value
= sym
->attr
.function
&& sym
->result
== sym
;
404 alternate_entry
= sym
->attr
.function
&& sym
->attr
.entry
405 && sym
->result
== sym
;
406 entry_master
= sym
->attr
.result
407 && sym
->ns
->proc_name
->attr
.entry_master
408 && !gfc_return_by_reference (sym
->ns
->proc_name
);
409 parent_decl
= DECL_CONTEXT (current_function_decl
);
411 if ((se
->expr
== parent_decl
&& return_value
)
412 || (sym
->ns
&& sym
->ns
->proc_name
414 && sym
->ns
->proc_name
->backend_decl
== parent_decl
415 && (alternate_entry
|| entry_master
)))
420 /* Special case for assigning the return value of a function.
421 Self recursive functions must have an explicit return value. */
422 if (return_value
&& (se
->expr
== current_function_decl
|| parent_flag
))
423 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
425 /* Similarly for alternate entry points. */
426 else if (alternate_entry
427 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
430 gfc_entry_list
*el
= NULL
;
432 for (el
= sym
->ns
->entries
; el
; el
= el
->next
)
435 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
440 else if (entry_master
441 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
443 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
448 /* Procedure actual arguments. */
449 else if (sym
->attr
.flavor
== FL_PROCEDURE
450 && se
->expr
!= current_function_decl
)
452 gcc_assert (se
->want_pointer
);
453 if (!sym
->attr
.dummy
)
455 gcc_assert (TREE_CODE (se
->expr
) == FUNCTION_DECL
);
456 se
->expr
= build_fold_addr_expr (se
->expr
);
462 /* Dereference the expression, where needed. Since characters
463 are entirely different from other types, they are treated
465 if (sym
->ts
.type
== BT_CHARACTER
)
467 /* Dereference character pointer dummy arguments
469 if ((sym
->attr
.pointer
|| sym
->attr
.allocatable
)
471 || sym
->attr
.function
472 || sym
->attr
.result
))
473 se
->expr
= build_fold_indirect_ref (se
->expr
);
475 /* A character with VALUE attribute needs an address
478 se
->expr
= build_fold_addr_expr (se
->expr
);
481 else if (!sym
->attr
.value
)
483 /* Dereference non-character scalar dummy arguments. */
484 if (sym
->attr
.dummy
&& !sym
->attr
.dimension
)
485 se
->expr
= build_fold_indirect_ref (se
->expr
);
487 /* Dereference scalar hidden result. */
488 if (gfc_option
.flag_f2c
&& sym
->ts
.type
== BT_COMPLEX
489 && (sym
->attr
.function
|| sym
->attr
.result
)
490 && !sym
->attr
.dimension
&& !sym
->attr
.pointer
)
491 se
->expr
= build_fold_indirect_ref (se
->expr
);
493 /* Dereference non-character pointer variables.
494 These must be dummies, results, or scalars. */
495 if ((sym
->attr
.pointer
|| sym
->attr
.allocatable
)
497 || sym
->attr
.function
499 || !sym
->attr
.dimension
))
500 se
->expr
= build_fold_indirect_ref (se
->expr
);
506 /* For character variables, also get the length. */
507 if (sym
->ts
.type
== BT_CHARACTER
)
509 /* If the character length of an entry isn't set, get the length from
510 the master function instead. */
511 if (sym
->attr
.entry
&& !sym
->ts
.cl
->backend_decl
)
512 se
->string_length
= sym
->ns
->proc_name
->ts
.cl
->backend_decl
;
514 se
->string_length
= sym
->ts
.cl
->backend_decl
;
515 gcc_assert (se
->string_length
);
523 /* Return the descriptor if that's what we want and this is an array
524 section reference. */
525 if (se
->descriptor_only
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
527 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
528 /* Return the descriptor for array pointers and allocations. */
530 && ref
->next
== NULL
&& (se
->descriptor_only
))
533 gfc_conv_array_ref (se
, &ref
->u
.ar
, sym
, &expr
->where
);
534 /* Return a pointer to an element. */
538 gfc_conv_component_ref (se
, ref
);
542 gfc_conv_substring (se
, ref
, expr
->ts
.kind
,
543 expr
->symtree
->name
, &expr
->where
);
552 /* Pointer assignment, allocation or pass by reference. Arrays are handled
554 if (se
->want_pointer
)
556 if (expr
->ts
.type
== BT_CHARACTER
)
557 gfc_conv_string_parameter (se
);
559 se
->expr
= build_fold_addr_expr (se
->expr
);
564 /* Unary ops are easy... Or they would be if ! was a valid op. */
567 gfc_conv_unary_op (enum tree_code code
, gfc_se
* se
, gfc_expr
* expr
)
572 gcc_assert (expr
->ts
.type
!= BT_CHARACTER
);
573 /* Initialize the operand. */
574 gfc_init_se (&operand
, se
);
575 gfc_conv_expr_val (&operand
, expr
->value
.op
.op1
);
576 gfc_add_block_to_block (&se
->pre
, &operand
.pre
);
578 type
= gfc_typenode_for_spec (&expr
->ts
);
580 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
581 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
582 All other unary operators have an equivalent GIMPLE unary operator. */
583 if (code
== TRUTH_NOT_EXPR
)
584 se
->expr
= build2 (EQ_EXPR
, type
, operand
.expr
,
585 build_int_cst (type
, 0));
587 se
->expr
= build1 (code
, type
, operand
.expr
);
591 /* Expand power operator to optimal multiplications when a value is raised
592 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
593 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
594 Programming", 3rd Edition, 1998. */
596 /* This code is mostly duplicated from expand_powi in the backend.
597 We establish the "optimal power tree" lookup table with the defined size.
598 The items in the table are the exponents used to calculate the index
599 exponents. Any integer n less than the value can get an "addition chain",
600 with the first node being one. */
601 #define POWI_TABLE_SIZE 256
603 /* The table is from builtins.c. */
604 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
606 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
607 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
608 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
609 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
610 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
611 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
612 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
613 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
614 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
615 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
616 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
617 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
618 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
619 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
620 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
621 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
622 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
623 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
624 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
625 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
626 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
627 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
628 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
629 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
630 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
631 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
632 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
633 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
634 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
635 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
636 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
637 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
640 /* If n is larger than lookup table's max index, we use the "window
642 #define POWI_WINDOW_SIZE 3
644 /* Recursive function to expand the power operator. The temporary
645 values are put in tmpvar. The function returns tmpvar[1] ** n. */
647 gfc_conv_powi (gfc_se
* se
, unsigned HOST_WIDE_INT n
, tree
* tmpvar
)
654 if (n
< POWI_TABLE_SIZE
)
659 op0
= gfc_conv_powi (se
, n
- powi_table
[n
], tmpvar
);
660 op1
= gfc_conv_powi (se
, powi_table
[n
], tmpvar
);
664 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
665 op0
= gfc_conv_powi (se
, n
- digit
, tmpvar
);
666 op1
= gfc_conv_powi (se
, digit
, tmpvar
);
670 op0
= gfc_conv_powi (se
, n
>> 1, tmpvar
);
674 tmp
= fold_build2 (MULT_EXPR
, TREE_TYPE (op0
), op0
, op1
);
675 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
677 if (n
< POWI_TABLE_SIZE
)
684 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
685 return 1. Else return 0 and a call to runtime library functions
686 will have to be built. */
688 gfc_conv_cst_int_power (gfc_se
* se
, tree lhs
, tree rhs
)
693 tree vartmp
[POWI_TABLE_SIZE
];
695 unsigned HOST_WIDE_INT n
;
698 /* If exponent is too large, we won't expand it anyway, so don't bother
699 with large integer values. */
700 if (!double_int_fits_in_shwi_p (TREE_INT_CST (rhs
)))
703 m
= double_int_to_shwi (TREE_INT_CST (rhs
));
704 /* There's no ABS for HOST_WIDE_INT, so here we go. It also takes care
705 of the asymmetric range of the integer type. */
706 n
= (unsigned HOST_WIDE_INT
) (m
< 0 ? -m
: m
);
708 type
= TREE_TYPE (lhs
);
709 sgn
= tree_int_cst_sgn (rhs
);
711 if (((FLOAT_TYPE_P (type
) && !flag_unsafe_math_optimizations
)
712 || optimize_size
) && (m
> 2 || m
< -1))
718 se
->expr
= gfc_build_const (type
, integer_one_node
);
722 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
723 if ((sgn
== -1) && (TREE_CODE (type
) == INTEGER_TYPE
))
725 tmp
= build2 (EQ_EXPR
, boolean_type_node
, lhs
,
726 build_int_cst (TREE_TYPE (lhs
), -1));
727 cond
= build2 (EQ_EXPR
, boolean_type_node
, lhs
,
728 build_int_cst (TREE_TYPE (lhs
), 1));
731 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
734 tmp
= build2 (TRUTH_OR_EXPR
, boolean_type_node
, tmp
, cond
);
735 se
->expr
= build3 (COND_EXPR
, type
, tmp
, build_int_cst (type
, 1),
736 build_int_cst (type
, 0));
740 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
741 tmp
= build3 (COND_EXPR
, type
, tmp
, build_int_cst (type
, -1),
742 build_int_cst (type
, 0));
743 se
->expr
= build3 (COND_EXPR
, type
, cond
, build_int_cst (type
, 1), tmp
);
747 memset (vartmp
, 0, sizeof (vartmp
));
751 tmp
= gfc_build_const (type
, integer_one_node
);
752 vartmp
[1] = build2 (RDIV_EXPR
, type
, tmp
, vartmp
[1]);
755 se
->expr
= gfc_conv_powi (se
, n
, vartmp
);
761 /* Power op (**). Constant integer exponent has special handling. */
764 gfc_conv_power_op (gfc_se
* se
, gfc_expr
* expr
)
766 tree gfc_int4_type_node
;
773 gfc_init_se (&lse
, se
);
774 gfc_conv_expr_val (&lse
, expr
->value
.op
.op1
);
775 lse
.expr
= gfc_evaluate_now (lse
.expr
, &lse
.pre
);
776 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
778 gfc_init_se (&rse
, se
);
779 gfc_conv_expr_val (&rse
, expr
->value
.op
.op2
);
780 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
782 if (expr
->value
.op
.op2
->ts
.type
== BT_INTEGER
783 && expr
->value
.op
.op2
->expr_type
== EXPR_CONSTANT
)
784 if (gfc_conv_cst_int_power (se
, lse
.expr
, rse
.expr
))
787 gfc_int4_type_node
= gfc_get_int_type (4);
789 kind
= expr
->value
.op
.op1
->ts
.kind
;
790 switch (expr
->value
.op
.op2
->ts
.type
)
793 ikind
= expr
->value
.op
.op2
->ts
.kind
;
798 rse
.expr
= convert (gfc_int4_type_node
, rse
.expr
);
820 if (expr
->value
.op
.op1
->ts
.type
== BT_INTEGER
)
821 lse
.expr
= convert (gfc_int4_type_node
, lse
.expr
);
846 switch (expr
->value
.op
.op1
->ts
.type
)
849 if (kind
== 3) /* Case 16 was not handled properly above. */
851 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].integer
;
855 /* Use builtins for real ** int4. */
861 fndecl
= built_in_decls
[BUILT_IN_POWIF
];
865 fndecl
= built_in_decls
[BUILT_IN_POWI
];
870 fndecl
= built_in_decls
[BUILT_IN_POWIL
];
878 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].real
;
882 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].cmplx
;
894 fndecl
= built_in_decls
[BUILT_IN_POWF
];
897 fndecl
= built_in_decls
[BUILT_IN_POW
];
901 fndecl
= built_in_decls
[BUILT_IN_POWL
];
912 fndecl
= gfor_fndecl_math_cpowf
;
915 fndecl
= gfor_fndecl_math_cpow
;
918 fndecl
= gfor_fndecl_math_cpowl10
;
921 fndecl
= gfor_fndecl_math_cpowl16
;
933 se
->expr
= build_call_expr (fndecl
, 2, lse
.expr
, rse
.expr
);
937 /* Generate code to allocate a string temporary. */
940 gfc_conv_string_tmp (gfc_se
* se
, tree type
, tree len
)
945 gcc_assert (TREE_TYPE (len
) == gfc_charlen_type_node
);
947 if (gfc_can_put_var_on_stack (len
))
949 /* Create a temporary variable to hold the result. */
950 tmp
= fold_build2 (MINUS_EXPR
, gfc_charlen_type_node
, len
,
951 build_int_cst (gfc_charlen_type_node
, 1));
952 tmp
= build_range_type (gfc_array_index_type
, gfc_index_zero_node
, tmp
);
953 tmp
= build_array_type (gfc_character1_type_node
, tmp
);
954 var
= gfc_create_var (tmp
, "str");
955 var
= gfc_build_addr_expr (type
, var
);
959 /* Allocate a temporary to hold the result. */
960 var
= gfc_create_var (type
, "pstr");
961 tmp
= gfc_call_malloc (&se
->pre
, type
, len
);
962 gfc_add_modify_expr (&se
->pre
, var
, tmp
);
964 /* Free the temporary afterwards. */
965 tmp
= gfc_call_free (convert (pvoid_type_node
, var
));
966 gfc_add_expr_to_block (&se
->post
, tmp
);
973 /* Handle a string concatenation operation. A temporary will be allocated to
977 gfc_conv_concat_op (gfc_se
* se
, gfc_expr
* expr
)
986 gcc_assert (expr
->value
.op
.op1
->ts
.type
== BT_CHARACTER
987 && expr
->value
.op
.op2
->ts
.type
== BT_CHARACTER
);
989 gfc_init_se (&lse
, se
);
990 gfc_conv_expr (&lse
, expr
->value
.op
.op1
);
991 gfc_conv_string_parameter (&lse
);
992 gfc_init_se (&rse
, se
);
993 gfc_conv_expr (&rse
, expr
->value
.op
.op2
);
994 gfc_conv_string_parameter (&rse
);
996 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
997 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
999 type
= gfc_get_character_type (expr
->ts
.kind
, expr
->ts
.cl
);
1000 len
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
1001 if (len
== NULL_TREE
)
1003 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (lse
.string_length
),
1004 lse
.string_length
, rse
.string_length
);
1007 type
= build_pointer_type (type
);
1009 var
= gfc_conv_string_tmp (se
, type
, len
);
1011 /* Do the actual concatenation. */
1012 tmp
= build_call_expr (gfor_fndecl_concat_string
, 6,
1014 lse
.string_length
, lse
.expr
,
1015 rse
.string_length
, rse
.expr
);
1016 gfc_add_expr_to_block (&se
->pre
, tmp
);
1018 /* Add the cleanup for the operands. */
1019 gfc_add_block_to_block (&se
->pre
, &rse
.post
);
1020 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
1023 se
->string_length
= len
;
1026 /* Translates an op expression. Common (binary) cases are handled by this
1027 function, others are passed on. Recursion is used in either case.
1028 We use the fact that (op1.ts == op2.ts) (except for the power
1030 Operators need no special handling for scalarized expressions as long as
1031 they call gfc_conv_simple_val to get their operands.
1032 Character strings get special handling. */
1035 gfc_conv_expr_op (gfc_se
* se
, gfc_expr
* expr
)
1037 enum tree_code code
;
1047 switch (expr
->value
.op
.operator)
1049 case INTRINSIC_UPLUS
:
1050 case INTRINSIC_PARENTHESES
:
1051 gfc_conv_expr (se
, expr
->value
.op
.op1
);
1054 case INTRINSIC_UMINUS
:
1055 gfc_conv_unary_op (NEGATE_EXPR
, se
, expr
);
1059 gfc_conv_unary_op (TRUTH_NOT_EXPR
, se
, expr
);
1062 case INTRINSIC_PLUS
:
1066 case INTRINSIC_MINUS
:
1070 case INTRINSIC_TIMES
:
1074 case INTRINSIC_DIVIDE
:
1075 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1076 an integer, we must round towards zero, so we use a
1078 if (expr
->ts
.type
== BT_INTEGER
)
1079 code
= TRUNC_DIV_EXPR
;
1084 case INTRINSIC_POWER
:
1085 gfc_conv_power_op (se
, expr
);
1088 case INTRINSIC_CONCAT
:
1089 gfc_conv_concat_op (se
, expr
);
1093 code
= TRUTH_ANDIF_EXPR
;
1098 code
= TRUTH_ORIF_EXPR
;
1102 /* EQV and NEQV only work on logicals, but since we represent them
1103 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
1105 case INTRINSIC_EQ_OS
:
1113 case INTRINSIC_NE_OS
:
1114 case INTRINSIC_NEQV
:
1121 case INTRINSIC_GT_OS
:
1128 case INTRINSIC_GE_OS
:
1135 case INTRINSIC_LT_OS
:
1142 case INTRINSIC_LE_OS
:
1148 case INTRINSIC_USER
:
1149 case INTRINSIC_ASSIGN
:
1150 /* These should be converted into function calls by the frontend. */
1154 fatal_error ("Unknown intrinsic op");
1158 /* The only exception to this is **, which is handled separately anyway. */
1159 gcc_assert (expr
->value
.op
.op1
->ts
.type
== expr
->value
.op
.op2
->ts
.type
);
1161 if (checkstring
&& expr
->value
.op
.op1
->ts
.type
!= BT_CHARACTER
)
1165 gfc_init_se (&lse
, se
);
1166 gfc_conv_expr (&lse
, expr
->value
.op
.op1
);
1167 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
1170 gfc_init_se (&rse
, se
);
1171 gfc_conv_expr (&rse
, expr
->value
.op
.op2
);
1172 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
1176 gfc_conv_string_parameter (&lse
);
1177 gfc_conv_string_parameter (&rse
);
1179 lse
.expr
= gfc_build_compare_string (lse
.string_length
, lse
.expr
,
1180 rse
.string_length
, rse
.expr
);
1181 rse
.expr
= build_int_cst (TREE_TYPE (lse
.expr
), 0);
1182 gfc_add_block_to_block (&lse
.post
, &rse
.post
);
1185 type
= gfc_typenode_for_spec (&expr
->ts
);
1189 /* The result of logical ops is always boolean_type_node. */
1190 tmp
= fold_build2 (code
, type
, lse
.expr
, rse
.expr
);
1191 se
->expr
= convert (type
, tmp
);
1194 se
->expr
= fold_build2 (code
, type
, lse
.expr
, rse
.expr
);
1196 /* Add the post blocks. */
1197 gfc_add_block_to_block (&se
->post
, &rse
.post
);
1198 gfc_add_block_to_block (&se
->post
, &lse
.post
);
1201 /* If a string's length is one, we convert it to a single character. */
1204 gfc_to_single_character (tree len
, tree str
)
1206 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str
)));
1208 if (INTEGER_CST_P (len
) && TREE_INT_CST_LOW (len
) == 1
1209 && TREE_INT_CST_HIGH (len
) == 0)
1211 str
= fold_convert (pchar_type_node
, str
);
1212 return build_fold_indirect_ref (str
);
1218 /* Compare two strings. If they are all single characters, the result is the
1219 subtraction of them. Otherwise, we build a library call. */
1222 gfc_build_compare_string (tree len1
, tree str1
, tree len2
, tree str2
)
1229 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1
)));
1230 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2
)));
1232 type
= gfc_get_int_type (gfc_default_integer_kind
);
1234 sc1
= gfc_to_single_character (len1
, str1
);
1235 sc2
= gfc_to_single_character (len2
, str2
);
1237 /* Deal with single character specially. */
1238 if (sc1
!= NULL_TREE
&& sc2
!= NULL_TREE
)
1240 sc1
= fold_convert (type
, sc1
);
1241 sc2
= fold_convert (type
, sc2
);
1242 tmp
= fold_build2 (MINUS_EXPR
, type
, sc1
, sc2
);
1245 /* Build a call for the comparison. */
1246 tmp
= build_call_expr (gfor_fndecl_compare_string
, 4,
1247 len1
, str1
, len2
, str2
);
1252 gfc_conv_function_val (gfc_se
* se
, gfc_symbol
* sym
)
1256 if (sym
->attr
.dummy
)
1258 tmp
= gfc_get_symbol_decl (sym
);
1259 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
1260 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) == FUNCTION_TYPE
);
1264 if (!sym
->backend_decl
)
1265 sym
->backend_decl
= gfc_get_extern_function_decl (sym
);
1267 tmp
= sym
->backend_decl
;
1268 if (sym
->attr
.cray_pointee
)
1269 tmp
= convert (build_pointer_type (TREE_TYPE (tmp
)),
1270 gfc_get_symbol_decl (sym
->cp_pointer
));
1271 if (!POINTER_TYPE_P (TREE_TYPE (tmp
)))
1273 gcc_assert (TREE_CODE (tmp
) == FUNCTION_DECL
);
1274 tmp
= build_fold_addr_expr (tmp
);
1281 /* Translate the call for an elemental subroutine call used in an operator
1282 assignment. This is a simplified version of gfc_conv_function_call. */
1285 gfc_conv_operator_assign (gfc_se
*lse
, gfc_se
*rse
, gfc_symbol
*sym
)
1292 /* Only elemental subroutines with two arguments. */
1293 gcc_assert (sym
->attr
.elemental
&& sym
->attr
.subroutine
);
1294 gcc_assert (sym
->formal
->next
->next
== NULL
);
1296 gfc_init_block (&block
);
1298 gfc_add_block_to_block (&block
, &lse
->pre
);
1299 gfc_add_block_to_block (&block
, &rse
->pre
);
1301 /* Build the argument list for the call, including hidden string lengths. */
1302 args
= gfc_chainon_list (NULL_TREE
, build_fold_addr_expr (lse
->expr
));
1303 args
= gfc_chainon_list (args
, build_fold_addr_expr (rse
->expr
));
1304 if (lse
->string_length
!= NULL_TREE
)
1305 args
= gfc_chainon_list (args
, lse
->string_length
);
1306 if (rse
->string_length
!= NULL_TREE
)
1307 args
= gfc_chainon_list (args
, rse
->string_length
);
1309 /* Build the function call. */
1310 gfc_init_se (&se
, NULL
);
1311 gfc_conv_function_val (&se
, sym
);
1312 tmp
= TREE_TYPE (TREE_TYPE (TREE_TYPE (se
.expr
)));
1313 tmp
= build_call_list (tmp
, se
.expr
, args
);
1314 gfc_add_expr_to_block (&block
, tmp
);
1316 gfc_add_block_to_block (&block
, &lse
->post
);
1317 gfc_add_block_to_block (&block
, &rse
->post
);
1319 return gfc_finish_block (&block
);
1323 /* Initialize MAPPING. */
1326 gfc_init_interface_mapping (gfc_interface_mapping
* mapping
)
1328 mapping
->syms
= NULL
;
1329 mapping
->charlens
= NULL
;
1333 /* Free all memory held by MAPPING (but not MAPPING itself). */
1336 gfc_free_interface_mapping (gfc_interface_mapping
* mapping
)
1338 gfc_interface_sym_mapping
*sym
;
1339 gfc_interface_sym_mapping
*nextsym
;
1341 gfc_charlen
*nextcl
;
1343 for (sym
= mapping
->syms
; sym
; sym
= nextsym
)
1345 nextsym
= sym
->next
;
1346 gfc_free_symbol (sym
->new->n
.sym
);
1347 gfc_free (sym
->new);
1350 for (cl
= mapping
->charlens
; cl
; cl
= nextcl
)
1353 gfc_free_expr (cl
->length
);
1359 /* Return a copy of gfc_charlen CL. Add the returned structure to
1360 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1362 static gfc_charlen
*
1363 gfc_get_interface_mapping_charlen (gfc_interface_mapping
* mapping
,
1368 new = gfc_get_charlen ();
1369 new->next
= mapping
->charlens
;
1370 new->length
= gfc_copy_expr (cl
->length
);
1372 mapping
->charlens
= new;
1377 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1378 array variable that can be used as the actual argument for dummy
1379 argument SYM. Add any initialization code to BLOCK. PACKED is as
1380 for gfc_get_nodesc_array_type and DATA points to the first element
1381 in the passed array. */
1384 gfc_get_interface_mapping_array (stmtblock_t
* block
, gfc_symbol
* sym
,
1385 gfc_packed packed
, tree data
)
1390 type
= gfc_typenode_for_spec (&sym
->ts
);
1391 type
= gfc_get_nodesc_array_type (type
, sym
->as
, packed
);
1393 var
= gfc_create_var (type
, "ifm");
1394 gfc_add_modify_expr (block
, var
, fold_convert (type
, data
));
1400 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1401 and offset of descriptorless array type TYPE given that it has the same
1402 size as DESC. Add any set-up code to BLOCK. */
1405 gfc_set_interface_mapping_bounds (stmtblock_t
* block
, tree type
, tree desc
)
1412 offset
= gfc_index_zero_node
;
1413 for (n
= 0; n
< GFC_TYPE_ARRAY_RANK (type
); n
++)
1415 dim
= gfc_rank_cst
[n
];
1416 GFC_TYPE_ARRAY_STRIDE (type
, n
) = gfc_conv_array_stride (desc
, n
);
1417 if (GFC_TYPE_ARRAY_LBOUND (type
, n
) == NULL_TREE
)
1419 GFC_TYPE_ARRAY_LBOUND (type
, n
)
1420 = gfc_conv_descriptor_lbound (desc
, dim
);
1421 GFC_TYPE_ARRAY_UBOUND (type
, n
)
1422 = gfc_conv_descriptor_ubound (desc
, dim
);
1424 else if (GFC_TYPE_ARRAY_UBOUND (type
, n
) == NULL_TREE
)
1426 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1427 gfc_conv_descriptor_ubound (desc
, dim
),
1428 gfc_conv_descriptor_lbound (desc
, dim
));
1429 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1430 GFC_TYPE_ARRAY_LBOUND (type
, n
),
1432 tmp
= gfc_evaluate_now (tmp
, block
);
1433 GFC_TYPE_ARRAY_UBOUND (type
, n
) = tmp
;
1435 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
1436 GFC_TYPE_ARRAY_LBOUND (type
, n
),
1437 GFC_TYPE_ARRAY_STRIDE (type
, n
));
1438 offset
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp
);
1440 offset
= gfc_evaluate_now (offset
, block
);
1441 GFC_TYPE_ARRAY_OFFSET (type
) = offset
;
1445 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1446 in SE. The caller may still use se->expr and se->string_length after
1447 calling this function. */
1450 gfc_add_interface_mapping (gfc_interface_mapping
* mapping
,
1451 gfc_symbol
* sym
, gfc_se
* se
)
1453 gfc_interface_sym_mapping
*sm
;
1457 gfc_symbol
*new_sym
;
1459 gfc_symtree
*new_symtree
;
1461 /* Create a new symbol to represent the actual argument. */
1462 new_sym
= gfc_new_symbol (sym
->name
, NULL
);
1463 new_sym
->ts
= sym
->ts
;
1464 new_sym
->attr
.referenced
= 1;
1465 new_sym
->attr
.dimension
= sym
->attr
.dimension
;
1466 new_sym
->attr
.pointer
= sym
->attr
.pointer
;
1467 new_sym
->attr
.allocatable
= sym
->attr
.allocatable
;
1468 new_sym
->attr
.flavor
= sym
->attr
.flavor
;
1470 /* Create a fake symtree for it. */
1472 new_symtree
= gfc_new_symtree (&root
, sym
->name
);
1473 new_symtree
->n
.sym
= new_sym
;
1474 gcc_assert (new_symtree
== root
);
1476 /* Create a dummy->actual mapping. */
1477 sm
= gfc_getmem (sizeof (*sm
));
1478 sm
->next
= mapping
->syms
;
1480 sm
->new = new_symtree
;
1483 /* Stabilize the argument's value. */
1484 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
1486 if (sym
->ts
.type
== BT_CHARACTER
)
1488 /* Create a copy of the dummy argument's length. */
1489 new_sym
->ts
.cl
= gfc_get_interface_mapping_charlen (mapping
, sym
->ts
.cl
);
1491 /* If the length is specified as "*", record the length that
1492 the caller is passing. We should use the callee's length
1493 in all other cases. */
1494 if (!new_sym
->ts
.cl
->length
)
1496 se
->string_length
= gfc_evaluate_now (se
->string_length
, &se
->pre
);
1497 new_sym
->ts
.cl
->backend_decl
= se
->string_length
;
1501 /* Use the passed value as-is if the argument is a function. */
1502 if (sym
->attr
.flavor
== FL_PROCEDURE
)
1505 /* If the argument is either a string or a pointer to a string,
1506 convert it to a boundless character type. */
1507 else if (!sym
->attr
.dimension
&& sym
->ts
.type
== BT_CHARACTER
)
1509 tmp
= gfc_get_character_type_len (sym
->ts
.kind
, NULL
);
1510 tmp
= build_pointer_type (tmp
);
1511 if (sym
->attr
.pointer
)
1512 value
= build_fold_indirect_ref (se
->expr
);
1515 value
= fold_convert (tmp
, value
);
1518 /* If the argument is a scalar, a pointer to an array or an allocatable,
1520 else if (!sym
->attr
.dimension
|| sym
->attr
.pointer
|| sym
->attr
.allocatable
)
1521 value
= build_fold_indirect_ref (se
->expr
);
1523 /* For character(*), use the actual argument's descriptor. */
1524 else if (sym
->ts
.type
== BT_CHARACTER
&& !new_sym
->ts
.cl
->length
)
1525 value
= build_fold_indirect_ref (se
->expr
);
1527 /* If the argument is an array descriptor, use it to determine
1528 information about the actual argument's shape. */
1529 else if (POINTER_TYPE_P (TREE_TYPE (se
->expr
))
1530 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se
->expr
))))
1532 /* Get the actual argument's descriptor. */
1533 desc
= build_fold_indirect_ref (se
->expr
);
1535 /* Create the replacement variable. */
1536 tmp
= gfc_conv_descriptor_data_get (desc
);
1537 value
= gfc_get_interface_mapping_array (&se
->pre
, sym
,
1540 /* Use DESC to work out the upper bounds, strides and offset. */
1541 gfc_set_interface_mapping_bounds (&se
->pre
, TREE_TYPE (value
), desc
);
1544 /* Otherwise we have a packed array. */
1545 value
= gfc_get_interface_mapping_array (&se
->pre
, sym
,
1546 PACKED_FULL
, se
->expr
);
1548 new_sym
->backend_decl
= value
;
1552 /* Called once all dummy argument mappings have been added to MAPPING,
1553 but before the mapping is used to evaluate expressions. Pre-evaluate
1554 the length of each argument, adding any initialization code to PRE and
1555 any finalization code to POST. */
1558 gfc_finish_interface_mapping (gfc_interface_mapping
* mapping
,
1559 stmtblock_t
* pre
, stmtblock_t
* post
)
1561 gfc_interface_sym_mapping
*sym
;
1565 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
1566 if (sym
->new->n
.sym
->ts
.type
== BT_CHARACTER
1567 && !sym
->new->n
.sym
->ts
.cl
->backend_decl
)
1569 expr
= sym
->new->n
.sym
->ts
.cl
->length
;
1570 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
1571 gfc_init_se (&se
, NULL
);
1572 gfc_conv_expr (&se
, expr
);
1574 se
.expr
= gfc_evaluate_now (se
.expr
, &se
.pre
);
1575 gfc_add_block_to_block (pre
, &se
.pre
);
1576 gfc_add_block_to_block (post
, &se
.post
);
1578 sym
->new->n
.sym
->ts
.cl
->backend_decl
= se
.expr
;
1583 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1587 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping
* mapping
,
1588 gfc_constructor
* c
)
1590 for (; c
; c
= c
->next
)
1592 gfc_apply_interface_mapping_to_expr (mapping
, c
->expr
);
1595 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->start
);
1596 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->end
);
1597 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->step
);
1603 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1607 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping
* mapping
,
1612 for (; ref
; ref
= ref
->next
)
1616 for (n
= 0; n
< ref
->u
.ar
.dimen
; n
++)
1618 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.start
[n
]);
1619 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.end
[n
]);
1620 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.stride
[n
]);
1622 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.offset
);
1629 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ss
.start
);
1630 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ss
.end
);
1636 /* EXPR is a copy of an expression that appeared in the interface
1637 associated with MAPPING. Walk it recursively looking for references to
1638 dummy arguments that MAPPING maps to actual arguments. Replace each such
1639 reference with a reference to the associated actual argument. */
1642 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping
* mapping
,
1645 gfc_interface_sym_mapping
*sym
;
1646 gfc_actual_arglist
*actual
;
1647 int seen_result
= 0;
1652 /* Copying an expression does not copy its length, so do that here. */
1653 if (expr
->ts
.type
== BT_CHARACTER
&& expr
->ts
.cl
)
1655 expr
->ts
.cl
= gfc_get_interface_mapping_charlen (mapping
, expr
->ts
.cl
);
1656 gfc_apply_interface_mapping_to_expr (mapping
, expr
->ts
.cl
->length
);
1659 /* Apply the mapping to any references. */
1660 gfc_apply_interface_mapping_to_ref (mapping
, expr
->ref
);
1662 /* ...and to the expression's symbol, if it has one. */
1664 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
1665 if (sym
->old
== expr
->symtree
->n
.sym
)
1666 expr
->symtree
= sym
->new;
1668 /* ...and to subexpressions in expr->value. */
1669 switch (expr
->expr_type
)
1672 if (expr
->symtree
->n
.sym
->attr
.result
)
1676 case EXPR_SUBSTRING
:
1680 gfc_apply_interface_mapping_to_expr (mapping
, expr
->value
.op
.op1
);
1681 gfc_apply_interface_mapping_to_expr (mapping
, expr
->value
.op
.op2
);
1685 if (expr
->value
.function
.esym
== NULL
1686 && expr
->value
.function
.isym
!= NULL
1687 && expr
->value
.function
.isym
->id
== GFC_ISYM_LEN
1688 && expr
->value
.function
.actual
->expr
->expr_type
== EXPR_VARIABLE
1689 && gfc_apply_interface_mapping_to_expr (mapping
,
1690 expr
->value
.function
.actual
->expr
))
1693 new_expr
= gfc_copy_expr (expr
->value
.function
.actual
->expr
->ts
.cl
->length
);
1695 gfc_free (new_expr
);
1696 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
1700 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
1701 if (sym
->old
== expr
->value
.function
.esym
)
1702 expr
->value
.function
.esym
= sym
->new->n
.sym
;
1704 for (actual
= expr
->value
.function
.actual
; actual
; actual
= actual
->next
)
1705 gfc_apply_interface_mapping_to_expr (mapping
, actual
->expr
);
1709 case EXPR_STRUCTURE
:
1710 gfc_apply_interface_mapping_to_cons (mapping
, expr
->value
.constructor
);
1717 /* Evaluate interface expression EXPR using MAPPING. Store the result
1721 gfc_apply_interface_mapping (gfc_interface_mapping
* mapping
,
1722 gfc_se
* se
, gfc_expr
* expr
)
1724 expr
= gfc_copy_expr (expr
);
1725 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
1726 gfc_conv_expr (se
, expr
);
1727 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
1728 gfc_free_expr (expr
);
1731 /* Returns a reference to a temporary array into which a component of
1732 an actual argument derived type array is copied and then returned
1733 after the function call.
1734 TODO Get rid of this kludge, when array descriptors are capable of
1735 handling arrays with a bigger stride in bytes than size. */
1738 gfc_conv_aliased_arg (gfc_se
* parmse
, gfc_expr
* expr
,
1739 int g77
, sym_intent intent
)
1755 gcc_assert (expr
->expr_type
== EXPR_VARIABLE
);
1757 gfc_init_se (&lse
, NULL
);
1758 gfc_init_se (&rse
, NULL
);
1760 /* Walk the argument expression. */
1761 rss
= gfc_walk_expr (expr
);
1763 gcc_assert (rss
!= gfc_ss_terminator
);
1765 /* Initialize the scalarizer. */
1766 gfc_init_loopinfo (&loop
);
1767 gfc_add_ss_to_loop (&loop
, rss
);
1769 /* Calculate the bounds of the scalarization. */
1770 gfc_conv_ss_startstride (&loop
);
1772 /* Build an ss for the temporary. */
1773 base_type
= gfc_typenode_for_spec (&expr
->ts
);
1774 if (GFC_ARRAY_TYPE_P (base_type
)
1775 || GFC_DESCRIPTOR_TYPE_P (base_type
))
1776 base_type
= gfc_get_element_type (base_type
);
1778 loop
.temp_ss
= gfc_get_ss ();;
1779 loop
.temp_ss
->type
= GFC_SS_TEMP
;
1780 loop
.temp_ss
->data
.temp
.type
= base_type
;
1782 if (expr
->ts
.type
== BT_CHARACTER
)
1784 gfc_ref
*char_ref
= expr
->ref
;
1786 for (; char_ref
; char_ref
= char_ref
->next
)
1787 if (char_ref
->type
== REF_SUBSTRING
)
1791 expr
->ts
.cl
= gfc_get_charlen ();
1792 expr
->ts
.cl
->next
= char_ref
->u
.ss
.length
->next
;
1793 char_ref
->u
.ss
.length
->next
= expr
->ts
.cl
;
1795 gfc_init_se (&tmp_se
, NULL
);
1796 gfc_conv_expr_type (&tmp_se
, char_ref
->u
.ss
.end
,
1797 gfc_array_index_type
);
1798 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1799 tmp_se
.expr
, gfc_index_one_node
);
1800 tmp
= gfc_evaluate_now (tmp
, &parmse
->pre
);
1801 gfc_init_se (&tmp_se
, NULL
);
1802 gfc_conv_expr_type (&tmp_se
, char_ref
->u
.ss
.start
,
1803 gfc_array_index_type
);
1804 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1806 expr
->ts
.cl
->backend_decl
= tmp
;
1810 loop
.temp_ss
->data
.temp
.type
1811 = gfc_typenode_for_spec (&expr
->ts
);
1812 loop
.temp_ss
->string_length
= expr
->ts
.cl
->backend_decl
;
1815 loop
.temp_ss
->data
.temp
.dimen
= loop
.dimen
;
1816 loop
.temp_ss
->next
= gfc_ss_terminator
;
1818 /* Associate the SS with the loop. */
1819 gfc_add_ss_to_loop (&loop
, loop
.temp_ss
);
1821 /* Setup the scalarizing loops. */
1822 gfc_conv_loop_setup (&loop
);
1824 /* Pass the temporary descriptor back to the caller. */
1825 info
= &loop
.temp_ss
->data
.info
;
1826 parmse
->expr
= info
->descriptor
;
1828 /* Setup the gfc_se structures. */
1829 gfc_copy_loopinfo_to_se (&lse
, &loop
);
1830 gfc_copy_loopinfo_to_se (&rse
, &loop
);
1833 lse
.ss
= loop
.temp_ss
;
1834 gfc_mark_ss_chain_used (rss
, 1);
1835 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
1837 /* Start the scalarized loop body. */
1838 gfc_start_scalarized_body (&loop
, &body
);
1840 /* Translate the expression. */
1841 gfc_conv_expr (&rse
, expr
);
1843 gfc_conv_tmp_array_ref (&lse
);
1844 gfc_advance_se_ss_chain (&lse
);
1846 if (intent
!= INTENT_OUT
)
1848 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, true, false);
1849 gfc_add_expr_to_block (&body
, tmp
);
1850 gcc_assert (rse
.ss
== gfc_ss_terminator
);
1851 gfc_trans_scalarizing_loops (&loop
, &body
);
1855 /* Make sure that the temporary declaration survives by merging
1856 all the loop declarations into the current context. */
1857 for (n
= 0; n
< loop
.dimen
; n
++)
1859 gfc_merge_block_scope (&body
);
1860 body
= loop
.code
[loop
.order
[n
]];
1862 gfc_merge_block_scope (&body
);
1865 /* Add the post block after the second loop, so that any
1866 freeing of allocated memory is done at the right time. */
1867 gfc_add_block_to_block (&parmse
->pre
, &loop
.pre
);
1869 /**********Copy the temporary back again.*********/
1871 gfc_init_se (&lse
, NULL
);
1872 gfc_init_se (&rse
, NULL
);
1874 /* Walk the argument expression. */
1875 lss
= gfc_walk_expr (expr
);
1876 rse
.ss
= loop
.temp_ss
;
1879 /* Initialize the scalarizer. */
1880 gfc_init_loopinfo (&loop2
);
1881 gfc_add_ss_to_loop (&loop2
, lss
);
1883 /* Calculate the bounds of the scalarization. */
1884 gfc_conv_ss_startstride (&loop2
);
1886 /* Setup the scalarizing loops. */
1887 gfc_conv_loop_setup (&loop2
);
1889 gfc_copy_loopinfo_to_se (&lse
, &loop2
);
1890 gfc_copy_loopinfo_to_se (&rse
, &loop2
);
1892 gfc_mark_ss_chain_used (lss
, 1);
1893 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
1895 /* Declare the variable to hold the temporary offset and start the
1896 scalarized loop body. */
1897 offset
= gfc_create_var (gfc_array_index_type
, NULL
);
1898 gfc_start_scalarized_body (&loop2
, &body
);
1900 /* Build the offsets for the temporary from the loop variables. The
1901 temporary array has lbounds of zero and strides of one in all
1902 dimensions, so this is very simple. The offset is only computed
1903 outside the innermost loop, so the overall transfer could be
1904 optimized further. */
1905 info
= &rse
.ss
->data
.info
;
1907 tmp_index
= gfc_index_zero_node
;
1908 for (n
= info
->dimen
- 1; n
> 0; n
--)
1911 tmp
= rse
.loop
->loopvar
[n
];
1912 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1913 tmp
, rse
.loop
->from
[n
]);
1914 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1917 tmp_str
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1918 rse
.loop
->to
[n
-1], rse
.loop
->from
[n
-1]);
1919 tmp_str
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1920 tmp_str
, gfc_index_one_node
);
1922 tmp_index
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
1926 tmp_index
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1927 tmp_index
, rse
.loop
->from
[0]);
1928 gfc_add_modify_expr (&rse
.loop
->code
[0], offset
, tmp_index
);
1930 tmp_index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1931 rse
.loop
->loopvar
[0], offset
);
1933 /* Now use the offset for the reference. */
1934 tmp
= build_fold_indirect_ref (info
->data
);
1935 rse
.expr
= gfc_build_array_ref (tmp
, tmp_index
);
1937 if (expr
->ts
.type
== BT_CHARACTER
)
1938 rse
.string_length
= expr
->ts
.cl
->backend_decl
;
1940 gfc_conv_expr (&lse
, expr
);
1942 gcc_assert (lse
.ss
== gfc_ss_terminator
);
1944 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, false, false);
1945 gfc_add_expr_to_block (&body
, tmp
);
1947 /* Generate the copying loops. */
1948 gfc_trans_scalarizing_loops (&loop2
, &body
);
1950 /* Wrap the whole thing up by adding the second loop to the post-block
1951 and following it by the post-block of the first loop. In this way,
1952 if the temporary needs freeing, it is done after use! */
1953 if (intent
!= INTENT_IN
)
1955 gfc_add_block_to_block (&parmse
->post
, &loop2
.pre
);
1956 gfc_add_block_to_block (&parmse
->post
, &loop2
.post
);
1959 gfc_add_block_to_block (&parmse
->post
, &loop
.post
);
1961 gfc_cleanup_loop (&loop
);
1962 gfc_cleanup_loop (&loop2
);
1964 /* Pass the string length to the argument expression. */
1965 if (expr
->ts
.type
== BT_CHARACTER
)
1966 parmse
->string_length
= expr
->ts
.cl
->backend_decl
;
1968 /* We want either the address for the data or the address of the descriptor,
1969 depending on the mode of passing array arguments. */
1971 parmse
->expr
= gfc_conv_descriptor_data_get (parmse
->expr
);
1973 parmse
->expr
= build_fold_addr_expr (parmse
->expr
);
1978 /* Is true if an array reference is followed by a component or substring
1982 is_aliased_array (gfc_expr
* e
)
1988 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
1990 if (ref
->type
== REF_ARRAY
1991 && ref
->u
.ar
.type
!= AR_ELEMENT
)
1995 && ref
->type
!= REF_ARRAY
)
2001 /* Generate the code for argument list functions. */
2004 conv_arglist_function (gfc_se
*se
, gfc_expr
*expr
, const char *name
)
2006 /* Pass by value for g77 %VAL(arg), pass the address
2007 indirectly for %LOC, else by reference. Thus %REF
2008 is a "do-nothing" and %LOC is the same as an F95
2010 if (strncmp (name
, "%VAL", 4) == 0)
2011 gfc_conv_expr (se
, expr
);
2012 else if (strncmp (name
, "%LOC", 4) == 0)
2014 gfc_conv_expr_reference (se
, expr
);
2015 se
->expr
= gfc_build_addr_expr (NULL
, se
->expr
);
2017 else if (strncmp (name
, "%REF", 4) == 0)
2018 gfc_conv_expr_reference (se
, expr
);
2020 gfc_error ("Unknown argument list function at %L", &expr
->where
);
2024 /* Generate code for a procedure call. Note can return se->post != NULL.
2025 If se->direct_byref is set then se->expr contains the return parameter.
2026 Return nonzero, if the call has alternate specifiers. */
2029 gfc_conv_function_call (gfc_se
* se
, gfc_symbol
* sym
,
2030 gfc_actual_arglist
* arg
, tree append_args
)
2032 gfc_interface_mapping mapping
;
2046 gfc_formal_arglist
*formal
;
2047 int has_alternate_specifier
= 0;
2048 bool need_interface_mapping
;
2055 enum {MISSING
= 0, ELEMENTAL
, SCALAR
, SCALAR_POINTER
, ARRAY
};
2057 arglist
= NULL_TREE
;
2058 retargs
= NULL_TREE
;
2059 stringargs
= NULL_TREE
;
2065 if (!sym
->attr
.elemental
)
2067 gcc_assert (se
->ss
->type
== GFC_SS_FUNCTION
);
2068 if (se
->ss
->useflags
)
2070 gcc_assert (gfc_return_by_reference (sym
)
2071 && sym
->result
->attr
.dimension
);
2072 gcc_assert (se
->loop
!= NULL
);
2074 /* Access the previously obtained result. */
2075 gfc_conv_tmp_array_ref (se
);
2076 gfc_advance_se_ss_chain (se
);
2080 info
= &se
->ss
->data
.info
;
2085 gfc_init_block (&post
);
2086 gfc_init_interface_mapping (&mapping
);
2087 need_interface_mapping
= ((sym
->ts
.type
== BT_CHARACTER
2088 && sym
->ts
.cl
->length
2089 && sym
->ts
.cl
->length
->expr_type
2091 || sym
->attr
.dimension
);
2092 formal
= sym
->formal
;
2093 /* Evaluate the arguments. */
2094 for (; arg
!= NULL
; arg
= arg
->next
, formal
= formal
? formal
->next
: NULL
)
2097 fsym
= formal
? formal
->sym
: NULL
;
2098 parm_kind
= MISSING
;
2102 if (se
->ignore_optional
)
2104 /* Some intrinsics have already been resolved to the correct
2108 else if (arg
->label
)
2110 has_alternate_specifier
= 1;
2115 /* Pass a NULL pointer for an absent arg. */
2116 gfc_init_se (&parmse
, NULL
);
2117 parmse
.expr
= null_pointer_node
;
2118 if (arg
->missing_arg_type
== BT_CHARACTER
)
2119 parmse
.string_length
= build_int_cst (gfc_charlen_type_node
, 0);
2122 else if (se
->ss
&& se
->ss
->useflags
)
2124 /* An elemental function inside a scalarized loop. */
2125 gfc_init_se (&parmse
, se
);
2126 gfc_conv_expr_reference (&parmse
, e
);
2127 parm_kind
= ELEMENTAL
;
2131 /* A scalar or transformational function. */
2132 gfc_init_se (&parmse
, NULL
);
2133 argss
= gfc_walk_expr (e
);
2135 if (argss
== gfc_ss_terminator
)
2137 if (fsym
&& fsym
->attr
.value
)
2139 gfc_conv_expr (&parmse
, e
);
2141 else if (arg
->name
&& arg
->name
[0] == '%')
2142 /* Argument list functions %VAL, %LOC and %REF are signalled
2143 through arg->name. */
2144 conv_arglist_function (&parmse
, arg
->expr
, arg
->name
);
2145 else if ((e
->expr_type
== EXPR_FUNCTION
)
2146 && e
->symtree
->n
.sym
->attr
.pointer
2147 && fsym
&& fsym
->attr
.target
)
2149 gfc_conv_expr (&parmse
, e
);
2150 parmse
.expr
= build_fold_addr_expr (parmse
.expr
);
2154 gfc_conv_expr_reference (&parmse
, e
);
2155 if (fsym
&& fsym
->attr
.pointer
2156 && fsym
->attr
.flavor
!= FL_PROCEDURE
2157 && e
->expr_type
!= EXPR_NULL
)
2159 /* Scalar pointer dummy args require an extra level of
2160 indirection. The null pointer already contains
2161 this level of indirection. */
2162 parm_kind
= SCALAR_POINTER
;
2163 parmse
.expr
= build_fold_addr_expr (parmse
.expr
);
2169 /* If the procedure requires an explicit interface, the actual
2170 argument is passed according to the corresponding formal
2171 argument. If the corresponding formal argument is a POINTER,
2172 ALLOCATABLE or assumed shape, we do not use g77's calling
2173 convention, and pass the address of the array descriptor
2174 instead. Otherwise we use g77's calling convention. */
2177 && !(fsym
->attr
.pointer
|| fsym
->attr
.allocatable
)
2178 && fsym
->as
->type
!= AS_ASSUMED_SHAPE
;
2179 f
= f
|| !sym
->attr
.always_explicit
;
2181 if (e
->expr_type
== EXPR_VARIABLE
2182 && is_aliased_array (e
))
2183 /* The actual argument is a component reference to an
2184 array of derived types. In this case, the argument
2185 is converted to a temporary, which is passed and then
2186 written back after the procedure call. */
2187 gfc_conv_aliased_arg (&parmse
, e
, f
,
2188 fsym
? fsym
->attr
.intent
: INTENT_INOUT
);
2190 gfc_conv_array_parameter (&parmse
, e
, argss
, f
);
2192 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2193 allocated on entry, it must be deallocated. */
2194 if (fsym
&& fsym
->attr
.allocatable
2195 && fsym
->attr
.intent
== INTENT_OUT
)
2197 tmp
= build_fold_indirect_ref (parmse
.expr
);
2198 tmp
= gfc_trans_dealloc_allocated (tmp
);
2199 gfc_add_expr_to_block (&se
->pre
, tmp
);
2209 /* If an optional argument is itself an optional dummy
2210 argument, check its presence and substitute a null
2212 if (e
->expr_type
== EXPR_VARIABLE
2213 && e
->symtree
->n
.sym
->attr
.optional
2214 && fsym
->attr
.optional
)
2215 gfc_conv_missing_dummy (&parmse
, e
, fsym
->ts
);
2217 /* If an INTENT(OUT) dummy of derived type has a default
2218 initializer, it must be (re)initialized here. */
2219 if (fsym
->attr
.intent
== INTENT_OUT
2220 && fsym
->ts
.type
== BT_DERIVED
2223 gcc_assert (!fsym
->attr
.allocatable
);
2224 tmp
= gfc_trans_assignment (e
, fsym
->value
, false);
2225 gfc_add_expr_to_block (&se
->pre
, tmp
);
2228 /* Obtain the character length of an assumed character
2229 length procedure from the typespec. */
2230 if (fsym
->ts
.type
== BT_CHARACTER
2231 && parmse
.string_length
== NULL_TREE
2232 && e
->ts
.type
== BT_PROCEDURE
2233 && e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
2234 && e
->symtree
->n
.sym
->ts
.cl
->length
!= NULL
)
2236 gfc_conv_const_charlen (e
->symtree
->n
.sym
->ts
.cl
);
2237 parmse
.string_length
2238 = e
->symtree
->n
.sym
->ts
.cl
->backend_decl
;
2242 if (need_interface_mapping
)
2243 gfc_add_interface_mapping (&mapping
, fsym
, &parmse
);
2246 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
2247 gfc_add_block_to_block (&post
, &parmse
.post
);
2249 /* Allocated allocatable components of derived types must be
2250 deallocated for INTENT(OUT) dummy arguments and non-variable
2251 scalars. Non-variable arrays are dealt with in trans-array.c
2252 (gfc_conv_array_parameter). */
2253 if (e
&& e
->ts
.type
== BT_DERIVED
2254 && e
->ts
.derived
->attr
.alloc_comp
2255 && ((formal
&& formal
->sym
->attr
.intent
== INTENT_OUT
)
2257 (e
->expr_type
!= EXPR_VARIABLE
&& !e
->rank
)))
2260 tmp
= build_fold_indirect_ref (parmse
.expr
);
2261 parm_rank
= e
->rank
;
2269 case (SCALAR_POINTER
):
2270 tmp
= build_fold_indirect_ref (tmp
);
2277 tmp
= gfc_deallocate_alloc_comp (e
->ts
.derived
, tmp
, parm_rank
);
2278 if (e
->expr_type
== EXPR_VARIABLE
&& e
->symtree
->n
.sym
->attr
.optional
)
2279 tmp
= build3_v (COND_EXPR
, gfc_conv_expr_present (e
->symtree
->n
.sym
),
2280 tmp
, build_empty_stmt ());
2282 if (e
->expr_type
!= EXPR_VARIABLE
)
2283 /* Don't deallocate non-variables until they have been used. */
2284 gfc_add_expr_to_block (&se
->post
, tmp
);
2287 gcc_assert (formal
&& formal
->sym
->attr
.intent
== INTENT_OUT
);
2288 gfc_add_expr_to_block (&se
->pre
, tmp
);
2292 /* Character strings are passed as two parameters, a length and a
2294 if (parmse
.string_length
!= NULL_TREE
)
2295 stringargs
= gfc_chainon_list (stringargs
, parmse
.string_length
);
2297 arglist
= gfc_chainon_list (arglist
, parmse
.expr
);
2299 gfc_finish_interface_mapping (&mapping
, &se
->pre
, &se
->post
);
2302 if (ts
.type
== BT_CHARACTER
)
2304 if (sym
->ts
.cl
->length
== NULL
)
2306 /* Assumed character length results are not allowed by 5.1.1.5 of the
2307 standard and are trapped in resolve.c; except in the case of SPREAD
2308 (and other intrinsics?) and dummy functions. In the case of SPREAD,
2309 we take the character length of the first argument for the result.
2310 For dummies, we have to look through the formal argument list for
2311 this function and use the character length found there.*/
2312 if (!sym
->attr
.dummy
)
2313 cl
.backend_decl
= TREE_VALUE (stringargs
);
2316 formal
= sym
->ns
->proc_name
->formal
;
2317 for (; formal
; formal
= formal
->next
)
2318 if (strcmp (formal
->sym
->name
, sym
->name
) == 0)
2319 cl
.backend_decl
= formal
->sym
->ts
.cl
->backend_decl
;
2326 /* Calculate the length of the returned string. */
2327 gfc_init_se (&parmse
, NULL
);
2328 if (need_interface_mapping
)
2329 gfc_apply_interface_mapping (&mapping
, &parmse
, sym
->ts
.cl
->length
);
2331 gfc_conv_expr (&parmse
, sym
->ts
.cl
->length
);
2332 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
2333 gfc_add_block_to_block (&se
->post
, &parmse
.post
);
2335 tmp
= fold_convert (gfc_charlen_type_node
, parmse
.expr
);
2336 tmp
= fold_build2 (MAX_EXPR
, gfc_charlen_type_node
, tmp
,
2337 build_int_cst (gfc_charlen_type_node
, 0));
2338 cl
.backend_decl
= tmp
;
2341 /* Set up a charlen structure for it. */
2346 len
= cl
.backend_decl
;
2349 byref
= gfc_return_by_reference (sym
);
2352 if (se
->direct_byref
)
2354 /* Sometimes, too much indirection can be applied; eg. for
2355 function_result = array_valued_recursive_function. */
2356 if (TREE_TYPE (TREE_TYPE (se
->expr
))
2357 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
)))
2358 && GFC_DESCRIPTOR_TYPE_P
2359 (TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
)))))
2360 se
->expr
= build_fold_indirect_ref (se
->expr
);
2362 retargs
= gfc_chainon_list (retargs
, se
->expr
);
2364 else if (sym
->result
->attr
.dimension
)
2366 gcc_assert (se
->loop
&& info
);
2368 /* Set the type of the array. */
2369 tmp
= gfc_typenode_for_spec (&ts
);
2370 info
->dimen
= se
->loop
->dimen
;
2372 /* Evaluate the bounds of the result, if known. */
2373 gfc_set_loop_bounds_from_array_spec (&mapping
, se
, sym
->result
->as
);
2375 /* Create a temporary to store the result. In case the function
2376 returns a pointer, the temporary will be a shallow copy and
2377 mustn't be deallocated. */
2378 callee_alloc
= sym
->attr
.allocatable
|| sym
->attr
.pointer
;
2379 gfc_trans_create_temp_array (&se
->pre
, &se
->post
, se
->loop
, info
, tmp
,
2380 false, !sym
->attr
.pointer
, callee_alloc
);
2382 /* Pass the temporary as the first argument. */
2383 tmp
= info
->descriptor
;
2384 tmp
= build_fold_addr_expr (tmp
);
2385 retargs
= gfc_chainon_list (retargs
, tmp
);
2387 else if (ts
.type
== BT_CHARACTER
)
2389 /* Pass the string length. */
2390 type
= gfc_get_character_type (ts
.kind
, ts
.cl
);
2391 type
= build_pointer_type (type
);
2393 /* Return an address to a char[0:len-1]* temporary for
2394 character pointers. */
2395 if (sym
->attr
.pointer
|| sym
->attr
.allocatable
)
2397 /* Build char[0:len-1] * pstr. */
2398 tmp
= fold_build2 (MINUS_EXPR
, gfc_charlen_type_node
, len
,
2399 build_int_cst (gfc_charlen_type_node
, 1));
2400 tmp
= build_range_type (gfc_array_index_type
,
2401 gfc_index_zero_node
, tmp
);
2402 tmp
= build_array_type (gfc_character1_type_node
, tmp
);
2403 var
= gfc_create_var (build_pointer_type (tmp
), "pstr");
2405 /* Provide an address expression for the function arguments. */
2406 var
= build_fold_addr_expr (var
);
2409 var
= gfc_conv_string_tmp (se
, type
, len
);
2411 retargs
= gfc_chainon_list (retargs
, var
);
2415 gcc_assert (gfc_option
.flag_f2c
&& ts
.type
== BT_COMPLEX
);
2417 type
= gfc_get_complex_type (ts
.kind
);
2418 var
= build_fold_addr_expr (gfc_create_var (type
, "cmplx"));
2419 retargs
= gfc_chainon_list (retargs
, var
);
2422 /* Add the string length to the argument list. */
2423 if (ts
.type
== BT_CHARACTER
)
2424 retargs
= gfc_chainon_list (retargs
, len
);
2426 gfc_free_interface_mapping (&mapping
);
2428 /* Add the return arguments. */
2429 arglist
= chainon (retargs
, arglist
);
2431 /* Add the hidden string length parameters to the arguments. */
2432 arglist
= chainon (arglist
, stringargs
);
2434 /* We may want to append extra arguments here. This is used e.g. for
2435 calls to libgfortran_matmul_??, which need extra information. */
2436 if (append_args
!= NULL_TREE
)
2437 arglist
= chainon (arglist
, append_args
);
2439 /* Generate the actual call. */
2440 gfc_conv_function_val (se
, sym
);
2442 /* If there are alternate return labels, function type should be
2443 integer. Can't modify the type in place though, since it can be shared
2444 with other functions. For dummy arguments, the typing is done to
2445 to this result, even if it has to be repeated for each call. */
2446 if (has_alternate_specifier
2447 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
))) != integer_type_node
)
2449 if (!sym
->attr
.dummy
)
2451 TREE_TYPE (sym
->backend_decl
)
2452 = build_function_type (integer_type_node
,
2453 TYPE_ARG_TYPES (TREE_TYPE (sym
->backend_decl
)));
2454 se
->expr
= build_fold_addr_expr (sym
->backend_decl
);
2457 TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
))) = integer_type_node
;
2460 fntype
= TREE_TYPE (TREE_TYPE (se
->expr
));
2461 se
->expr
= build_call_list (TREE_TYPE (fntype
), se
->expr
, arglist
);
2463 /* If we have a pointer function, but we don't want a pointer, e.g.
2466 where f is pointer valued, we have to dereference the result. */
2467 if (!se
->want_pointer
&& !byref
&& sym
->attr
.pointer
)
2468 se
->expr
= build_fold_indirect_ref (se
->expr
);
2470 /* f2c calling conventions require a scalar default real function to
2471 return a double precision result. Convert this back to default
2472 real. We only care about the cases that can happen in Fortran 77.
2474 if (gfc_option
.flag_f2c
&& sym
->ts
.type
== BT_REAL
2475 && sym
->ts
.kind
== gfc_default_real_kind
2476 && !sym
->attr
.always_explicit
)
2477 se
->expr
= fold_convert (gfc_get_real_type (sym
->ts
.kind
), se
->expr
);
2479 /* A pure function may still have side-effects - it may modify its
2481 TREE_SIDE_EFFECTS (se
->expr
) = 1;
2483 if (!sym
->attr
.pure
)
2484 TREE_SIDE_EFFECTS (se
->expr
) = 1;
2489 /* Add the function call to the pre chain. There is no expression. */
2490 gfc_add_expr_to_block (&se
->pre
, se
->expr
);
2491 se
->expr
= NULL_TREE
;
2493 if (!se
->direct_byref
)
2495 if (sym
->attr
.dimension
)
2497 if (flag_bounds_check
)
2499 /* Check the data pointer hasn't been modified. This would
2500 happen in a function returning a pointer. */
2501 tmp
= gfc_conv_descriptor_data_get (info
->descriptor
);
2502 tmp
= fold_build2 (NE_EXPR
, boolean_type_node
,
2504 gfc_trans_runtime_check (tmp
, gfc_msg_fault
, &se
->pre
, NULL
);
2506 se
->expr
= info
->descriptor
;
2507 /* Bundle in the string length. */
2508 se
->string_length
= len
;
2510 else if (sym
->ts
.type
== BT_CHARACTER
)
2512 /* Dereference for character pointer results. */
2513 if (sym
->attr
.pointer
|| sym
->attr
.allocatable
)
2514 se
->expr
= build_fold_indirect_ref (var
);
2518 se
->string_length
= len
;
2522 gcc_assert (sym
->ts
.type
== BT_COMPLEX
&& gfc_option
.flag_f2c
);
2523 se
->expr
= build_fold_indirect_ref (var
);
2528 /* Follow the function call with the argument post block. */
2530 gfc_add_block_to_block (&se
->pre
, &post
);
2532 gfc_add_block_to_block (&se
->post
, &post
);
2534 return has_alternate_specifier
;
2538 /* Generate code to copy a string. */
2541 gfc_trans_string_copy (stmtblock_t
* block
, tree dlength
, tree dest
,
2542 tree slength
, tree src
)
2544 tree tmp
, dlen
, slen
;
2552 stmtblock_t tempblock
;
2554 dlen
= fold_convert (size_type_node
, gfc_evaluate_now (dlength
, block
));
2555 slen
= fold_convert (size_type_node
, gfc_evaluate_now (slength
, block
));
2557 /* Deal with single character specially. */
2558 dsc
= gfc_to_single_character (dlen
, dest
);
2559 ssc
= gfc_to_single_character (slen
, src
);
2560 if (dsc
!= NULL_TREE
&& ssc
!= NULL_TREE
)
2562 gfc_add_modify_expr (block
, dsc
, ssc
);
2566 /* Do nothing if the destination length is zero. */
2567 cond
= fold_build2 (GT_EXPR
, boolean_type_node
, dlen
,
2568 build_int_cst (size_type_node
, 0));
2570 /* The following code was previously in _gfortran_copy_string:
2572 // The two strings may overlap so we use memmove.
2574 copy_string (GFC_INTEGER_4 destlen, char * dest,
2575 GFC_INTEGER_4 srclen, const char * src)
2577 if (srclen >= destlen)
2579 // This will truncate if too long.
2580 memmove (dest, src, destlen);
2584 memmove (dest, src, srclen);
2586 memset (&dest[srclen], ' ', destlen - srclen);
2590 We're now doing it here for better optimization, but the logic
2593 /* Truncate string if source is too long. */
2594 cond2
= fold_build2 (GE_EXPR
, boolean_type_node
, slen
, dlen
);
2595 tmp2
= build_call_expr (built_in_decls
[BUILT_IN_MEMMOVE
],
2596 3, dest
, src
, dlen
);
2598 /* Else copy and pad with spaces. */
2599 tmp3
= build_call_expr (built_in_decls
[BUILT_IN_MEMMOVE
],
2600 3, dest
, src
, slen
);
2602 tmp4
= fold_build2 (POINTER_PLUS_EXPR
, pchar_type_node
, dest
,
2603 fold_convert (sizetype
, slen
));
2604 tmp4
= build_call_expr (built_in_decls
[BUILT_IN_MEMSET
], 3,
2606 build_int_cst (gfc_get_int_type (gfc_c_int_kind
),
2607 lang_hooks
.to_target_charset (' ')),
2608 fold_build2 (MINUS_EXPR
, TREE_TYPE(dlen
),
2611 gfc_init_block (&tempblock
);
2612 gfc_add_expr_to_block (&tempblock
, tmp3
);
2613 gfc_add_expr_to_block (&tempblock
, tmp4
);
2614 tmp3
= gfc_finish_block (&tempblock
);
2616 /* The whole copy_string function is there. */
2617 tmp
= fold_build3 (COND_EXPR
, void_type_node
, cond2
, tmp2
, tmp3
);
2618 tmp
= fold_build3 (COND_EXPR
, void_type_node
, cond
, tmp
, build_empty_stmt ());
2619 gfc_add_expr_to_block (block
, tmp
);
2623 /* Translate a statement function.
2624 The value of a statement function reference is obtained by evaluating the
2625 expression using the values of the actual arguments for the values of the
2626 corresponding dummy arguments. */
2629 gfc_conv_statement_function (gfc_se
* se
, gfc_expr
* expr
)
2633 gfc_formal_arglist
*fargs
;
2634 gfc_actual_arglist
*args
;
2637 gfc_saved_var
*saved_vars
;
2643 sym
= expr
->symtree
->n
.sym
;
2644 args
= expr
->value
.function
.actual
;
2645 gfc_init_se (&lse
, NULL
);
2646 gfc_init_se (&rse
, NULL
);
2649 for (fargs
= sym
->formal
; fargs
; fargs
= fargs
->next
)
2651 saved_vars
= (gfc_saved_var
*)gfc_getmem (n
* sizeof (gfc_saved_var
));
2652 temp_vars
= (tree
*)gfc_getmem (n
* sizeof (tree
));
2654 for (fargs
= sym
->formal
, n
= 0; fargs
; fargs
= fargs
->next
, n
++)
2656 /* Each dummy shall be specified, explicitly or implicitly, to be
2658 gcc_assert (fargs
->sym
->attr
.dimension
== 0);
2661 /* Create a temporary to hold the value. */
2662 type
= gfc_typenode_for_spec (&fsym
->ts
);
2663 temp_vars
[n
] = gfc_create_var (type
, fsym
->name
);
2665 if (fsym
->ts
.type
== BT_CHARACTER
)
2667 /* Copy string arguments. */
2670 gcc_assert (fsym
->ts
.cl
&& fsym
->ts
.cl
->length
2671 && fsym
->ts
.cl
->length
->expr_type
== EXPR_CONSTANT
);
2673 arglen
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
2674 tmp
= gfc_build_addr_expr (build_pointer_type (type
),
2677 gfc_conv_expr (&rse
, args
->expr
);
2678 gfc_conv_string_parameter (&rse
);
2679 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
2680 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
2682 gfc_trans_string_copy (&se
->pre
, arglen
, tmp
, rse
.string_length
,
2684 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
2685 gfc_add_block_to_block (&se
->pre
, &rse
.post
);
2689 /* For everything else, just evaluate the expression. */
2690 gfc_conv_expr (&lse
, args
->expr
);
2692 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
2693 gfc_add_modify_expr (&se
->pre
, temp_vars
[n
], lse
.expr
);
2694 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
2700 /* Use the temporary variables in place of the real ones. */
2701 for (fargs
= sym
->formal
, n
= 0; fargs
; fargs
= fargs
->next
, n
++)
2702 gfc_shadow_sym (fargs
->sym
, temp_vars
[n
], &saved_vars
[n
]);
2704 gfc_conv_expr (se
, sym
->value
);
2706 if (sym
->ts
.type
== BT_CHARACTER
)
2708 gfc_conv_const_charlen (sym
->ts
.cl
);
2710 /* Force the expression to the correct length. */
2711 if (!INTEGER_CST_P (se
->string_length
)
2712 || tree_int_cst_lt (se
->string_length
,
2713 sym
->ts
.cl
->backend_decl
))
2715 type
= gfc_get_character_type (sym
->ts
.kind
, sym
->ts
.cl
);
2716 tmp
= gfc_create_var (type
, sym
->name
);
2717 tmp
= gfc_build_addr_expr (build_pointer_type (type
), tmp
);
2718 gfc_trans_string_copy (&se
->pre
, sym
->ts
.cl
->backend_decl
, tmp
,
2719 se
->string_length
, se
->expr
);
2722 se
->string_length
= sym
->ts
.cl
->backend_decl
;
2725 /* Restore the original variables. */
2726 for (fargs
= sym
->formal
, n
= 0; fargs
; fargs
= fargs
->next
, n
++)
2727 gfc_restore_sym (fargs
->sym
, &saved_vars
[n
]);
2728 gfc_free (saved_vars
);
2732 /* Translate a function expression. */
2735 gfc_conv_function_expr (gfc_se
* se
, gfc_expr
* expr
)
2739 if (expr
->value
.function
.isym
)
2741 gfc_conv_intrinsic_function (se
, expr
);
2745 /* We distinguish statement functions from general functions to improve
2746 runtime performance. */
2747 if (expr
->symtree
->n
.sym
->attr
.proc
== PROC_ST_FUNCTION
)
2749 gfc_conv_statement_function (se
, expr
);
2753 /* expr.value.function.esym is the resolved (specific) function symbol for
2754 most functions. However this isn't set for dummy procedures. */
2755 sym
= expr
->value
.function
.esym
;
2757 sym
= expr
->symtree
->n
.sym
;
2758 gfc_conv_function_call (se
, sym
, expr
->value
.function
.actual
, NULL_TREE
);
2763 gfc_conv_array_constructor_expr (gfc_se
* se
, gfc_expr
* expr
)
2765 gcc_assert (se
->ss
!= NULL
&& se
->ss
!= gfc_ss_terminator
);
2766 gcc_assert (se
->ss
->expr
== expr
&& se
->ss
->type
== GFC_SS_CONSTRUCTOR
);
2768 gfc_conv_tmp_array_ref (se
);
2769 gfc_advance_se_ss_chain (se
);
2773 /* Build a static initializer. EXPR is the expression for the initial value.
2774 The other parameters describe the variable of the component being
2775 initialized. EXPR may be null. */
2778 gfc_conv_initializer (gfc_expr
* expr
, gfc_typespec
* ts
, tree type
,
2779 bool array
, bool pointer
)
2783 if (!(expr
|| pointer
))
2786 if (expr
!= NULL
&& expr
->ts
.type
== BT_DERIVED
2787 && expr
->ts
.is_iso_c
&& expr
->ts
.derived
2788 && (expr
->symtree
->n
.sym
->intmod_sym_id
== ISOCBINDING_NULL_PTR
2789 || expr
->symtree
->n
.sym
->intmod_sym_id
== ISOCBINDING_NULL_FUNPTR
))
2790 expr
= gfc_int_expr (0);
2794 /* Arrays need special handling. */
2796 return gfc_build_null_descriptor (type
);
2798 return gfc_conv_array_initializer (type
, expr
);
2801 return fold_convert (type
, null_pointer_node
);
2807 gfc_init_se (&se
, NULL
);
2808 gfc_conv_structure (&se
, expr
, 1);
2812 return gfc_conv_string_init (ts
->cl
->backend_decl
,expr
);
2815 gfc_init_se (&se
, NULL
);
2816 gfc_conv_constant (&se
, expr
);
2823 gfc_trans_subarray_assign (tree dest
, gfc_component
* cm
, gfc_expr
* expr
)
2835 gfc_start_block (&block
);
2837 /* Initialize the scalarizer. */
2838 gfc_init_loopinfo (&loop
);
2840 gfc_init_se (&lse
, NULL
);
2841 gfc_init_se (&rse
, NULL
);
2844 rss
= gfc_walk_expr (expr
);
2845 if (rss
== gfc_ss_terminator
)
2847 /* The rhs is scalar. Add a ss for the expression. */
2848 rss
= gfc_get_ss ();
2849 rss
->next
= gfc_ss_terminator
;
2850 rss
->type
= GFC_SS_SCALAR
;
2854 /* Create a SS for the destination. */
2855 lss
= gfc_get_ss ();
2856 lss
->type
= GFC_SS_COMPONENT
;
2858 lss
->shape
= gfc_get_shape (cm
->as
->rank
);
2859 lss
->next
= gfc_ss_terminator
;
2860 lss
->data
.info
.dimen
= cm
->as
->rank
;
2861 lss
->data
.info
.descriptor
= dest
;
2862 lss
->data
.info
.data
= gfc_conv_array_data (dest
);
2863 lss
->data
.info
.offset
= gfc_conv_array_offset (dest
);
2864 for (n
= 0; n
< cm
->as
->rank
; n
++)
2866 lss
->data
.info
.dim
[n
] = n
;
2867 lss
->data
.info
.start
[n
] = gfc_conv_array_lbound (dest
, n
);
2868 lss
->data
.info
.stride
[n
] = gfc_index_one_node
;
2870 mpz_init (lss
->shape
[n
]);
2871 mpz_sub (lss
->shape
[n
], cm
->as
->upper
[n
]->value
.integer
,
2872 cm
->as
->lower
[n
]->value
.integer
);
2873 mpz_add_ui (lss
->shape
[n
], lss
->shape
[n
], 1);
2876 /* Associate the SS with the loop. */
2877 gfc_add_ss_to_loop (&loop
, lss
);
2878 gfc_add_ss_to_loop (&loop
, rss
);
2880 /* Calculate the bounds of the scalarization. */
2881 gfc_conv_ss_startstride (&loop
);
2883 /* Setup the scalarizing loops. */
2884 gfc_conv_loop_setup (&loop
);
2886 /* Setup the gfc_se structures. */
2887 gfc_copy_loopinfo_to_se (&lse
, &loop
);
2888 gfc_copy_loopinfo_to_se (&rse
, &loop
);
2891 gfc_mark_ss_chain_used (rss
, 1);
2893 gfc_mark_ss_chain_used (lss
, 1);
2895 /* Start the scalarized loop body. */
2896 gfc_start_scalarized_body (&loop
, &body
);
2898 gfc_conv_tmp_array_ref (&lse
);
2899 if (cm
->ts
.type
== BT_CHARACTER
)
2900 lse
.string_length
= cm
->ts
.cl
->backend_decl
;
2902 gfc_conv_expr (&rse
, expr
);
2904 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, cm
->ts
, true, false);
2905 gfc_add_expr_to_block (&body
, tmp
);
2907 gcc_assert (rse
.ss
== gfc_ss_terminator
);
2909 /* Generate the copying loops. */
2910 gfc_trans_scalarizing_loops (&loop
, &body
);
2912 /* Wrap the whole thing up. */
2913 gfc_add_block_to_block (&block
, &loop
.pre
);
2914 gfc_add_block_to_block (&block
, &loop
.post
);
2916 for (n
= 0; n
< cm
->as
->rank
; n
++)
2917 mpz_clear (lss
->shape
[n
]);
2918 gfc_free (lss
->shape
);
2920 gfc_cleanup_loop (&loop
);
2922 return gfc_finish_block (&block
);
2926 /* Assign a single component of a derived type constructor. */
2929 gfc_trans_subcomponent_assign (tree dest
, gfc_component
* cm
, gfc_expr
* expr
)
2939 gfc_start_block (&block
);
2943 gfc_init_se (&se
, NULL
);
2944 /* Pointer component. */
2947 /* Array pointer. */
2948 if (expr
->expr_type
== EXPR_NULL
)
2949 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
2952 rss
= gfc_walk_expr (expr
);
2953 se
.direct_byref
= 1;
2955 gfc_conv_expr_descriptor (&se
, expr
, rss
);
2956 gfc_add_block_to_block (&block
, &se
.pre
);
2957 gfc_add_block_to_block (&block
, &se
.post
);
2962 /* Scalar pointers. */
2963 se
.want_pointer
= 1;
2964 gfc_conv_expr (&se
, expr
);
2965 gfc_add_block_to_block (&block
, &se
.pre
);
2966 gfc_add_modify_expr (&block
, dest
,
2967 fold_convert (TREE_TYPE (dest
), se
.expr
));
2968 gfc_add_block_to_block (&block
, &se
.post
);
2971 else if (cm
->dimension
)
2973 if (cm
->allocatable
&& expr
->expr_type
== EXPR_NULL
)
2974 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
2975 else if (cm
->allocatable
)
2979 gfc_init_se (&se
, NULL
);
2981 rss
= gfc_walk_expr (expr
);
2982 se
.want_pointer
= 0;
2983 gfc_conv_expr_descriptor (&se
, expr
, rss
);
2984 gfc_add_block_to_block (&block
, &se
.pre
);
2986 tmp
= fold_convert (TREE_TYPE (dest
), se
.expr
);
2987 gfc_add_modify_expr (&block
, dest
, tmp
);
2989 if (cm
->ts
.type
== BT_DERIVED
&& cm
->ts
.derived
->attr
.alloc_comp
)
2990 tmp
= gfc_copy_alloc_comp (cm
->ts
.derived
, se
.expr
, dest
,
2993 tmp
= gfc_duplicate_allocatable (dest
, se
.expr
,
2994 TREE_TYPE(cm
->backend_decl
),
2997 gfc_add_expr_to_block (&block
, tmp
);
2999 gfc_add_block_to_block (&block
, &se
.post
);
3000 gfc_conv_descriptor_data_set (&block
, se
.expr
, null_pointer_node
);
3002 /* Shift the lbound and ubound of temporaries to being unity, rather
3003 than zero, based. Calculate the offset for all cases. */
3004 offset
= gfc_conv_descriptor_offset (dest
);
3005 gfc_add_modify_expr (&block
, offset
, gfc_index_zero_node
);
3006 tmp2
=gfc_create_var (gfc_array_index_type
, NULL
);
3007 for (n
= 0; n
< expr
->rank
; n
++)
3009 if (expr
->expr_type
!= EXPR_VARIABLE
3010 && expr
->expr_type
!= EXPR_CONSTANT
)
3012 tmp
= gfc_conv_descriptor_ubound (dest
, gfc_rank_cst
[n
]);
3013 gfc_add_modify_expr (&block
, tmp
,
3014 fold_build2 (PLUS_EXPR
,
3015 gfc_array_index_type
,
3016 tmp
, gfc_index_one_node
));
3017 tmp
= gfc_conv_descriptor_lbound (dest
, gfc_rank_cst
[n
]);
3018 gfc_add_modify_expr (&block
, tmp
, gfc_index_one_node
);
3020 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
3021 gfc_conv_descriptor_lbound (dest
,
3023 gfc_conv_descriptor_stride (dest
,
3025 gfc_add_modify_expr (&block
, tmp2
, tmp
);
3026 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp2
);
3027 gfc_add_modify_expr (&block
, offset
, tmp
);
3032 tmp
= gfc_trans_subarray_assign (dest
, cm
, expr
);
3033 gfc_add_expr_to_block (&block
, tmp
);
3036 else if (expr
->ts
.type
== BT_DERIVED
)
3038 if (expr
->expr_type
!= EXPR_STRUCTURE
)
3040 gfc_init_se (&se
, NULL
);
3041 gfc_conv_expr (&se
, expr
);
3042 gfc_add_modify_expr (&block
, dest
,
3043 fold_convert (TREE_TYPE (dest
), se
.expr
));
3047 /* Nested constructors. */
3048 tmp
= gfc_trans_structure_assign (dest
, expr
);
3049 gfc_add_expr_to_block (&block
, tmp
);
3054 /* Scalar component. */
3055 gfc_init_se (&se
, NULL
);
3056 gfc_init_se (&lse
, NULL
);
3058 gfc_conv_expr (&se
, expr
);
3059 if (cm
->ts
.type
== BT_CHARACTER
)
3060 lse
.string_length
= cm
->ts
.cl
->backend_decl
;
3062 tmp
= gfc_trans_scalar_assign (&lse
, &se
, cm
->ts
, true, false);
3063 gfc_add_expr_to_block (&block
, tmp
);
3065 return gfc_finish_block (&block
);
3068 /* Assign a derived type constructor to a variable. */
3071 gfc_trans_structure_assign (tree dest
, gfc_expr
* expr
)
3079 gfc_start_block (&block
);
3080 cm
= expr
->ts
.derived
->components
;
3081 for (c
= expr
->value
.constructor
; c
; c
= c
->next
, cm
= cm
->next
)
3083 /* Skip absent members in default initializers. */
3087 field
= cm
->backend_decl
;
3088 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), dest
, field
, NULL_TREE
);
3089 tmp
= gfc_trans_subcomponent_assign (tmp
, cm
, c
->expr
);
3090 gfc_add_expr_to_block (&block
, tmp
);
3092 return gfc_finish_block (&block
);
3095 /* Build an expression for a constructor. If init is nonzero then
3096 this is part of a static variable initializer. */
3099 gfc_conv_structure (gfc_se
* se
, gfc_expr
* expr
, int init
)
3106 VEC(constructor_elt
,gc
) *v
= NULL
;
3108 gcc_assert (se
->ss
== NULL
);
3109 gcc_assert (expr
->expr_type
== EXPR_STRUCTURE
);
3110 type
= gfc_typenode_for_spec (&expr
->ts
);
3114 /* Create a temporary variable and fill it in. */
3115 se
->expr
= gfc_create_var (type
, expr
->ts
.derived
->name
);
3116 tmp
= gfc_trans_structure_assign (se
->expr
, expr
);
3117 gfc_add_expr_to_block (&se
->pre
, tmp
);
3121 cm
= expr
->ts
.derived
->components
;
3123 for (c
= expr
->value
.constructor
; c
; c
= c
->next
, cm
= cm
->next
)
3125 /* Skip absent members in default initializers and allocatable
3126 components. Although the latter have a default initializer
3127 of EXPR_NULL,... by default, the static nullify is not needed
3128 since this is done every time we come into scope. */
3129 if (!c
->expr
|| cm
->allocatable
)
3132 val
= gfc_conv_initializer (c
->expr
, &cm
->ts
,
3133 TREE_TYPE (cm
->backend_decl
), cm
->dimension
, cm
->pointer
);
3135 /* Append it to the constructor list. */
3136 CONSTRUCTOR_APPEND_ELT (v
, cm
->backend_decl
, val
);
3138 se
->expr
= build_constructor (type
, v
);
3142 /* Translate a substring expression. */
3145 gfc_conv_substring_expr (gfc_se
* se
, gfc_expr
* expr
)
3151 gcc_assert (ref
->type
== REF_SUBSTRING
);
3153 se
->expr
= gfc_build_string_const(expr
->value
.character
.length
,
3154 expr
->value
.character
.string
);
3155 se
->string_length
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se
->expr
)));
3156 TYPE_STRING_FLAG (TREE_TYPE (se
->expr
))=1;
3158 gfc_conv_substring(se
,ref
,expr
->ts
.kind
,NULL
,&expr
->where
);
3162 /* Entry point for expression translation. Evaluates a scalar quantity.
3163 EXPR is the expression to be translated, and SE is the state structure if
3164 called from within the scalarized. */
3167 gfc_conv_expr (gfc_se
* se
, gfc_expr
* expr
)
3169 if (se
->ss
&& se
->ss
->expr
== expr
3170 && (se
->ss
->type
== GFC_SS_SCALAR
|| se
->ss
->type
== GFC_SS_REFERENCE
))
3172 /* Substitute a scalar expression evaluated outside the scalarization
3174 se
->expr
= se
->ss
->data
.scalar
.expr
;
3175 se
->string_length
= se
->ss
->string_length
;
3176 gfc_advance_se_ss_chain (se
);
3180 /* We need to convert the expressions for the iso_c_binding derived types.
3181 C_NULL_PTR and C_NULL_FUNPTR will be made EXPR_NULL, which evaluates to
3182 null_pointer_node. C_PTR and C_FUNPTR are converted to match the
3183 typespec for the C_PTR and C_FUNPTR symbols, which has already been
3184 updated to be an integer with a kind equal to the size of a (void *). */
3185 if (expr
->ts
.type
== BT_DERIVED
&& expr
->ts
.derived
3186 && expr
->ts
.derived
->attr
.is_iso_c
)
3188 if (expr
->symtree
->n
.sym
->intmod_sym_id
== ISOCBINDING_NULL_PTR
3189 || expr
->symtree
->n
.sym
->intmod_sym_id
== ISOCBINDING_NULL_FUNPTR
)
3191 /* Set expr_type to EXPR_NULL, which will result in
3192 null_pointer_node being used below. */
3193 expr
->expr_type
= EXPR_NULL
;
3197 /* Update the type/kind of the expression to be what the new
3198 type/kind are for the updated symbols of C_PTR/C_FUNPTR. */
3199 expr
->ts
.type
= expr
->ts
.derived
->ts
.type
;
3200 expr
->ts
.f90_type
= expr
->ts
.derived
->ts
.f90_type
;
3201 expr
->ts
.kind
= expr
->ts
.derived
->ts
.kind
;
3205 switch (expr
->expr_type
)
3208 gfc_conv_expr_op (se
, expr
);
3212 gfc_conv_function_expr (se
, expr
);
3216 gfc_conv_constant (se
, expr
);
3220 gfc_conv_variable (se
, expr
);
3224 se
->expr
= null_pointer_node
;
3227 case EXPR_SUBSTRING
:
3228 gfc_conv_substring_expr (se
, expr
);
3231 case EXPR_STRUCTURE
:
3232 gfc_conv_structure (se
, expr
, 0);
3236 gfc_conv_array_constructor_expr (se
, expr
);
3245 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3246 of an assignment. */
3248 gfc_conv_expr_lhs (gfc_se
* se
, gfc_expr
* expr
)
3250 gfc_conv_expr (se
, expr
);
3251 /* All numeric lvalues should have empty post chains. If not we need to
3252 figure out a way of rewriting an lvalue so that it has no post chain. */
3253 gcc_assert (expr
->ts
.type
== BT_CHARACTER
|| !se
->post
.head
);
3256 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3257 numeric expressions. Used for scalar values where inserting cleanup code
3260 gfc_conv_expr_val (gfc_se
* se
, gfc_expr
* expr
)
3264 gcc_assert (expr
->ts
.type
!= BT_CHARACTER
);
3265 gfc_conv_expr (se
, expr
);
3268 val
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
3269 gfc_add_modify_expr (&se
->pre
, val
, se
->expr
);
3271 gfc_add_block_to_block (&se
->pre
, &se
->post
);
3275 /* Helper to translate and expression and convert it to a particular type. */
3277 gfc_conv_expr_type (gfc_se
* se
, gfc_expr
* expr
, tree type
)
3279 gfc_conv_expr_val (se
, expr
);
3280 se
->expr
= convert (type
, se
->expr
);
3284 /* Converts an expression so that it can be passed by reference. Scalar
3288 gfc_conv_expr_reference (gfc_se
* se
, gfc_expr
* expr
)
3292 if (se
->ss
&& se
->ss
->expr
== expr
3293 && se
->ss
->type
== GFC_SS_REFERENCE
)
3295 se
->expr
= se
->ss
->data
.scalar
.expr
;
3296 se
->string_length
= se
->ss
->string_length
;
3297 gfc_advance_se_ss_chain (se
);
3301 if (expr
->ts
.type
== BT_CHARACTER
)
3303 gfc_conv_expr (se
, expr
);
3304 gfc_conv_string_parameter (se
);
3308 if (expr
->expr_type
== EXPR_VARIABLE
)
3310 se
->want_pointer
= 1;
3311 gfc_conv_expr (se
, expr
);
3314 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
3315 gfc_add_modify_expr (&se
->pre
, var
, se
->expr
);
3316 gfc_add_block_to_block (&se
->pre
, &se
->post
);
3322 gfc_conv_expr (se
, expr
);
3324 /* Create a temporary var to hold the value. */
3325 if (TREE_CONSTANT (se
->expr
))
3327 tree tmp
= se
->expr
;
3328 STRIP_TYPE_NOPS (tmp
);
3329 var
= build_decl (CONST_DECL
, NULL
, TREE_TYPE (tmp
));
3330 DECL_INITIAL (var
) = tmp
;
3331 TREE_STATIC (var
) = 1;
3336 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
3337 gfc_add_modify_expr (&se
->pre
, var
, se
->expr
);
3339 gfc_add_block_to_block (&se
->pre
, &se
->post
);
3341 /* Take the address of that value. */
3342 se
->expr
= build_fold_addr_expr (var
);
3347 gfc_trans_pointer_assign (gfc_code
* code
)
3349 return gfc_trans_pointer_assignment (code
->expr
, code
->expr2
);
3353 /* Generate code for a pointer assignment. */
3356 gfc_trans_pointer_assignment (gfc_expr
* expr1
, gfc_expr
* expr2
)
3366 gfc_start_block (&block
);
3368 gfc_init_se (&lse
, NULL
);
3370 lss
= gfc_walk_expr (expr1
);
3371 rss
= gfc_walk_expr (expr2
);
3372 if (lss
== gfc_ss_terminator
)
3374 /* Scalar pointers. */
3375 lse
.want_pointer
= 1;
3376 gfc_conv_expr (&lse
, expr1
);
3377 gcc_assert (rss
== gfc_ss_terminator
);
3378 gfc_init_se (&rse
, NULL
);
3379 rse
.want_pointer
= 1;
3380 gfc_conv_expr (&rse
, expr2
);
3381 gfc_add_block_to_block (&block
, &lse
.pre
);
3382 gfc_add_block_to_block (&block
, &rse
.pre
);
3383 gfc_add_modify_expr (&block
, lse
.expr
,
3384 fold_convert (TREE_TYPE (lse
.expr
), rse
.expr
));
3385 gfc_add_block_to_block (&block
, &rse
.post
);
3386 gfc_add_block_to_block (&block
, &lse
.post
);
3390 /* Array pointer. */
3391 gfc_conv_expr_descriptor (&lse
, expr1
, lss
);
3392 switch (expr2
->expr_type
)
3395 /* Just set the data pointer to null. */
3396 gfc_conv_descriptor_data_set (&lse
.pre
, lse
.expr
, null_pointer_node
);
3400 /* Assign directly to the pointer's descriptor. */
3401 lse
.direct_byref
= 1;
3402 gfc_conv_expr_descriptor (&lse
, expr2
, rss
);
3406 /* Assign to a temporary descriptor and then copy that
3407 temporary to the pointer. */
3409 tmp
= gfc_create_var (TREE_TYPE (desc
), "ptrtemp");
3412 lse
.direct_byref
= 1;
3413 gfc_conv_expr_descriptor (&lse
, expr2
, rss
);
3414 gfc_add_modify_expr (&lse
.pre
, desc
, tmp
);
3417 gfc_add_block_to_block (&block
, &lse
.pre
);
3418 gfc_add_block_to_block (&block
, &lse
.post
);
3420 return gfc_finish_block (&block
);
3424 /* Makes sure se is suitable for passing as a function string parameter. */
3425 /* TODO: Need to check all callers fo this function. It may be abused. */
3428 gfc_conv_string_parameter (gfc_se
* se
)
3432 if (TREE_CODE (se
->expr
) == STRING_CST
)
3434 se
->expr
= gfc_build_addr_expr (pchar_type_node
, se
->expr
);
3438 type
= TREE_TYPE (se
->expr
);
3439 if (TYPE_STRING_FLAG (type
))
3441 gcc_assert (TREE_CODE (se
->expr
) != INDIRECT_REF
);
3442 se
->expr
= gfc_build_addr_expr (pchar_type_node
, se
->expr
);
3445 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se
->expr
)));
3446 gcc_assert (se
->string_length
3447 && TREE_CODE (TREE_TYPE (se
->string_length
)) == INTEGER_TYPE
);
3451 /* Generate code for assignment of scalar variables. Includes character
3452 strings and derived types with allocatable components. */
3455 gfc_trans_scalar_assign (gfc_se
* lse
, gfc_se
* rse
, gfc_typespec ts
,
3456 bool l_is_temp
, bool r_is_var
)
3462 gfc_init_block (&block
);
3464 if (ts
.type
== BT_CHARACTER
)
3466 gcc_assert (lse
->string_length
!= NULL_TREE
3467 && rse
->string_length
!= NULL_TREE
);
3469 gfc_conv_string_parameter (lse
);
3470 gfc_conv_string_parameter (rse
);
3472 gfc_add_block_to_block (&block
, &lse
->pre
);
3473 gfc_add_block_to_block (&block
, &rse
->pre
);
3475 gfc_trans_string_copy (&block
, lse
->string_length
, lse
->expr
,
3476 rse
->string_length
, rse
->expr
);
3478 else if (ts
.type
== BT_DERIVED
&& ts
.derived
->attr
.alloc_comp
)
3482 /* Are the rhs and the lhs the same? */
3485 cond
= fold_build2 (EQ_EXPR
, boolean_type_node
,
3486 build_fold_addr_expr (lse
->expr
),
3487 build_fold_addr_expr (rse
->expr
));
3488 cond
= gfc_evaluate_now (cond
, &lse
->pre
);
3491 /* Deallocate the lhs allocated components as long as it is not
3492 the same as the rhs. */
3495 tmp
= gfc_deallocate_alloc_comp (ts
.derived
, lse
->expr
, 0);
3497 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (), tmp
);
3498 gfc_add_expr_to_block (&lse
->pre
, tmp
);
3501 gfc_add_block_to_block (&block
, &lse
->pre
);
3502 gfc_add_block_to_block (&block
, &rse
->pre
);
3504 gfc_add_modify_expr (&block
, lse
->expr
,
3505 fold_convert (TREE_TYPE (lse
->expr
), rse
->expr
));
3507 /* Do a deep copy if the rhs is a variable, if it is not the
3511 tmp
= gfc_copy_alloc_comp (ts
.derived
, rse
->expr
, lse
->expr
, 0);
3512 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (), tmp
);
3513 gfc_add_expr_to_block (&block
, tmp
);
3518 gfc_add_block_to_block (&block
, &lse
->pre
);
3519 gfc_add_block_to_block (&block
, &rse
->pre
);
3521 gfc_add_modify_expr (&block
, lse
->expr
,
3522 fold_convert (TREE_TYPE (lse
->expr
), rse
->expr
));
3525 gfc_add_block_to_block (&block
, &lse
->post
);
3526 gfc_add_block_to_block (&block
, &rse
->post
);
3528 return gfc_finish_block (&block
);
3532 /* Try to translate array(:) = func (...), where func is a transformational
3533 array function, without using a temporary. Returns NULL is this isn't the
3537 gfc_trans_arrayfunc_assign (gfc_expr
* expr1
, gfc_expr
* expr2
)
3542 bool seen_array_ref
;
3544 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
3545 if (expr2
->value
.function
.isym
&& !gfc_is_intrinsic_libcall (expr2
))
3548 /* Elemental functions don't need a temporary anyway. */
3549 if (expr2
->value
.function
.esym
!= NULL
3550 && expr2
->value
.function
.esym
->attr
.elemental
)
3553 /* Fail if EXPR1 can't be expressed as a descriptor. */
3554 if (gfc_ref_needs_temporary_p (expr1
->ref
))
3557 /* Functions returning pointers need temporaries. */
3558 if (expr2
->symtree
->n
.sym
->attr
.pointer
3559 || expr2
->symtree
->n
.sym
->attr
.allocatable
)
3562 /* Character array functions need temporaries unless the
3563 character lengths are the same. */
3564 if (expr2
->ts
.type
== BT_CHARACTER
&& expr2
->rank
> 0)
3566 if (expr1
->ts
.cl
->length
== NULL
3567 || expr1
->ts
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
3570 if (expr2
->ts
.cl
->length
== NULL
3571 || expr2
->ts
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
3574 if (mpz_cmp (expr1
->ts
.cl
->length
->value
.integer
,
3575 expr2
->ts
.cl
->length
->value
.integer
) != 0)
3579 /* Check that no LHS component references appear during an array
3580 reference. This is needed because we do not have the means to
3581 span any arbitrary stride with an array descriptor. This check
3582 is not needed for the rhs because the function result has to be
3584 seen_array_ref
= false;
3585 for (ref
= expr1
->ref
; ref
; ref
= ref
->next
)
3587 if (ref
->type
== REF_ARRAY
)
3588 seen_array_ref
= true;
3589 else if (ref
->type
== REF_COMPONENT
&& seen_array_ref
)
3593 /* Check for a dependency. */
3594 if (gfc_check_fncall_dependency (expr1
, INTENT_OUT
,
3595 expr2
->value
.function
.esym
,
3596 expr2
->value
.function
.actual
))
3599 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3601 gcc_assert (expr2
->value
.function
.isym
3602 || (gfc_return_by_reference (expr2
->value
.function
.esym
)
3603 && expr2
->value
.function
.esym
->result
->attr
.dimension
));
3605 ss
= gfc_walk_expr (expr1
);
3606 gcc_assert (ss
!= gfc_ss_terminator
);
3607 gfc_init_se (&se
, NULL
);
3608 gfc_start_block (&se
.pre
);
3609 se
.want_pointer
= 1;
3611 gfc_conv_array_parameter (&se
, expr1
, ss
, 0);
3613 se
.direct_byref
= 1;
3614 se
.ss
= gfc_walk_expr (expr2
);
3615 gcc_assert (se
.ss
!= gfc_ss_terminator
);
3616 gfc_conv_function_expr (&se
, expr2
);
3617 gfc_add_block_to_block (&se
.pre
, &se
.post
);
3619 return gfc_finish_block (&se
.pre
);
3622 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
3625 is_zero_initializer_p (gfc_expr
* expr
)
3627 if (expr
->expr_type
!= EXPR_CONSTANT
)
3630 /* We ignore constants with prescribed memory representations for now. */
3631 if (expr
->representation
.string
)
3634 switch (expr
->ts
.type
)
3637 return mpz_cmp_si (expr
->value
.integer
, 0) == 0;
3640 return mpfr_zero_p (expr
->value
.real
)
3641 && MPFR_SIGN (expr
->value
.real
) >= 0;
3644 return expr
->value
.logical
== 0;
3647 return mpfr_zero_p (expr
->value
.complex.r
)
3648 && MPFR_SIGN (expr
->value
.complex.r
) >= 0
3649 && mpfr_zero_p (expr
->value
.complex.i
)
3650 && MPFR_SIGN (expr
->value
.complex.i
) >= 0;
3658 /* Try to efficiently translate array(:) = 0. Return NULL if this
3662 gfc_trans_zero_assign (gfc_expr
* expr
)
3664 tree dest
, len
, type
;
3668 sym
= expr
->symtree
->n
.sym
;
3669 dest
= gfc_get_symbol_decl (sym
);
3671 type
= TREE_TYPE (dest
);
3672 if (POINTER_TYPE_P (type
))
3673 type
= TREE_TYPE (type
);
3674 if (!GFC_ARRAY_TYPE_P (type
))
3677 /* Determine the length of the array. */
3678 len
= GFC_TYPE_ARRAY_SIZE (type
);
3679 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
3682 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (type
));
3683 len
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, len
,
3684 fold_convert (gfc_array_index_type
, tmp
));
3686 /* Convert arguments to the correct types. */
3687 if (!POINTER_TYPE_P (TREE_TYPE (dest
)))
3688 dest
= gfc_build_addr_expr (pvoid_type_node
, dest
);
3690 dest
= fold_convert (pvoid_type_node
, dest
);
3691 len
= fold_convert (size_type_node
, len
);
3693 /* Construct call to __builtin_memset. */
3694 tmp
= build_call_expr (built_in_decls
[BUILT_IN_MEMSET
],
3695 3, dest
, integer_zero_node
, len
);
3696 return fold_convert (void_type_node
, tmp
);
3700 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
3701 that constructs the call to __builtin_memcpy. */
3704 gfc_build_memcpy_call (tree dst
, tree src
, tree len
)
3708 /* Convert arguments to the correct types. */
3709 if (!POINTER_TYPE_P (TREE_TYPE (dst
)))
3710 dst
= gfc_build_addr_expr (pvoid_type_node
, dst
);
3712 dst
= fold_convert (pvoid_type_node
, dst
);
3714 if (!POINTER_TYPE_P (TREE_TYPE (src
)))
3715 src
= gfc_build_addr_expr (pvoid_type_node
, src
);
3717 src
= fold_convert (pvoid_type_node
, src
);
3719 len
= fold_convert (size_type_node
, len
);
3721 /* Construct call to __builtin_memcpy. */
3722 tmp
= build_call_expr (built_in_decls
[BUILT_IN_MEMCPY
], 3, dst
, src
, len
);
3723 return fold_convert (void_type_node
, tmp
);
3727 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
3728 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
3729 source/rhs, both are gfc_full_array_ref_p which have been checked for
3733 gfc_trans_array_copy (gfc_expr
* expr1
, gfc_expr
* expr2
)
3735 tree dst
, dlen
, dtype
;
3736 tree src
, slen
, stype
;
3739 dst
= gfc_get_symbol_decl (expr1
->symtree
->n
.sym
);
3740 src
= gfc_get_symbol_decl (expr2
->symtree
->n
.sym
);
3742 dtype
= TREE_TYPE (dst
);
3743 if (POINTER_TYPE_P (dtype
))
3744 dtype
= TREE_TYPE (dtype
);
3745 stype
= TREE_TYPE (src
);
3746 if (POINTER_TYPE_P (stype
))
3747 stype
= TREE_TYPE (stype
);
3749 if (!GFC_ARRAY_TYPE_P (dtype
) || !GFC_ARRAY_TYPE_P (stype
))
3752 /* Determine the lengths of the arrays. */
3753 dlen
= GFC_TYPE_ARRAY_SIZE (dtype
);
3754 if (!dlen
|| TREE_CODE (dlen
) != INTEGER_CST
)
3756 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (dtype
));
3757 dlen
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, dlen
,
3758 fold_convert (gfc_array_index_type
, tmp
));
3760 slen
= GFC_TYPE_ARRAY_SIZE (stype
);
3761 if (!slen
|| TREE_CODE (slen
) != INTEGER_CST
)
3763 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (stype
));
3764 slen
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, slen
,
3765 fold_convert (gfc_array_index_type
, tmp
));
3767 /* Sanity check that they are the same. This should always be
3768 the case, as we should already have checked for conformance. */
3769 if (!tree_int_cst_equal (slen
, dlen
))
3772 return gfc_build_memcpy_call (dst
, src
, dlen
);
3776 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
3777 this can't be done. EXPR1 is the destination/lhs for which
3778 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
3781 gfc_trans_array_constructor_copy (gfc_expr
* expr1
, gfc_expr
* expr2
)
3783 unsigned HOST_WIDE_INT nelem
;
3789 nelem
= gfc_constant_array_constructor_p (expr2
->value
.constructor
);
3793 dst
= gfc_get_symbol_decl (expr1
->symtree
->n
.sym
);
3794 dtype
= TREE_TYPE (dst
);
3795 if (POINTER_TYPE_P (dtype
))
3796 dtype
= TREE_TYPE (dtype
);
3797 if (!GFC_ARRAY_TYPE_P (dtype
))
3800 /* Determine the lengths of the array. */
3801 len
= GFC_TYPE_ARRAY_SIZE (dtype
);
3802 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
3805 /* Confirm that the constructor is the same size. */
3806 if (compare_tree_int (len
, nelem
) != 0)
3809 tmp
= TYPE_SIZE_UNIT (gfc_get_element_type (dtype
));
3810 len
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, len
,
3811 fold_convert (gfc_array_index_type
, tmp
));
3813 stype
= gfc_typenode_for_spec (&expr2
->ts
);
3814 src
= gfc_build_constant_array_constructor (expr2
, stype
);
3816 stype
= TREE_TYPE (src
);
3817 if (POINTER_TYPE_P (stype
))
3818 stype
= TREE_TYPE (stype
);
3820 return gfc_build_memcpy_call (dst
, src
, len
);
3824 /* Subroutine of gfc_trans_assignment that actually scalarizes the
3825 assignment. EXPR1 is the destination/RHS and EXPR2 is the source/LHS. */
3828 gfc_trans_assignment_1 (gfc_expr
* expr1
, gfc_expr
* expr2
, bool init_flag
)
3833 gfc_ss
*lss_section
;
3841 /* Assignment of the form lhs = rhs. */
3842 gfc_start_block (&block
);
3844 gfc_init_se (&lse
, NULL
);
3845 gfc_init_se (&rse
, NULL
);
3848 lss
= gfc_walk_expr (expr1
);
3850 if (lss
!= gfc_ss_terminator
)
3852 /* The assignment needs scalarization. */
3855 /* Find a non-scalar SS from the lhs. */
3856 while (lss_section
!= gfc_ss_terminator
3857 && lss_section
->type
!= GFC_SS_SECTION
)
3858 lss_section
= lss_section
->next
;
3860 gcc_assert (lss_section
!= gfc_ss_terminator
);
3862 /* Initialize the scalarizer. */
3863 gfc_init_loopinfo (&loop
);
3866 rss
= gfc_walk_expr (expr2
);
3867 if (rss
== gfc_ss_terminator
)
3869 /* The rhs is scalar. Add a ss for the expression. */
3870 rss
= gfc_get_ss ();
3871 rss
->next
= gfc_ss_terminator
;
3872 rss
->type
= GFC_SS_SCALAR
;
3875 /* Associate the SS with the loop. */
3876 gfc_add_ss_to_loop (&loop
, lss
);
3877 gfc_add_ss_to_loop (&loop
, rss
);
3879 /* Calculate the bounds of the scalarization. */
3880 gfc_conv_ss_startstride (&loop
);
3881 /* Resolve any data dependencies in the statement. */
3882 gfc_conv_resolve_dependencies (&loop
, lss
, rss
);
3883 /* Setup the scalarizing loops. */
3884 gfc_conv_loop_setup (&loop
);
3886 /* Setup the gfc_se structures. */
3887 gfc_copy_loopinfo_to_se (&lse
, &loop
);
3888 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3891 gfc_mark_ss_chain_used (rss
, 1);
3892 if (loop
.temp_ss
== NULL
)
3895 gfc_mark_ss_chain_used (lss
, 1);
3899 lse
.ss
= loop
.temp_ss
;
3900 gfc_mark_ss_chain_used (lss
, 3);
3901 gfc_mark_ss_chain_used (loop
.temp_ss
, 3);
3904 /* Start the scalarized loop body. */
3905 gfc_start_scalarized_body (&loop
, &body
);
3908 gfc_init_block (&body
);
3910 l_is_temp
= (lss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
);
3912 /* Translate the expression. */
3913 gfc_conv_expr (&rse
, expr2
);
3917 gfc_conv_tmp_array_ref (&lse
);
3918 gfc_advance_se_ss_chain (&lse
);
3921 gfc_conv_expr (&lse
, expr1
);
3923 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
3924 l_is_temp
|| init_flag
,
3925 expr2
->expr_type
== EXPR_VARIABLE
);
3926 gfc_add_expr_to_block (&body
, tmp
);
3928 if (lss
== gfc_ss_terminator
)
3930 /* Use the scalar assignment as is. */
3931 gfc_add_block_to_block (&block
, &body
);
3935 gcc_assert (lse
.ss
== gfc_ss_terminator
3936 && rse
.ss
== gfc_ss_terminator
);
3940 gfc_trans_scalarized_loop_boundary (&loop
, &body
);
3942 /* We need to copy the temporary to the actual lhs. */
3943 gfc_init_se (&lse
, NULL
);
3944 gfc_init_se (&rse
, NULL
);
3945 gfc_copy_loopinfo_to_se (&lse
, &loop
);
3946 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3948 rse
.ss
= loop
.temp_ss
;
3951 gfc_conv_tmp_array_ref (&rse
);
3952 gfc_advance_se_ss_chain (&rse
);
3953 gfc_conv_expr (&lse
, expr1
);
3955 gcc_assert (lse
.ss
== gfc_ss_terminator
3956 && rse
.ss
== gfc_ss_terminator
);
3958 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
3960 gfc_add_expr_to_block (&body
, tmp
);
3963 /* Generate the copying loops. */
3964 gfc_trans_scalarizing_loops (&loop
, &body
);
3966 /* Wrap the whole thing up. */
3967 gfc_add_block_to_block (&block
, &loop
.pre
);
3968 gfc_add_block_to_block (&block
, &loop
.post
);
3970 gfc_cleanup_loop (&loop
);
3973 return gfc_finish_block (&block
);
3977 /* Check whether EXPR, which is an EXPR_VARIABLE, is a copyable array. */
3980 copyable_array_p (gfc_expr
* expr
)
3982 /* First check it's an array. */
3983 if (expr
->rank
< 1 || !expr
->ref
)
3986 /* Next check that it's of a simple enough type. */
3987 switch (expr
->ts
.type
)
3999 return !expr
->ts
.derived
->attr
.alloc_comp
;
4008 /* Translate an assignment. */
4011 gfc_trans_assignment (gfc_expr
* expr1
, gfc_expr
* expr2
, bool init_flag
)
4015 /* Special case a single function returning an array. */
4016 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->rank
> 0)
4018 tmp
= gfc_trans_arrayfunc_assign (expr1
, expr2
);
4023 /* Special case assigning an array to zero. */
4024 if (expr1
->expr_type
== EXPR_VARIABLE
4027 && expr1
->ref
->next
== NULL
4028 && gfc_full_array_ref_p (expr1
->ref
)
4029 && is_zero_initializer_p (expr2
))
4031 tmp
= gfc_trans_zero_assign (expr1
);
4036 /* Special case copying one array to another. */
4037 if (expr1
->expr_type
== EXPR_VARIABLE
4038 && copyable_array_p (expr1
)
4039 && gfc_full_array_ref_p (expr1
->ref
)
4040 && expr2
->expr_type
== EXPR_VARIABLE
4041 && copyable_array_p (expr2
)
4042 && gfc_full_array_ref_p (expr2
->ref
)
4043 && gfc_compare_types (&expr1
->ts
, &expr2
->ts
)
4044 && !gfc_check_dependency (expr1
, expr2
, 0))
4046 tmp
= gfc_trans_array_copy (expr1
, expr2
);
4051 /* Special case initializing an array from a constant array constructor. */
4052 if (expr1
->expr_type
== EXPR_VARIABLE
4053 && copyable_array_p (expr1
)
4054 && gfc_full_array_ref_p (expr1
->ref
)
4055 && expr2
->expr_type
== EXPR_ARRAY
4056 && gfc_compare_types (&expr1
->ts
, &expr2
->ts
))
4058 tmp
= gfc_trans_array_constructor_copy (expr1
, expr2
);
4063 /* Fallback to the scalarizer to generate explicit loops. */
4064 return gfc_trans_assignment_1 (expr1
, expr2
, init_flag
);
4068 gfc_trans_init_assign (gfc_code
* code
)
4070 return gfc_trans_assignment (code
->expr
, code
->expr2
, true);
4074 gfc_trans_assign (gfc_code
* code
)
4076 return gfc_trans_assignment (code
->expr
, code
->expr2
, false);