1 /* Expression translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 /* trans-expr.c-- generate GENERIC trees for gfc_expr. */
27 #include "coretypes.h"
33 #include "tree-gimple.h"
34 #include "langhooks.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
41 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
42 #include "trans-stmt.h"
43 #include "dependency.h"
45 static tree
gfc_trans_structure_assign (tree dest
, gfc_expr
* expr
);
46 static void gfc_apply_interface_mapping_to_expr (gfc_interface_mapping
*,
49 /* Copy the scalarization loop variables. */
52 gfc_copy_se_loopvars (gfc_se
* dest
, gfc_se
* src
)
55 dest
->loop
= src
->loop
;
59 /* Initialize a simple expression holder.
61 Care must be taken when multiple se are created with the same parent.
62 The child se must be kept in sync. The easiest way is to delay creation
63 of a child se until after after the previous se has been translated. */
66 gfc_init_se (gfc_se
* se
, gfc_se
* parent
)
68 memset (se
, 0, sizeof (gfc_se
));
69 gfc_init_block (&se
->pre
);
70 gfc_init_block (&se
->post
);
75 gfc_copy_se_loopvars (se
, parent
);
79 /* Advances to the next SS in the chain. Use this rather than setting
80 se->ss = se->ss->next because all the parents needs to be kept in sync.
84 gfc_advance_se_ss_chain (gfc_se
* se
)
88 gcc_assert (se
!= NULL
&& se
->ss
!= NULL
&& se
->ss
!= gfc_ss_terminator
);
91 /* Walk down the parent chain. */
94 /* Simple consistency check. */
95 gcc_assert (p
->parent
== NULL
|| p
->parent
->ss
== p
->ss
);
104 /* Ensures the result of the expression as either a temporary variable
105 or a constant so that it can be used repeatedly. */
108 gfc_make_safe_expr (gfc_se
* se
)
112 if (CONSTANT_CLASS_P (se
->expr
))
115 /* We need a temporary for this result. */
116 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
117 gfc_add_modify_expr (&se
->pre
, var
, se
->expr
);
122 /* Return an expression which determines if a dummy parameter is present.
123 Also used for arguments to procedures with multiple entry points. */
126 gfc_conv_expr_present (gfc_symbol
* sym
)
130 gcc_assert (sym
->attr
.dummy
);
132 decl
= gfc_get_symbol_decl (sym
);
133 if (TREE_CODE (decl
) != PARM_DECL
)
135 /* Array parameters use a temporary descriptor, we want the real
137 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl
))
138 || GFC_ARRAY_TYPE_P (TREE_TYPE (decl
)));
139 decl
= GFC_DECL_SAVED_DESCRIPTOR (decl
);
141 return build2 (NE_EXPR
, boolean_type_node
, decl
,
142 fold_convert (TREE_TYPE (decl
), null_pointer_node
));
146 /* Converts a missing, dummy argument into a null or zero. */
149 gfc_conv_missing_dummy (gfc_se
* se
, gfc_expr
* arg
, gfc_typespec ts
)
154 present
= gfc_conv_expr_present (arg
->symtree
->n
.sym
);
155 tmp
= build3 (COND_EXPR
, TREE_TYPE (se
->expr
), present
, se
->expr
,
156 fold_convert (TREE_TYPE (se
->expr
), integer_zero_node
));
158 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
160 if (ts
.type
== BT_CHARACTER
)
162 tmp
= build_int_cst (gfc_charlen_type_node
, 0);
163 tmp
= build3 (COND_EXPR
, gfc_charlen_type_node
, present
,
164 se
->string_length
, tmp
);
165 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
166 se
->string_length
= tmp
;
172 /* Get the character length of an expression, looking through gfc_refs
176 gfc_get_expr_charlen (gfc_expr
*e
)
181 gcc_assert (e
->expr_type
== EXPR_VARIABLE
182 && e
->ts
.type
== BT_CHARACTER
);
184 length
= NULL
; /* To silence compiler warning. */
186 /* First candidate: if the variable is of type CHARACTER, the
187 expression's length could be the length of the character
189 if (e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
)
190 length
= e
->symtree
->n
.sym
->ts
.cl
->backend_decl
;
192 /* Look through the reference chain for component references. */
193 for (r
= e
->ref
; r
; r
= r
->next
)
198 if (r
->u
.c
.component
->ts
.type
== BT_CHARACTER
)
199 length
= r
->u
.c
.component
->ts
.cl
->backend_decl
;
207 /* We should never got substring references here. These will be
208 broken down by the scalarizer. */
213 gcc_assert (length
!= NULL
);
219 /* Generate code to initialize a string length variable. Returns the
223 gfc_trans_init_string_length (gfc_charlen
* cl
, stmtblock_t
* pblock
)
228 gfc_init_se (&se
, NULL
);
229 gfc_conv_expr_type (&se
, cl
->length
, gfc_charlen_type_node
);
230 gfc_add_block_to_block (pblock
, &se
.pre
);
232 tmp
= cl
->backend_decl
;
233 gfc_add_modify_expr (pblock
, tmp
, se
.expr
);
238 gfc_conv_substring (gfc_se
* se
, gfc_ref
* ref
, int kind
,
239 const char *name
, locus
*where
)
249 type
= gfc_get_character_type (kind
, ref
->u
.ss
.length
);
250 type
= build_pointer_type (type
);
253 gfc_init_se (&start
, se
);
254 gfc_conv_expr_type (&start
, ref
->u
.ss
.start
, gfc_charlen_type_node
);
255 gfc_add_block_to_block (&se
->pre
, &start
.pre
);
257 if (integer_onep (start
.expr
))
258 gfc_conv_string_parameter (se
);
261 /* Change the start of the string. */
262 if (TYPE_STRING_FLAG (TREE_TYPE (se
->expr
)))
265 tmp
= build_fold_indirect_ref (se
->expr
);
266 tmp
= gfc_build_array_ref (tmp
, start
.expr
);
267 se
->expr
= gfc_build_addr_expr (type
, tmp
);
270 /* Length = end + 1 - start. */
271 gfc_init_se (&end
, se
);
272 if (ref
->u
.ss
.end
== NULL
)
273 end
.expr
= se
->string_length
;
276 gfc_conv_expr_type (&end
, ref
->u
.ss
.end
, gfc_charlen_type_node
);
277 gfc_add_block_to_block (&se
->pre
, &end
.pre
);
279 if (flag_bounds_check
)
281 tree nonempty
= fold_build2 (LE_EXPR
, boolean_type_node
,
282 start
.expr
, end
.expr
);
284 /* Check lower bound. */
285 fault
= fold_build2 (LT_EXPR
, boolean_type_node
, start
.expr
,
286 build_int_cst (gfc_charlen_type_node
, 1));
287 fault
= fold_build2 (TRUTH_ANDIF_EXPR
, boolean_type_node
,
290 asprintf (&msg
, "Substring out of bounds: lower bound of '%s' "
291 "is less than one", name
);
293 asprintf (&msg
, "Substring out of bounds: lower bound "
295 gfc_trans_runtime_check (fault
, msg
, &se
->pre
, where
);
298 /* Check upper bound. */
299 fault
= fold_build2 (GT_EXPR
, boolean_type_node
, end
.expr
,
301 fault
= fold_build2 (TRUTH_ANDIF_EXPR
, boolean_type_node
,
304 asprintf (&msg
, "Substring out of bounds: upper bound of '%s' "
305 "exceeds string length", name
);
307 asprintf (&msg
, "Substring out of bounds: upper bound "
308 "exceeds string length");
309 gfc_trans_runtime_check (fault
, msg
, &se
->pre
, where
);
313 tmp
= fold_build2 (MINUS_EXPR
, gfc_charlen_type_node
,
314 build_int_cst (gfc_charlen_type_node
, 1),
316 tmp
= fold_build2 (PLUS_EXPR
, gfc_charlen_type_node
, end
.expr
, tmp
);
317 tmp
= fold_build2 (MAX_EXPR
, gfc_charlen_type_node
, tmp
,
318 build_int_cst (gfc_charlen_type_node
, 0));
319 se
->string_length
= tmp
;
323 /* Convert a derived type component reference. */
326 gfc_conv_component_ref (gfc_se
* se
, gfc_ref
* ref
)
333 c
= ref
->u
.c
.component
;
335 gcc_assert (c
->backend_decl
);
337 field
= c
->backend_decl
;
338 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
340 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), decl
, field
, NULL_TREE
);
344 if (c
->ts
.type
== BT_CHARACTER
)
346 tmp
= c
->ts
.cl
->backend_decl
;
347 /* Components must always be constant length. */
348 gcc_assert (tmp
&& INTEGER_CST_P (tmp
));
349 se
->string_length
= tmp
;
352 if (c
->pointer
&& c
->dimension
== 0 && c
->ts
.type
!= BT_CHARACTER
)
353 se
->expr
= build_fold_indirect_ref (se
->expr
);
357 /* Return the contents of a variable. Also handles reference/pointer
358 variables (all Fortran pointer references are implicit). */
361 gfc_conv_variable (gfc_se
* se
, gfc_expr
* expr
)
368 bool alternate_entry
;
371 sym
= expr
->symtree
->n
.sym
;
374 /* Check that something hasn't gone horribly wrong. */
375 gcc_assert (se
->ss
!= gfc_ss_terminator
);
376 gcc_assert (se
->ss
->expr
== expr
);
378 /* A scalarized term. We already know the descriptor. */
379 se
->expr
= se
->ss
->data
.info
.descriptor
;
380 se
->string_length
= se
->ss
->string_length
;
381 for (ref
= se
->ss
->data
.info
.ref
; ref
; ref
= ref
->next
)
382 if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
387 tree se_expr
= NULL_TREE
;
389 se
->expr
= gfc_get_symbol_decl (sym
);
391 /* Deal with references to a parent results or entries by storing
392 the current_function_decl and moving to the parent_decl. */
393 return_value
= sym
->attr
.function
&& sym
->result
== sym
;
394 alternate_entry
= sym
->attr
.function
&& sym
->attr
.entry
395 && sym
->result
== sym
;
396 entry_master
= sym
->attr
.result
397 && sym
->ns
->proc_name
->attr
.entry_master
398 && !gfc_return_by_reference (sym
->ns
->proc_name
);
399 parent_decl
= DECL_CONTEXT (current_function_decl
);
401 if ((se
->expr
== parent_decl
&& return_value
)
402 || (sym
->ns
&& sym
->ns
->proc_name
404 && sym
->ns
->proc_name
->backend_decl
== parent_decl
405 && (alternate_entry
|| entry_master
)))
410 /* Special case for assigning the return value of a function.
411 Self recursive functions must have an explicit return value. */
412 if (return_value
&& (se
->expr
== current_function_decl
|| parent_flag
))
413 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
415 /* Similarly for alternate entry points. */
416 else if (alternate_entry
417 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
420 gfc_entry_list
*el
= NULL
;
422 for (el
= sym
->ns
->entries
; el
; el
= el
->next
)
425 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
430 else if (entry_master
431 && (sym
->ns
->proc_name
->backend_decl
== current_function_decl
433 se_expr
= gfc_get_fake_result_decl (sym
, parent_flag
);
438 /* Procedure actual arguments. */
439 else if (sym
->attr
.flavor
== FL_PROCEDURE
440 && se
->expr
!= current_function_decl
)
442 gcc_assert (se
->want_pointer
);
443 if (!sym
->attr
.dummy
)
445 gcc_assert (TREE_CODE (se
->expr
) == FUNCTION_DECL
);
446 se
->expr
= build_fold_addr_expr (se
->expr
);
452 /* Dereference the expression, where needed. Since characters
453 are entirely different from other types, they are treated
455 if (sym
->ts
.type
== BT_CHARACTER
)
457 /* Dereference character pointer dummy arguments
459 if ((sym
->attr
.pointer
|| sym
->attr
.allocatable
)
461 || sym
->attr
.function
462 || sym
->attr
.result
))
463 se
->expr
= build_fold_indirect_ref (se
->expr
);
465 /* A character with VALUE attribute needs an address
468 se
->expr
= build_fold_addr_expr (se
->expr
);
471 else if (!sym
->attr
.value
)
473 /* Dereference non-character scalar dummy arguments. */
474 if (sym
->attr
.dummy
&& !sym
->attr
.dimension
)
475 se
->expr
= build_fold_indirect_ref (se
->expr
);
477 /* Dereference scalar hidden result. */
478 if (gfc_option
.flag_f2c
&& sym
->ts
.type
== BT_COMPLEX
479 && (sym
->attr
.function
|| sym
->attr
.result
)
480 && !sym
->attr
.dimension
&& !sym
->attr
.pointer
)
481 se
->expr
= build_fold_indirect_ref (se
->expr
);
483 /* Dereference non-character pointer variables.
484 These must be dummies, results, or scalars. */
485 if ((sym
->attr
.pointer
|| sym
->attr
.allocatable
)
487 || sym
->attr
.function
489 || !sym
->attr
.dimension
))
490 se
->expr
= build_fold_indirect_ref (se
->expr
);
496 /* For character variables, also get the length. */
497 if (sym
->ts
.type
== BT_CHARACTER
)
499 /* If the character length of an entry isn't set, get the length from
500 the master function instead. */
501 if (sym
->attr
.entry
&& !sym
->ts
.cl
->backend_decl
)
502 se
->string_length
= sym
->ns
->proc_name
->ts
.cl
->backend_decl
;
504 se
->string_length
= sym
->ts
.cl
->backend_decl
;
505 gcc_assert (se
->string_length
);
513 /* Return the descriptor if that's what we want and this is an array
514 section reference. */
515 if (se
->descriptor_only
&& ref
->u
.ar
.type
!= AR_ELEMENT
)
517 /* TODO: Pointers to single elements of array sections, eg elemental subs. */
518 /* Return the descriptor for array pointers and allocations. */
520 && ref
->next
== NULL
&& (se
->descriptor_only
))
523 gfc_conv_array_ref (se
, &ref
->u
.ar
, sym
, &expr
->where
);
524 /* Return a pointer to an element. */
528 gfc_conv_component_ref (se
, ref
);
532 gfc_conv_substring (se
, ref
, expr
->ts
.kind
,
533 expr
->symtree
->name
, &expr
->where
);
542 /* Pointer assignment, allocation or pass by reference. Arrays are handled
544 if (se
->want_pointer
)
546 if (expr
->ts
.type
== BT_CHARACTER
)
547 gfc_conv_string_parameter (se
);
549 se
->expr
= build_fold_addr_expr (se
->expr
);
554 /* Unary ops are easy... Or they would be if ! was a valid op. */
557 gfc_conv_unary_op (enum tree_code code
, gfc_se
* se
, gfc_expr
* expr
)
562 gcc_assert (expr
->ts
.type
!= BT_CHARACTER
);
563 /* Initialize the operand. */
564 gfc_init_se (&operand
, se
);
565 gfc_conv_expr_val (&operand
, expr
->value
.op
.op1
);
566 gfc_add_block_to_block (&se
->pre
, &operand
.pre
);
568 type
= gfc_typenode_for_spec (&expr
->ts
);
570 /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
571 We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
572 All other unary operators have an equivalent GIMPLE unary operator. */
573 if (code
== TRUTH_NOT_EXPR
)
574 se
->expr
= build2 (EQ_EXPR
, type
, operand
.expr
,
575 build_int_cst (type
, 0));
577 se
->expr
= build1 (code
, type
, operand
.expr
);
581 /* Expand power operator to optimal multiplications when a value is raised
582 to a constant integer n. See section 4.6.3, "Evaluation of Powers" of
583 Donald E. Knuth, "Seminumerical Algorithms", Vol. 2, "The Art of Computer
584 Programming", 3rd Edition, 1998. */
586 /* This code is mostly duplicated from expand_powi in the backend.
587 We establish the "optimal power tree" lookup table with the defined size.
588 The items in the table are the exponents used to calculate the index
589 exponents. Any integer n less than the value can get an "addition chain",
590 with the first node being one. */
591 #define POWI_TABLE_SIZE 256
593 /* The table is from builtins.c. */
594 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
596 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
597 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
598 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
599 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
600 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
601 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
602 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
603 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
604 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
605 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
606 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
607 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
608 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
609 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
610 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
611 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
612 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
613 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
614 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
615 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
616 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
617 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
618 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
619 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
620 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
621 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
622 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
623 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
624 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
625 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
626 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
627 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
630 /* If n is larger than lookup table's max index, we use the "window
632 #define POWI_WINDOW_SIZE 3
634 /* Recursive function to expand the power operator. The temporary
635 values are put in tmpvar. The function returns tmpvar[1] ** n. */
637 gfc_conv_powi (gfc_se
* se
, int n
, tree
* tmpvar
)
644 if (n
< POWI_TABLE_SIZE
)
649 op0
= gfc_conv_powi (se
, n
- powi_table
[n
], tmpvar
);
650 op1
= gfc_conv_powi (se
, powi_table
[n
], tmpvar
);
654 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
655 op0
= gfc_conv_powi (se
, n
- digit
, tmpvar
);
656 op1
= gfc_conv_powi (se
, digit
, tmpvar
);
660 op0
= gfc_conv_powi (se
, n
>> 1, tmpvar
);
664 tmp
= fold_build2 (MULT_EXPR
, TREE_TYPE (op0
), op0
, op1
);
665 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
667 if (n
< POWI_TABLE_SIZE
)
674 /* Expand lhs ** rhs. rhs is a constant integer. If it expands successfully,
675 return 1. Else return 0 and a call to runtime library functions
676 will have to be built. */
678 gfc_conv_cst_int_power (gfc_se
* se
, tree lhs
, tree rhs
)
683 tree vartmp
[POWI_TABLE_SIZE
];
687 type
= TREE_TYPE (lhs
);
688 n
= abs (TREE_INT_CST_LOW (rhs
));
689 sgn
= tree_int_cst_sgn (rhs
);
691 if (((FLOAT_TYPE_P (type
) && !flag_unsafe_math_optimizations
) || optimize_size
)
692 && (n
> 2 || n
< -1))
698 se
->expr
= gfc_build_const (type
, integer_one_node
);
701 /* If rhs < 0 and lhs is an integer, the result is -1, 0 or 1. */
702 if ((sgn
== -1) && (TREE_CODE (type
) == INTEGER_TYPE
))
704 tmp
= build2 (EQ_EXPR
, boolean_type_node
, lhs
,
705 build_int_cst (TREE_TYPE (lhs
), -1));
706 cond
= build2 (EQ_EXPR
, boolean_type_node
, lhs
,
707 build_int_cst (TREE_TYPE (lhs
), 1));
710 result = (lhs == 1 || lhs == -1) ? 1 : 0. */
713 tmp
= build2 (TRUTH_OR_EXPR
, boolean_type_node
, tmp
, cond
);
714 se
->expr
= build3 (COND_EXPR
, type
, tmp
, build_int_cst (type
, 1),
715 build_int_cst (type
, 0));
719 result = (lhs == 1) ? 1 : (lhs == -1) ? -1 : 0. */
720 tmp
= build3 (COND_EXPR
, type
, tmp
, build_int_cst (type
, -1),
721 build_int_cst (type
, 0));
722 se
->expr
= build3 (COND_EXPR
, type
, cond
, build_int_cst (type
, 1), tmp
);
726 memset (vartmp
, 0, sizeof (vartmp
));
730 tmp
= gfc_build_const (type
, integer_one_node
);
731 vartmp
[1] = build2 (RDIV_EXPR
, type
, tmp
, vartmp
[1]);
734 se
->expr
= gfc_conv_powi (se
, n
, vartmp
);
740 /* Power op (**). Constant integer exponent has special handling. */
743 gfc_conv_power_op (gfc_se
* se
, gfc_expr
* expr
)
745 tree gfc_int4_type_node
;
752 gfc_init_se (&lse
, se
);
753 gfc_conv_expr_val (&lse
, expr
->value
.op
.op1
);
754 lse
.expr
= gfc_evaluate_now (lse
.expr
, &lse
.pre
);
755 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
757 gfc_init_se (&rse
, se
);
758 gfc_conv_expr_val (&rse
, expr
->value
.op
.op2
);
759 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
761 if (expr
->value
.op
.op2
->ts
.type
== BT_INTEGER
762 && expr
->value
.op
.op2
->expr_type
== EXPR_CONSTANT
)
763 if (gfc_conv_cst_int_power (se
, lse
.expr
, rse
.expr
))
766 gfc_int4_type_node
= gfc_get_int_type (4);
768 kind
= expr
->value
.op
.op1
->ts
.kind
;
769 switch (expr
->value
.op
.op2
->ts
.type
)
772 ikind
= expr
->value
.op
.op2
->ts
.kind
;
777 rse
.expr
= convert (gfc_int4_type_node
, rse
.expr
);
799 if (expr
->value
.op
.op1
->ts
.type
== BT_INTEGER
)
800 lse
.expr
= convert (gfc_int4_type_node
, lse
.expr
);
825 switch (expr
->value
.op
.op1
->ts
.type
)
828 if (kind
== 3) /* Case 16 was not handled properly above. */
830 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].integer
;
834 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].real
;
838 fndecl
= gfor_fndecl_math_powi
[kind
][ikind
].cmplx
;
850 fndecl
= built_in_decls
[BUILT_IN_POWF
];
853 fndecl
= built_in_decls
[BUILT_IN_POW
];
857 fndecl
= built_in_decls
[BUILT_IN_POWL
];
868 fndecl
= gfor_fndecl_math_cpowf
;
871 fndecl
= gfor_fndecl_math_cpow
;
874 fndecl
= gfor_fndecl_math_cpowl10
;
877 fndecl
= gfor_fndecl_math_cpowl16
;
889 se
->expr
= build_call_expr (fndecl
, 2, lse
.expr
, rse
.expr
);
893 /* Generate code to allocate a string temporary. */
896 gfc_conv_string_tmp (gfc_se
* se
, tree type
, tree len
)
901 gcc_assert (TREE_TYPE (len
) == gfc_charlen_type_node
);
903 if (gfc_can_put_var_on_stack (len
))
905 /* Create a temporary variable to hold the result. */
906 tmp
= fold_build2 (MINUS_EXPR
, gfc_charlen_type_node
, len
,
907 build_int_cst (gfc_charlen_type_node
, 1));
908 tmp
= build_range_type (gfc_array_index_type
, gfc_index_zero_node
, tmp
);
909 tmp
= build_array_type (gfc_character1_type_node
, tmp
);
910 var
= gfc_create_var (tmp
, "str");
911 var
= gfc_build_addr_expr (type
, var
);
915 /* Allocate a temporary to hold the result. */
916 var
= gfc_create_var (type
, "pstr");
917 tmp
= build_call_expr (gfor_fndecl_internal_malloc
, 1, len
);
918 tmp
= convert (type
, tmp
);
919 gfc_add_modify_expr (&se
->pre
, var
, tmp
);
921 /* Free the temporary afterwards. */
922 tmp
= convert (pvoid_type_node
, var
);
923 tmp
= build_call_expr (gfor_fndecl_internal_free
, 1, tmp
);
924 gfc_add_expr_to_block (&se
->post
, tmp
);
931 /* Handle a string concatenation operation. A temporary will be allocated to
935 gfc_conv_concat_op (gfc_se
* se
, gfc_expr
* expr
)
944 gcc_assert (expr
->value
.op
.op1
->ts
.type
== BT_CHARACTER
945 && expr
->value
.op
.op2
->ts
.type
== BT_CHARACTER
);
947 gfc_init_se (&lse
, se
);
948 gfc_conv_expr (&lse
, expr
->value
.op
.op1
);
949 gfc_conv_string_parameter (&lse
);
950 gfc_init_se (&rse
, se
);
951 gfc_conv_expr (&rse
, expr
->value
.op
.op2
);
952 gfc_conv_string_parameter (&rse
);
954 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
955 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
957 type
= gfc_get_character_type (expr
->ts
.kind
, expr
->ts
.cl
);
958 len
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
959 if (len
== NULL_TREE
)
961 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (lse
.string_length
),
962 lse
.string_length
, rse
.string_length
);
965 type
= build_pointer_type (type
);
967 var
= gfc_conv_string_tmp (se
, type
, len
);
969 /* Do the actual concatenation. */
970 tmp
= build_call_expr (gfor_fndecl_concat_string
, 6,
972 lse
.string_length
, lse
.expr
,
973 rse
.string_length
, rse
.expr
);
974 gfc_add_expr_to_block (&se
->pre
, tmp
);
976 /* Add the cleanup for the operands. */
977 gfc_add_block_to_block (&se
->pre
, &rse
.post
);
978 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
981 se
->string_length
= len
;
984 /* Translates an op expression. Common (binary) cases are handled by this
985 function, others are passed on. Recursion is used in either case.
986 We use the fact that (op1.ts == op2.ts) (except for the power
988 Operators need no special handling for scalarized expressions as long as
989 they call gfc_conv_simple_val to get their operands.
990 Character strings get special handling. */
993 gfc_conv_expr_op (gfc_se
* se
, gfc_expr
* expr
)
1005 switch (expr
->value
.op
.operator)
1007 case INTRINSIC_UPLUS
:
1008 case INTRINSIC_PARENTHESES
:
1009 gfc_conv_expr (se
, expr
->value
.op
.op1
);
1012 case INTRINSIC_UMINUS
:
1013 gfc_conv_unary_op (NEGATE_EXPR
, se
, expr
);
1017 gfc_conv_unary_op (TRUTH_NOT_EXPR
, se
, expr
);
1020 case INTRINSIC_PLUS
:
1024 case INTRINSIC_MINUS
:
1028 case INTRINSIC_TIMES
:
1032 case INTRINSIC_DIVIDE
:
1033 /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
1034 an integer, we must round towards zero, so we use a
1036 if (expr
->ts
.type
== BT_INTEGER
)
1037 code
= TRUNC_DIV_EXPR
;
1042 case INTRINSIC_POWER
:
1043 gfc_conv_power_op (se
, expr
);
1046 case INTRINSIC_CONCAT
:
1047 gfc_conv_concat_op (se
, expr
);
1051 code
= TRUTH_ANDIF_EXPR
;
1056 code
= TRUTH_ORIF_EXPR
;
1060 /* EQV and NEQV only work on logicals, but since we represent them
1061 as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
1070 case INTRINSIC_NEQV
:
1100 case INTRINSIC_USER
:
1101 case INTRINSIC_ASSIGN
:
1102 /* These should be converted into function calls by the frontend. */
1106 fatal_error ("Unknown intrinsic op");
1110 /* The only exception to this is **, which is handled separately anyway. */
1111 gcc_assert (expr
->value
.op
.op1
->ts
.type
== expr
->value
.op
.op2
->ts
.type
);
1113 if (checkstring
&& expr
->value
.op
.op1
->ts
.type
!= BT_CHARACTER
)
1117 gfc_init_se (&lse
, se
);
1118 gfc_conv_expr (&lse
, expr
->value
.op
.op1
);
1119 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
1122 gfc_init_se (&rse
, se
);
1123 gfc_conv_expr (&rse
, expr
->value
.op
.op2
);
1124 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
1128 gfc_conv_string_parameter (&lse
);
1129 gfc_conv_string_parameter (&rse
);
1131 lse
.expr
= gfc_build_compare_string (lse
.string_length
, lse
.expr
,
1132 rse
.string_length
, rse
.expr
);
1133 rse
.expr
= integer_zero_node
;
1134 gfc_add_block_to_block (&lse
.post
, &rse
.post
);
1137 type
= gfc_typenode_for_spec (&expr
->ts
);
1141 /* The result of logical ops is always boolean_type_node. */
1142 tmp
= fold_build2 (code
, type
, lse
.expr
, rse
.expr
);
1143 se
->expr
= convert (type
, tmp
);
1146 se
->expr
= fold_build2 (code
, type
, lse
.expr
, rse
.expr
);
1148 /* Add the post blocks. */
1149 gfc_add_block_to_block (&se
->post
, &rse
.post
);
1150 gfc_add_block_to_block (&se
->post
, &lse
.post
);
1153 /* If a string's length is one, we convert it to a single character. */
1156 gfc_to_single_character (tree len
, tree str
)
1158 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str
)));
1160 if (INTEGER_CST_P (len
) && TREE_INT_CST_LOW (len
) == 1
1161 && TREE_INT_CST_HIGH (len
) == 0)
1163 str
= fold_convert (pchar_type_node
, str
);
1164 return build_fold_indirect_ref (str
);
1170 /* Compare two strings. If they are all single characters, the result is the
1171 subtraction of them. Otherwise, we build a library call. */
1174 gfc_build_compare_string (tree len1
, tree str1
, tree len2
, tree str2
)
1181 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str1
)));
1182 gcc_assert (POINTER_TYPE_P (TREE_TYPE (str2
)));
1184 type
= gfc_get_int_type (gfc_default_integer_kind
);
1186 sc1
= gfc_to_single_character (len1
, str1
);
1187 sc2
= gfc_to_single_character (len2
, str2
);
1189 /* Deal with single character specially. */
1190 if (sc1
!= NULL_TREE
&& sc2
!= NULL_TREE
)
1192 sc1
= fold_convert (type
, sc1
);
1193 sc2
= fold_convert (type
, sc2
);
1194 tmp
= fold_build2 (MINUS_EXPR
, type
, sc1
, sc2
);
1197 /* Build a call for the comparison. */
1198 tmp
= build_call_expr (gfor_fndecl_compare_string
, 4,
1199 len1
, str1
, len2
, str2
);
1204 gfc_conv_function_val (gfc_se
* se
, gfc_symbol
* sym
)
1208 if (sym
->attr
.dummy
)
1210 tmp
= gfc_get_symbol_decl (sym
);
1211 gcc_assert (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
1212 && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) == FUNCTION_TYPE
);
1216 if (!sym
->backend_decl
)
1217 sym
->backend_decl
= gfc_get_extern_function_decl (sym
);
1219 tmp
= sym
->backend_decl
;
1220 if (sym
->attr
.cray_pointee
)
1221 tmp
= convert (build_pointer_type (TREE_TYPE (tmp
)),
1222 gfc_get_symbol_decl (sym
->cp_pointer
));
1223 if (!POINTER_TYPE_P (TREE_TYPE (tmp
)))
1225 gcc_assert (TREE_CODE (tmp
) == FUNCTION_DECL
);
1226 tmp
= build_fold_addr_expr (tmp
);
1233 /* Translate the call for an elemental subroutine call used in an operator
1234 assignment. This is a simplified version of gfc_conv_function_call. */
1237 gfc_conv_operator_assign (gfc_se
*lse
, gfc_se
*rse
, gfc_symbol
*sym
)
1244 /* Only elemental subroutines with two arguments. */
1245 gcc_assert (sym
->attr
.elemental
&& sym
->attr
.subroutine
);
1246 gcc_assert (sym
->formal
->next
->next
== NULL
);
1248 gfc_init_block (&block
);
1250 gfc_add_block_to_block (&block
, &lse
->pre
);
1251 gfc_add_block_to_block (&block
, &rse
->pre
);
1253 /* Build the argument list for the call, including hidden string lengths. */
1254 args
= gfc_chainon_list (NULL_TREE
, build_fold_addr_expr (lse
->expr
));
1255 args
= gfc_chainon_list (args
, build_fold_addr_expr (rse
->expr
));
1256 if (lse
->string_length
!= NULL_TREE
)
1257 args
= gfc_chainon_list (args
, lse
->string_length
);
1258 if (rse
->string_length
!= NULL_TREE
)
1259 args
= gfc_chainon_list (args
, rse
->string_length
);
1261 /* Build the function call. */
1262 gfc_init_se (&se
, NULL
);
1263 gfc_conv_function_val (&se
, sym
);
1264 tmp
= TREE_TYPE (TREE_TYPE (TREE_TYPE (se
.expr
)));
1265 tmp
= build_call_list (tmp
, se
.expr
, args
);
1266 gfc_add_expr_to_block (&block
, tmp
);
1268 gfc_add_block_to_block (&block
, &lse
->post
);
1269 gfc_add_block_to_block (&block
, &rse
->post
);
1271 return gfc_finish_block (&block
);
1275 /* Initialize MAPPING. */
1278 gfc_init_interface_mapping (gfc_interface_mapping
* mapping
)
1280 mapping
->syms
= NULL
;
1281 mapping
->charlens
= NULL
;
1285 /* Free all memory held by MAPPING (but not MAPPING itself). */
1288 gfc_free_interface_mapping (gfc_interface_mapping
* mapping
)
1290 gfc_interface_sym_mapping
*sym
;
1291 gfc_interface_sym_mapping
*nextsym
;
1293 gfc_charlen
*nextcl
;
1295 for (sym
= mapping
->syms
; sym
; sym
= nextsym
)
1297 nextsym
= sym
->next
;
1298 gfc_free_symbol (sym
->new->n
.sym
);
1299 gfc_free (sym
->new);
1302 for (cl
= mapping
->charlens
; cl
; cl
= nextcl
)
1305 gfc_free_expr (cl
->length
);
1311 /* Return a copy of gfc_charlen CL. Add the returned structure to
1312 MAPPING so that it will be freed by gfc_free_interface_mapping. */
1314 static gfc_charlen
*
1315 gfc_get_interface_mapping_charlen (gfc_interface_mapping
* mapping
,
1320 new = gfc_get_charlen ();
1321 new->next
= mapping
->charlens
;
1322 new->length
= gfc_copy_expr (cl
->length
);
1324 mapping
->charlens
= new;
1329 /* A subroutine of gfc_add_interface_mapping. Return a descriptorless
1330 array variable that can be used as the actual argument for dummy
1331 argument SYM. Add any initialization code to BLOCK. PACKED is as
1332 for gfc_get_nodesc_array_type and DATA points to the first element
1333 in the passed array. */
1336 gfc_get_interface_mapping_array (stmtblock_t
* block
, gfc_symbol
* sym
,
1337 int packed
, tree data
)
1342 type
= gfc_typenode_for_spec (&sym
->ts
);
1343 type
= gfc_get_nodesc_array_type (type
, sym
->as
, packed
);
1345 var
= gfc_create_var (type
, "ifm");
1346 gfc_add_modify_expr (block
, var
, fold_convert (type
, data
));
1352 /* A subroutine of gfc_add_interface_mapping. Set the stride, upper bounds
1353 and offset of descriptorless array type TYPE given that it has the same
1354 size as DESC. Add any set-up code to BLOCK. */
1357 gfc_set_interface_mapping_bounds (stmtblock_t
* block
, tree type
, tree desc
)
1364 offset
= gfc_index_zero_node
;
1365 for (n
= 0; n
< GFC_TYPE_ARRAY_RANK (type
); n
++)
1367 dim
= gfc_rank_cst
[n
];
1368 GFC_TYPE_ARRAY_STRIDE (type
, n
) = gfc_conv_array_stride (desc
, n
);
1369 if (GFC_TYPE_ARRAY_LBOUND (type
, n
) == NULL_TREE
)
1371 GFC_TYPE_ARRAY_LBOUND (type
, n
)
1372 = gfc_conv_descriptor_lbound (desc
, dim
);
1373 GFC_TYPE_ARRAY_UBOUND (type
, n
)
1374 = gfc_conv_descriptor_ubound (desc
, dim
);
1376 else if (GFC_TYPE_ARRAY_UBOUND (type
, n
) == NULL_TREE
)
1378 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1379 gfc_conv_descriptor_ubound (desc
, dim
),
1380 gfc_conv_descriptor_lbound (desc
, dim
));
1381 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1382 GFC_TYPE_ARRAY_LBOUND (type
, n
),
1384 tmp
= gfc_evaluate_now (tmp
, block
);
1385 GFC_TYPE_ARRAY_UBOUND (type
, n
) = tmp
;
1387 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
1388 GFC_TYPE_ARRAY_LBOUND (type
, n
),
1389 GFC_TYPE_ARRAY_STRIDE (type
, n
));
1390 offset
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp
);
1392 offset
= gfc_evaluate_now (offset
, block
);
1393 GFC_TYPE_ARRAY_OFFSET (type
) = offset
;
1397 /* Extend MAPPING so that it maps dummy argument SYM to the value stored
1398 in SE. The caller may still use se->expr and se->string_length after
1399 calling this function. */
1402 gfc_add_interface_mapping (gfc_interface_mapping
* mapping
,
1403 gfc_symbol
* sym
, gfc_se
* se
)
1405 gfc_interface_sym_mapping
*sm
;
1409 gfc_symbol
*new_sym
;
1411 gfc_symtree
*new_symtree
;
1413 /* Create a new symbol to represent the actual argument. */
1414 new_sym
= gfc_new_symbol (sym
->name
, NULL
);
1415 new_sym
->ts
= sym
->ts
;
1416 new_sym
->attr
.referenced
= 1;
1417 new_sym
->attr
.dimension
= sym
->attr
.dimension
;
1418 new_sym
->attr
.pointer
= sym
->attr
.pointer
;
1419 new_sym
->attr
.allocatable
= sym
->attr
.allocatable
;
1420 new_sym
->attr
.flavor
= sym
->attr
.flavor
;
1422 /* Create a fake symtree for it. */
1424 new_symtree
= gfc_new_symtree (&root
, sym
->name
);
1425 new_symtree
->n
.sym
= new_sym
;
1426 gcc_assert (new_symtree
== root
);
1428 /* Create a dummy->actual mapping. */
1429 sm
= gfc_getmem (sizeof (*sm
));
1430 sm
->next
= mapping
->syms
;
1432 sm
->new = new_symtree
;
1435 /* Stabilize the argument's value. */
1436 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
1438 if (sym
->ts
.type
== BT_CHARACTER
)
1440 /* Create a copy of the dummy argument's length. */
1441 new_sym
->ts
.cl
= gfc_get_interface_mapping_charlen (mapping
, sym
->ts
.cl
);
1443 /* If the length is specified as "*", record the length that
1444 the caller is passing. We should use the callee's length
1445 in all other cases. */
1446 if (!new_sym
->ts
.cl
->length
)
1448 se
->string_length
= gfc_evaluate_now (se
->string_length
, &se
->pre
);
1449 new_sym
->ts
.cl
->backend_decl
= se
->string_length
;
1453 /* Use the passed value as-is if the argument is a function. */
1454 if (sym
->attr
.flavor
== FL_PROCEDURE
)
1457 /* If the argument is either a string or a pointer to a string,
1458 convert it to a boundless character type. */
1459 else if (!sym
->attr
.dimension
&& sym
->ts
.type
== BT_CHARACTER
)
1461 tmp
= gfc_get_character_type_len (sym
->ts
.kind
, NULL
);
1462 tmp
= build_pointer_type (tmp
);
1463 if (sym
->attr
.pointer
)
1464 value
= build_fold_indirect_ref (se
->expr
);
1467 value
= fold_convert (tmp
, value
);
1470 /* If the argument is a scalar, a pointer to an array or an allocatable,
1472 else if (!sym
->attr
.dimension
|| sym
->attr
.pointer
|| sym
->attr
.allocatable
)
1473 value
= build_fold_indirect_ref (se
->expr
);
1475 /* For character(*), use the actual argument's descriptor. */
1476 else if (sym
->ts
.type
== BT_CHARACTER
&& !new_sym
->ts
.cl
->length
)
1477 value
= build_fold_indirect_ref (se
->expr
);
1479 /* If the argument is an array descriptor, use it to determine
1480 information about the actual argument's shape. */
1481 else if (POINTER_TYPE_P (TREE_TYPE (se
->expr
))
1482 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (se
->expr
))))
1484 /* Get the actual argument's descriptor. */
1485 desc
= build_fold_indirect_ref (se
->expr
);
1487 /* Create the replacement variable. */
1488 tmp
= gfc_conv_descriptor_data_get (desc
);
1489 value
= gfc_get_interface_mapping_array (&se
->pre
, sym
, 0, tmp
);
1491 /* Use DESC to work out the upper bounds, strides and offset. */
1492 gfc_set_interface_mapping_bounds (&se
->pre
, TREE_TYPE (value
), desc
);
1495 /* Otherwise we have a packed array. */
1496 value
= gfc_get_interface_mapping_array (&se
->pre
, sym
, 2, se
->expr
);
1498 new_sym
->backend_decl
= value
;
1502 /* Called once all dummy argument mappings have been added to MAPPING,
1503 but before the mapping is used to evaluate expressions. Pre-evaluate
1504 the length of each argument, adding any initialization code to PRE and
1505 any finalization code to POST. */
1508 gfc_finish_interface_mapping (gfc_interface_mapping
* mapping
,
1509 stmtblock_t
* pre
, stmtblock_t
* post
)
1511 gfc_interface_sym_mapping
*sym
;
1515 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
1516 if (sym
->new->n
.sym
->ts
.type
== BT_CHARACTER
1517 && !sym
->new->n
.sym
->ts
.cl
->backend_decl
)
1519 expr
= sym
->new->n
.sym
->ts
.cl
->length
;
1520 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
1521 gfc_init_se (&se
, NULL
);
1522 gfc_conv_expr (&se
, expr
);
1524 se
.expr
= gfc_evaluate_now (se
.expr
, &se
.pre
);
1525 gfc_add_block_to_block (pre
, &se
.pre
);
1526 gfc_add_block_to_block (post
, &se
.post
);
1528 sym
->new->n
.sym
->ts
.cl
->backend_decl
= se
.expr
;
1533 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1537 gfc_apply_interface_mapping_to_cons (gfc_interface_mapping
* mapping
,
1538 gfc_constructor
* c
)
1540 for (; c
; c
= c
->next
)
1542 gfc_apply_interface_mapping_to_expr (mapping
, c
->expr
);
1545 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->start
);
1546 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->end
);
1547 gfc_apply_interface_mapping_to_expr (mapping
, c
->iterator
->step
);
1553 /* Like gfc_apply_interface_mapping_to_expr, but applied to
1557 gfc_apply_interface_mapping_to_ref (gfc_interface_mapping
* mapping
,
1562 for (; ref
; ref
= ref
->next
)
1566 for (n
= 0; n
< ref
->u
.ar
.dimen
; n
++)
1568 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.start
[n
]);
1569 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.end
[n
]);
1570 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.stride
[n
]);
1572 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ar
.offset
);
1579 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ss
.start
);
1580 gfc_apply_interface_mapping_to_expr (mapping
, ref
->u
.ss
.end
);
1586 /* EXPR is a copy of an expression that appeared in the interface
1587 associated with MAPPING. Walk it recursively looking for references to
1588 dummy arguments that MAPPING maps to actual arguments. Replace each such
1589 reference with a reference to the associated actual argument. */
1592 gfc_apply_interface_mapping_to_expr (gfc_interface_mapping
* mapping
,
1595 gfc_interface_sym_mapping
*sym
;
1596 gfc_actual_arglist
*actual
;
1601 /* Copying an expression does not copy its length, so do that here. */
1602 if (expr
->ts
.type
== BT_CHARACTER
&& expr
->ts
.cl
)
1604 expr
->ts
.cl
= gfc_get_interface_mapping_charlen (mapping
, expr
->ts
.cl
);
1605 gfc_apply_interface_mapping_to_expr (mapping
, expr
->ts
.cl
->length
);
1608 /* Apply the mapping to any references. */
1609 gfc_apply_interface_mapping_to_ref (mapping
, expr
->ref
);
1611 /* ...and to the expression's symbol, if it has one. */
1613 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
1614 if (sym
->old
== expr
->symtree
->n
.sym
)
1615 expr
->symtree
= sym
->new;
1617 /* ...and to subexpressions in expr->value. */
1618 switch (expr
->expr_type
)
1623 case EXPR_SUBSTRING
:
1627 gfc_apply_interface_mapping_to_expr (mapping
, expr
->value
.op
.op1
);
1628 gfc_apply_interface_mapping_to_expr (mapping
, expr
->value
.op
.op2
);
1632 for (sym
= mapping
->syms
; sym
; sym
= sym
->next
)
1633 if (sym
->old
== expr
->value
.function
.esym
)
1634 expr
->value
.function
.esym
= sym
->new->n
.sym
;
1636 for (actual
= expr
->value
.function
.actual
; actual
; actual
= actual
->next
)
1637 gfc_apply_interface_mapping_to_expr (mapping
, actual
->expr
);
1641 case EXPR_STRUCTURE
:
1642 gfc_apply_interface_mapping_to_cons (mapping
, expr
->value
.constructor
);
1648 /* Evaluate interface expression EXPR using MAPPING. Store the result
1652 gfc_apply_interface_mapping (gfc_interface_mapping
* mapping
,
1653 gfc_se
* se
, gfc_expr
* expr
)
1655 expr
= gfc_copy_expr (expr
);
1656 gfc_apply_interface_mapping_to_expr (mapping
, expr
);
1657 gfc_conv_expr (se
, expr
);
1658 se
->expr
= gfc_evaluate_now (se
->expr
, &se
->pre
);
1659 gfc_free_expr (expr
);
1662 /* Returns a reference to a temporary array into which a component of
1663 an actual argument derived type array is copied and then returned
1664 after the function call.
1665 TODO Get rid of this kludge, when array descriptors are capable of
1666 handling arrays with a bigger stride in bytes than size. */
1669 gfc_conv_aliased_arg (gfc_se
* parmse
, gfc_expr
* expr
,
1670 int g77
, sym_intent intent
)
1686 gcc_assert (expr
->expr_type
== EXPR_VARIABLE
);
1688 gfc_init_se (&lse
, NULL
);
1689 gfc_init_se (&rse
, NULL
);
1691 /* Walk the argument expression. */
1692 rss
= gfc_walk_expr (expr
);
1694 gcc_assert (rss
!= gfc_ss_terminator
);
1696 /* Initialize the scalarizer. */
1697 gfc_init_loopinfo (&loop
);
1698 gfc_add_ss_to_loop (&loop
, rss
);
1700 /* Calculate the bounds of the scalarization. */
1701 gfc_conv_ss_startstride (&loop
);
1703 /* Build an ss for the temporary. */
1704 base_type
= gfc_typenode_for_spec (&expr
->ts
);
1705 if (GFC_ARRAY_TYPE_P (base_type
)
1706 || GFC_DESCRIPTOR_TYPE_P (base_type
))
1707 base_type
= gfc_get_element_type (base_type
);
1709 loop
.temp_ss
= gfc_get_ss ();;
1710 loop
.temp_ss
->type
= GFC_SS_TEMP
;
1711 loop
.temp_ss
->data
.temp
.type
= base_type
;
1713 if (expr
->ts
.type
== BT_CHARACTER
)
1715 gfc_ref
*char_ref
= expr
->ref
;
1717 for (; char_ref
; char_ref
= char_ref
->next
)
1718 if (char_ref
->type
== REF_SUBSTRING
)
1722 expr
->ts
.cl
= gfc_get_charlen ();
1723 expr
->ts
.cl
->next
= char_ref
->u
.ss
.length
->next
;
1724 char_ref
->u
.ss
.length
->next
= expr
->ts
.cl
;
1726 gfc_init_se (&tmp_se
, NULL
);
1727 gfc_conv_expr_type (&tmp_se
, char_ref
->u
.ss
.end
,
1728 gfc_array_index_type
);
1729 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1730 tmp_se
.expr
, gfc_index_one_node
);
1731 tmp
= gfc_evaluate_now (tmp
, &parmse
->pre
);
1732 gfc_init_se (&tmp_se
, NULL
);
1733 gfc_conv_expr_type (&tmp_se
, char_ref
->u
.ss
.start
,
1734 gfc_array_index_type
);
1735 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1737 expr
->ts
.cl
->backend_decl
= tmp
;
1741 loop
.temp_ss
->data
.temp
.type
1742 = gfc_typenode_for_spec (&expr
->ts
);
1743 loop
.temp_ss
->string_length
= expr
->ts
.cl
->backend_decl
;
1746 loop
.temp_ss
->data
.temp
.dimen
= loop
.dimen
;
1747 loop
.temp_ss
->next
= gfc_ss_terminator
;
1749 /* Associate the SS with the loop. */
1750 gfc_add_ss_to_loop (&loop
, loop
.temp_ss
);
1752 /* Setup the scalarizing loops. */
1753 gfc_conv_loop_setup (&loop
);
1755 /* Pass the temporary descriptor back to the caller. */
1756 info
= &loop
.temp_ss
->data
.info
;
1757 parmse
->expr
= info
->descriptor
;
1759 /* Setup the gfc_se structures. */
1760 gfc_copy_loopinfo_to_se (&lse
, &loop
);
1761 gfc_copy_loopinfo_to_se (&rse
, &loop
);
1764 lse
.ss
= loop
.temp_ss
;
1765 gfc_mark_ss_chain_used (rss
, 1);
1766 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
1768 /* Start the scalarized loop body. */
1769 gfc_start_scalarized_body (&loop
, &body
);
1771 /* Translate the expression. */
1772 gfc_conv_expr (&rse
, expr
);
1774 gfc_conv_tmp_array_ref (&lse
);
1775 gfc_advance_se_ss_chain (&lse
);
1777 if (intent
!= INTENT_OUT
)
1779 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, true, false);
1780 gfc_add_expr_to_block (&body
, tmp
);
1781 gcc_assert (rse
.ss
== gfc_ss_terminator
);
1782 gfc_trans_scalarizing_loops (&loop
, &body
);
1786 /* Make sure that the temporary declaration survives by merging
1787 all the loop declarations into the current context. */
1788 for (n
= 0; n
< loop
.dimen
; n
++)
1790 gfc_merge_block_scope (&body
);
1791 body
= loop
.code
[loop
.order
[n
]];
1793 gfc_merge_block_scope (&body
);
1796 /* Add the post block after the second loop, so that any
1797 freeing of allocated memory is done at the right time. */
1798 gfc_add_block_to_block (&parmse
->pre
, &loop
.pre
);
1800 /**********Copy the temporary back again.*********/
1802 gfc_init_se (&lse
, NULL
);
1803 gfc_init_se (&rse
, NULL
);
1805 /* Walk the argument expression. */
1806 lss
= gfc_walk_expr (expr
);
1807 rse
.ss
= loop
.temp_ss
;
1810 /* Initialize the scalarizer. */
1811 gfc_init_loopinfo (&loop2
);
1812 gfc_add_ss_to_loop (&loop2
, lss
);
1814 /* Calculate the bounds of the scalarization. */
1815 gfc_conv_ss_startstride (&loop2
);
1817 /* Setup the scalarizing loops. */
1818 gfc_conv_loop_setup (&loop2
);
1820 gfc_copy_loopinfo_to_se (&lse
, &loop2
);
1821 gfc_copy_loopinfo_to_se (&rse
, &loop2
);
1823 gfc_mark_ss_chain_used (lss
, 1);
1824 gfc_mark_ss_chain_used (loop
.temp_ss
, 1);
1826 /* Declare the variable to hold the temporary offset and start the
1827 scalarized loop body. */
1828 offset
= gfc_create_var (gfc_array_index_type
, NULL
);
1829 gfc_start_scalarized_body (&loop2
, &body
);
1831 /* Build the offsets for the temporary from the loop variables. The
1832 temporary array has lbounds of zero and strides of one in all
1833 dimensions, so this is very simple. The offset is only computed
1834 outside the innermost loop, so the overall transfer could be
1835 optimized further. */
1836 info
= &rse
.ss
->data
.info
;
1838 tmp_index
= gfc_index_zero_node
;
1839 for (n
= info
->dimen
- 1; n
> 0; n
--)
1842 tmp
= rse
.loop
->loopvar
[n
];
1843 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1844 tmp
, rse
.loop
->from
[n
]);
1845 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1848 tmp_str
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1849 rse
.loop
->to
[n
-1], rse
.loop
->from
[n
-1]);
1850 tmp_str
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1851 tmp_str
, gfc_index_one_node
);
1853 tmp_index
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
1857 tmp_index
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
1858 tmp_index
, rse
.loop
->from
[0]);
1859 gfc_add_modify_expr (&rse
.loop
->code
[0], offset
, tmp_index
);
1861 tmp_index
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1862 rse
.loop
->loopvar
[0], offset
);
1864 /* Now use the offset for the reference. */
1865 tmp
= build_fold_indirect_ref (info
->data
);
1866 rse
.expr
= gfc_build_array_ref (tmp
, tmp_index
);
1868 if (expr
->ts
.type
== BT_CHARACTER
)
1869 rse
.string_length
= expr
->ts
.cl
->backend_decl
;
1871 gfc_conv_expr (&lse
, expr
);
1873 gcc_assert (lse
.ss
== gfc_ss_terminator
);
1875 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, false, false);
1876 gfc_add_expr_to_block (&body
, tmp
);
1878 /* Generate the copying loops. */
1879 gfc_trans_scalarizing_loops (&loop2
, &body
);
1881 /* Wrap the whole thing up by adding the second loop to the post-block
1882 and following it by the post-block of the first loop. In this way,
1883 if the temporary needs freeing, it is done after use! */
1884 if (intent
!= INTENT_IN
)
1886 gfc_add_block_to_block (&parmse
->post
, &loop2
.pre
);
1887 gfc_add_block_to_block (&parmse
->post
, &loop2
.post
);
1890 gfc_add_block_to_block (&parmse
->post
, &loop
.post
);
1892 gfc_cleanup_loop (&loop
);
1893 gfc_cleanup_loop (&loop2
);
1895 /* Pass the string length to the argument expression. */
1896 if (expr
->ts
.type
== BT_CHARACTER
)
1897 parmse
->string_length
= expr
->ts
.cl
->backend_decl
;
1899 /* We want either the address for the data or the address of the descriptor,
1900 depending on the mode of passing array arguments. */
1902 parmse
->expr
= gfc_conv_descriptor_data_get (parmse
->expr
);
1904 parmse
->expr
= build_fold_addr_expr (parmse
->expr
);
1909 /* Is true if an array reference is followed by a component or substring
1913 is_aliased_array (gfc_expr
* e
)
1919 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
1921 if (ref
->type
== REF_ARRAY
1922 && ref
->u
.ar
.type
!= AR_ELEMENT
)
1926 && ref
->type
!= REF_ARRAY
)
1932 /* Generate the code for argument list functions. */
1935 conv_arglist_function (gfc_se
*se
, gfc_expr
*expr
, const char *name
)
1937 tree type
= NULL_TREE
;
1938 /* Pass by value for g77 %VAL(arg), pass the address
1939 indirectly for %LOC, else by reference. Thus %REF
1940 is a "do-nothing" and %LOC is the same as an F95
1942 if (strncmp (name
, "%VAL", 4) == 0)
1944 gfc_conv_expr (se
, expr
);
1945 /* %VAL converts argument to default kind. */
1946 switch (expr
->ts
.type
)
1949 type
= gfc_get_real_type (gfc_default_real_kind
);
1950 se
->expr
= fold_convert (type
, se
->expr
);
1953 type
= gfc_get_complex_type (gfc_default_complex_kind
);
1954 se
->expr
= fold_convert (type
, se
->expr
);
1957 type
= gfc_get_int_type (gfc_default_integer_kind
);
1958 se
->expr
= fold_convert (type
, se
->expr
);
1961 type
= gfc_get_logical_type (gfc_default_logical_kind
);
1962 se
->expr
= fold_convert (type
, se
->expr
);
1964 /* This should have been resolved away. */
1965 case BT_UNKNOWN
: case BT_CHARACTER
: case BT_DERIVED
:
1966 case BT_PROCEDURE
: case BT_HOLLERITH
:
1967 gfc_internal_error ("Bad type in conv_arglist_function");
1971 else if (strncmp (name
, "%LOC", 4) == 0)
1973 gfc_conv_expr_reference (se
, expr
);
1974 se
->expr
= gfc_build_addr_expr (NULL
, se
->expr
);
1976 else if (strncmp (name
, "%REF", 4) == 0)
1977 gfc_conv_expr_reference (se
, expr
);
1979 gfc_error ("Unknown argument list function at %L", &expr
->where
);
1983 /* Generate code for a procedure call. Note can return se->post != NULL.
1984 If se->direct_byref is set then se->expr contains the return parameter.
1985 Return nonzero, if the call has alternate specifiers. */
1988 gfc_conv_function_call (gfc_se
* se
, gfc_symbol
* sym
,
1989 gfc_actual_arglist
* arg
, tree append_args
)
1991 gfc_interface_mapping mapping
;
2005 gfc_formal_arglist
*formal
;
2006 int has_alternate_specifier
= 0;
2007 bool need_interface_mapping
;
2014 enum {MISSING
= 0, ELEMENTAL
, SCALAR
, SCALAR_POINTER
, ARRAY
};
2016 arglist
= NULL_TREE
;
2017 retargs
= NULL_TREE
;
2018 stringargs
= NULL_TREE
;
2024 if (!sym
->attr
.elemental
)
2026 gcc_assert (se
->ss
->type
== GFC_SS_FUNCTION
);
2027 if (se
->ss
->useflags
)
2029 gcc_assert (gfc_return_by_reference (sym
)
2030 && sym
->result
->attr
.dimension
);
2031 gcc_assert (se
->loop
!= NULL
);
2033 /* Access the previously obtained result. */
2034 gfc_conv_tmp_array_ref (se
);
2035 gfc_advance_se_ss_chain (se
);
2039 info
= &se
->ss
->data
.info
;
2044 gfc_init_block (&post
);
2045 gfc_init_interface_mapping (&mapping
);
2046 need_interface_mapping
= ((sym
->ts
.type
== BT_CHARACTER
2047 && sym
->ts
.cl
->length
2048 && sym
->ts
.cl
->length
->expr_type
2050 || sym
->attr
.dimension
);
2051 formal
= sym
->formal
;
2052 /* Evaluate the arguments. */
2053 for (; arg
!= NULL
; arg
= arg
->next
, formal
= formal
? formal
->next
: NULL
)
2056 fsym
= formal
? formal
->sym
: NULL
;
2057 parm_kind
= MISSING
;
2061 if (se
->ignore_optional
)
2063 /* Some intrinsics have already been resolved to the correct
2067 else if (arg
->label
)
2069 has_alternate_specifier
= 1;
2074 /* Pass a NULL pointer for an absent arg. */
2075 gfc_init_se (&parmse
, NULL
);
2076 parmse
.expr
= null_pointer_node
;
2077 if (arg
->missing_arg_type
== BT_CHARACTER
)
2078 parmse
.string_length
= build_int_cst (gfc_charlen_type_node
, 0);
2081 else if (se
->ss
&& se
->ss
->useflags
)
2083 /* An elemental function inside a scalarized loop. */
2084 gfc_init_se (&parmse
, se
);
2085 gfc_conv_expr_reference (&parmse
, e
);
2086 parm_kind
= ELEMENTAL
;
2090 /* A scalar or transformational function. */
2091 gfc_init_se (&parmse
, NULL
);
2092 argss
= gfc_walk_expr (e
);
2094 if (argss
== gfc_ss_terminator
)
2097 if (fsym
&& fsym
->attr
.value
)
2099 gfc_conv_expr (&parmse
, e
);
2101 else if (arg
->name
&& arg
->name
[0] == '%')
2102 /* Argument list functions %VAL, %LOC and %REF are signalled
2103 through arg->name. */
2104 conv_arglist_function (&parmse
, arg
->expr
, arg
->name
);
2107 gfc_conv_expr_reference (&parmse
, e
);
2108 if (fsym
&& fsym
->attr
.pointer
2109 && e
->expr_type
!= EXPR_NULL
)
2111 /* Scalar pointer dummy args require an extra level of
2112 indirection. The null pointer already contains
2113 this level of indirection. */
2114 parm_kind
= SCALAR_POINTER
;
2115 parmse
.expr
= build_fold_addr_expr (parmse
.expr
);
2121 /* If the procedure requires an explicit interface, the actual
2122 argument is passed according to the corresponding formal
2123 argument. If the corresponding formal argument is a POINTER,
2124 ALLOCATABLE or assumed shape, we do not use g77's calling
2125 convention, and pass the address of the array descriptor
2126 instead. Otherwise we use g77's calling convention. */
2129 && !(fsym
->attr
.pointer
|| fsym
->attr
.allocatable
)
2130 && fsym
->as
->type
!= AS_ASSUMED_SHAPE
;
2131 f
= f
|| !sym
->attr
.always_explicit
;
2133 if (e
->expr_type
== EXPR_VARIABLE
2134 && is_aliased_array (e
))
2135 /* The actual argument is a component reference to an
2136 array of derived types. In this case, the argument
2137 is converted to a temporary, which is passed and then
2138 written back after the procedure call. */
2139 gfc_conv_aliased_arg (&parmse
, e
, f
,
2140 fsym
? fsym
->attr
.intent
: INTENT_INOUT
);
2142 gfc_conv_array_parameter (&parmse
, e
, argss
, f
);
2144 /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
2145 allocated on entry, it must be deallocated. */
2146 if (fsym
&& fsym
->attr
.allocatable
2147 && fsym
->attr
.intent
== INTENT_OUT
)
2149 tmp
= build_fold_indirect_ref (parmse
.expr
);
2150 tmp
= gfc_trans_dealloc_allocated (tmp
);
2151 gfc_add_expr_to_block (&se
->pre
, tmp
);
2161 /* If an optional argument is itself an optional dummy
2162 argument, check its presence and substitute a null
2164 if (e
->expr_type
== EXPR_VARIABLE
2165 && e
->symtree
->n
.sym
->attr
.optional
2166 && fsym
->attr
.optional
)
2167 gfc_conv_missing_dummy (&parmse
, e
, fsym
->ts
);
2169 /* If an INTENT(OUT) dummy of derived type has a default
2170 initializer, it must be (re)initialized here. */
2171 if (fsym
->attr
.intent
== INTENT_OUT
2172 && fsym
->ts
.type
== BT_DERIVED
2175 gcc_assert (!fsym
->attr
.allocatable
);
2176 tmp
= gfc_trans_assignment (e
, fsym
->value
, false);
2177 gfc_add_expr_to_block (&se
->pre
, tmp
);
2180 /* Obtain the character length of an assumed character
2181 length procedure from the typespec. */
2182 if (fsym
->ts
.type
== BT_CHARACTER
2183 && parmse
.string_length
== NULL_TREE
2184 && e
->ts
.type
== BT_PROCEDURE
2185 && e
->symtree
->n
.sym
->ts
.type
== BT_CHARACTER
2186 && e
->symtree
->n
.sym
->ts
.cl
->length
!= NULL
)
2188 gfc_conv_const_charlen (e
->symtree
->n
.sym
->ts
.cl
);
2189 parmse
.string_length
2190 = e
->symtree
->n
.sym
->ts
.cl
->backend_decl
;
2194 if (need_interface_mapping
)
2195 gfc_add_interface_mapping (&mapping
, fsym
, &parmse
);
2198 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
2199 gfc_add_block_to_block (&post
, &parmse
.post
);
2201 /* Allocated allocatable components of derived types must be
2202 deallocated for INTENT(OUT) dummy arguments and non-variable
2203 scalars. Non-variable arrays are dealt with in trans-array.c
2204 (gfc_conv_array_parameter). */
2205 if (e
&& e
->ts
.type
== BT_DERIVED
2206 && e
->ts
.derived
->attr
.alloc_comp
2207 && ((formal
&& formal
->sym
->attr
.intent
== INTENT_OUT
)
2209 (e
->expr_type
!= EXPR_VARIABLE
&& !e
->rank
)))
2212 tmp
= build_fold_indirect_ref (parmse
.expr
);
2213 parm_rank
= e
->rank
;
2221 case (SCALAR_POINTER
):
2222 tmp
= build_fold_indirect_ref (tmp
);
2229 tmp
= gfc_deallocate_alloc_comp (e
->ts
.derived
, tmp
, parm_rank
);
2230 if (e
->expr_type
== EXPR_VARIABLE
&& e
->symtree
->n
.sym
->attr
.optional
)
2231 tmp
= build3_v (COND_EXPR
, gfc_conv_expr_present (e
->symtree
->n
.sym
),
2232 tmp
, build_empty_stmt ());
2234 if (e
->expr_type
!= EXPR_VARIABLE
)
2235 /* Don't deallocate non-variables until they have been used. */
2236 gfc_add_expr_to_block (&se
->post
, tmp
);
2239 gcc_assert (formal
&& formal
->sym
->attr
.intent
== INTENT_OUT
);
2240 gfc_add_expr_to_block (&se
->pre
, tmp
);
2244 /* Character strings are passed as two parameters, a length and a
2246 if (parmse
.string_length
!= NULL_TREE
)
2247 stringargs
= gfc_chainon_list (stringargs
, parmse
.string_length
);
2249 arglist
= gfc_chainon_list (arglist
, parmse
.expr
);
2251 gfc_finish_interface_mapping (&mapping
, &se
->pre
, &se
->post
);
2254 if (ts
.type
== BT_CHARACTER
)
2256 if (sym
->ts
.cl
->length
== NULL
)
2258 /* Assumed character length results are not allowed by 5.1.1.5 of the
2259 standard and are trapped in resolve.c; except in the case of SPREAD
2260 (and other intrinsics?) and dummy functions. In the case of SPREAD,
2261 we take the character length of the first argument for the result.
2262 For dummies, we have to look through the formal argument list for
2263 this function and use the character length found there.*/
2264 if (!sym
->attr
.dummy
)
2265 cl
.backend_decl
= TREE_VALUE (stringargs
);
2268 formal
= sym
->ns
->proc_name
->formal
;
2269 for (; formal
; formal
= formal
->next
)
2270 if (strcmp (formal
->sym
->name
, sym
->name
) == 0)
2271 cl
.backend_decl
= formal
->sym
->ts
.cl
->backend_decl
;
2276 /* Calculate the length of the returned string. */
2277 gfc_init_se (&parmse
, NULL
);
2278 if (need_interface_mapping
)
2279 gfc_apply_interface_mapping (&mapping
, &parmse
, sym
->ts
.cl
->length
);
2281 gfc_conv_expr (&parmse
, sym
->ts
.cl
->length
);
2282 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
2283 gfc_add_block_to_block (&se
->post
, &parmse
.post
);
2284 cl
.backend_decl
= fold_convert (gfc_charlen_type_node
, parmse
.expr
);
2287 /* Set up a charlen structure for it. */
2292 len
= cl
.backend_decl
;
2295 byref
= gfc_return_by_reference (sym
);
2298 if (se
->direct_byref
)
2299 retargs
= gfc_chainon_list (retargs
, se
->expr
);
2300 else if (sym
->result
->attr
.dimension
)
2302 gcc_assert (se
->loop
&& info
);
2304 /* Set the type of the array. */
2305 tmp
= gfc_typenode_for_spec (&ts
);
2306 info
->dimen
= se
->loop
->dimen
;
2308 /* Evaluate the bounds of the result, if known. */
2309 gfc_set_loop_bounds_from_array_spec (&mapping
, se
, sym
->result
->as
);
2311 /* Create a temporary to store the result. In case the function
2312 returns a pointer, the temporary will be a shallow copy and
2313 mustn't be deallocated. */
2314 callee_alloc
= sym
->attr
.allocatable
|| sym
->attr
.pointer
;
2315 gfc_trans_create_temp_array (&se
->pre
, &se
->post
, se
->loop
, info
, tmp
,
2316 false, !sym
->attr
.pointer
, callee_alloc
);
2318 /* Pass the temporary as the first argument. */
2319 tmp
= info
->descriptor
;
2320 tmp
= build_fold_addr_expr (tmp
);
2321 retargs
= gfc_chainon_list (retargs
, tmp
);
2323 else if (ts
.type
== BT_CHARACTER
)
2325 /* Pass the string length. */
2326 type
= gfc_get_character_type (ts
.kind
, ts
.cl
);
2327 type
= build_pointer_type (type
);
2329 /* Return an address to a char[0:len-1]* temporary for
2330 character pointers. */
2331 if (sym
->attr
.pointer
|| sym
->attr
.allocatable
)
2333 /* Build char[0:len-1] * pstr. */
2334 tmp
= fold_build2 (MINUS_EXPR
, gfc_charlen_type_node
, len
,
2335 build_int_cst (gfc_charlen_type_node
, 1));
2336 tmp
= build_range_type (gfc_array_index_type
,
2337 gfc_index_zero_node
, tmp
);
2338 tmp
= build_array_type (gfc_character1_type_node
, tmp
);
2339 var
= gfc_create_var (build_pointer_type (tmp
), "pstr");
2341 /* Provide an address expression for the function arguments. */
2342 var
= build_fold_addr_expr (var
);
2345 var
= gfc_conv_string_tmp (se
, type
, len
);
2347 retargs
= gfc_chainon_list (retargs
, var
);
2351 gcc_assert (gfc_option
.flag_f2c
&& ts
.type
== BT_COMPLEX
);
2353 type
= gfc_get_complex_type (ts
.kind
);
2354 var
= build_fold_addr_expr (gfc_create_var (type
, "cmplx"));
2355 retargs
= gfc_chainon_list (retargs
, var
);
2358 /* Add the string length to the argument list. */
2359 if (ts
.type
== BT_CHARACTER
)
2360 retargs
= gfc_chainon_list (retargs
, len
);
2362 gfc_free_interface_mapping (&mapping
);
2364 /* Add the return arguments. */
2365 arglist
= chainon (retargs
, arglist
);
2367 /* Add the hidden string length parameters to the arguments. */
2368 arglist
= chainon (arglist
, stringargs
);
2370 /* We may want to append extra arguments here. This is used e.g. for
2371 calls to libgfortran_matmul_??, which need extra information. */
2372 if (append_args
!= NULL_TREE
)
2373 arglist
= chainon (arglist
, append_args
);
2375 /* Generate the actual call. */
2376 gfc_conv_function_val (se
, sym
);
2377 /* If there are alternate return labels, function type should be
2378 integer. Can't modify the type in place though, since it can be shared
2379 with other functions. */
2380 if (has_alternate_specifier
2381 && TREE_TYPE (TREE_TYPE (TREE_TYPE (se
->expr
))) != integer_type_node
)
2383 gcc_assert (! sym
->attr
.dummy
);
2384 TREE_TYPE (sym
->backend_decl
)
2385 = build_function_type (integer_type_node
,
2386 TYPE_ARG_TYPES (TREE_TYPE (sym
->backend_decl
)));
2387 se
->expr
= build_fold_addr_expr (sym
->backend_decl
);
2390 fntype
= TREE_TYPE (TREE_TYPE (se
->expr
));
2391 se
->expr
= build_call_list (TREE_TYPE (fntype
), se
->expr
, arglist
);
2393 /* If we have a pointer function, but we don't want a pointer, e.g.
2396 where f is pointer valued, we have to dereference the result. */
2397 if (!se
->want_pointer
&& !byref
&& sym
->attr
.pointer
)
2398 se
->expr
= build_fold_indirect_ref (se
->expr
);
2400 /* f2c calling conventions require a scalar default real function to
2401 return a double precision result. Convert this back to default
2402 real. We only care about the cases that can happen in Fortran 77.
2404 if (gfc_option
.flag_f2c
&& sym
->ts
.type
== BT_REAL
2405 && sym
->ts
.kind
== gfc_default_real_kind
2406 && !sym
->attr
.always_explicit
)
2407 se
->expr
= fold_convert (gfc_get_real_type (sym
->ts
.kind
), se
->expr
);
2409 /* A pure function may still have side-effects - it may modify its
2411 TREE_SIDE_EFFECTS (se
->expr
) = 1;
2413 if (!sym
->attr
.pure
)
2414 TREE_SIDE_EFFECTS (se
->expr
) = 1;
2419 /* Add the function call to the pre chain. There is no expression. */
2420 gfc_add_expr_to_block (&se
->pre
, se
->expr
);
2421 se
->expr
= NULL_TREE
;
2423 if (!se
->direct_byref
)
2425 if (sym
->attr
.dimension
)
2427 if (flag_bounds_check
)
2429 /* Check the data pointer hasn't been modified. This would
2430 happen in a function returning a pointer. */
2431 tmp
= gfc_conv_descriptor_data_get (info
->descriptor
);
2432 tmp
= fold_build2 (NE_EXPR
, boolean_type_node
,
2434 gfc_trans_runtime_check (tmp
, gfc_msg_fault
, &se
->pre
, NULL
);
2436 se
->expr
= info
->descriptor
;
2437 /* Bundle in the string length. */
2438 se
->string_length
= len
;
2440 else if (sym
->ts
.type
== BT_CHARACTER
)
2442 /* Dereference for character pointer results. */
2443 if (sym
->attr
.pointer
|| sym
->attr
.allocatable
)
2444 se
->expr
= build_fold_indirect_ref (var
);
2448 se
->string_length
= len
;
2452 gcc_assert (sym
->ts
.type
== BT_COMPLEX
&& gfc_option
.flag_f2c
);
2453 se
->expr
= build_fold_indirect_ref (var
);
2458 /* Follow the function call with the argument post block. */
2460 gfc_add_block_to_block (&se
->pre
, &post
);
2462 gfc_add_block_to_block (&se
->post
, &post
);
2464 return has_alternate_specifier
;
2468 /* Generate code to copy a string. */
2471 gfc_trans_string_copy (stmtblock_t
* block
, tree dlength
, tree dest
,
2472 tree slength
, tree src
)
2474 tree tmp
, dlen
, slen
;
2482 stmtblock_t tempblock
;
2484 dlen
= fold_convert (size_type_node
, gfc_evaluate_now (dlength
, block
));
2485 slen
= fold_convert (size_type_node
, gfc_evaluate_now (slength
, block
));
2487 /* Deal with single character specially. */
2488 dsc
= gfc_to_single_character (dlen
, dest
);
2489 ssc
= gfc_to_single_character (slen
, src
);
2490 if (dsc
!= NULL_TREE
&& ssc
!= NULL_TREE
)
2492 gfc_add_modify_expr (block
, dsc
, ssc
);
2496 /* Do nothing if the destination length is zero. */
2497 cond
= fold_build2 (GT_EXPR
, boolean_type_node
, dlen
,
2498 build_int_cst (gfc_charlen_type_node
, 0));
2500 /* The following code was previously in _gfortran_copy_string:
2502 // The two strings may overlap so we use memmove.
2504 copy_string (GFC_INTEGER_4 destlen, char * dest,
2505 GFC_INTEGER_4 srclen, const char * src)
2507 if (srclen >= destlen)
2509 // This will truncate if too long.
2510 memmove (dest, src, destlen);
2514 memmove (dest, src, srclen);
2516 memset (&dest[srclen], ' ', destlen - srclen);
2520 We're now doing it here for better optimization, but the logic
2523 /* Truncate string if source is too long. */
2524 cond2
= fold_build2 (GE_EXPR
, boolean_type_node
, slen
, dlen
);
2525 tmp2
= build_call_expr (built_in_decls
[BUILT_IN_MEMMOVE
],
2526 3, dest
, src
, dlen
);
2528 /* Else copy and pad with spaces. */
2529 tmp3
= build_call_expr (built_in_decls
[BUILT_IN_MEMMOVE
],
2530 3, dest
, src
, slen
);
2532 tmp4
= fold_build2 (PLUS_EXPR
, pchar_type_node
, dest
,
2533 fold_convert (pchar_type_node
, slen
));
2534 tmp4
= build_call_expr (built_in_decls
[BUILT_IN_MEMSET
], 3,
2536 build_int_cst (gfc_get_int_type (gfc_c_int_kind
),
2537 lang_hooks
.to_target_charset (' ')),
2538 fold_build2 (MINUS_EXPR
, TREE_TYPE(dlen
),
2541 gfc_init_block (&tempblock
);
2542 gfc_add_expr_to_block (&tempblock
, tmp3
);
2543 gfc_add_expr_to_block (&tempblock
, tmp4
);
2544 tmp3
= gfc_finish_block (&tempblock
);
2546 /* The whole copy_string function is there. */
2547 tmp
= fold_build3 (COND_EXPR
, void_type_node
, cond2
, tmp2
, tmp3
);
2548 tmp
= fold_build3 (COND_EXPR
, void_type_node
, cond
, tmp
, build_empty_stmt ());
2549 gfc_add_expr_to_block (block
, tmp
);
2553 /* Translate a statement function.
2554 The value of a statement function reference is obtained by evaluating the
2555 expression using the values of the actual arguments for the values of the
2556 corresponding dummy arguments. */
2559 gfc_conv_statement_function (gfc_se
* se
, gfc_expr
* expr
)
2563 gfc_formal_arglist
*fargs
;
2564 gfc_actual_arglist
*args
;
2567 gfc_saved_var
*saved_vars
;
2573 sym
= expr
->symtree
->n
.sym
;
2574 args
= expr
->value
.function
.actual
;
2575 gfc_init_se (&lse
, NULL
);
2576 gfc_init_se (&rse
, NULL
);
2579 for (fargs
= sym
->formal
; fargs
; fargs
= fargs
->next
)
2581 saved_vars
= (gfc_saved_var
*)gfc_getmem (n
* sizeof (gfc_saved_var
));
2582 temp_vars
= (tree
*)gfc_getmem (n
* sizeof (tree
));
2584 for (fargs
= sym
->formal
, n
= 0; fargs
; fargs
= fargs
->next
, n
++)
2586 /* Each dummy shall be specified, explicitly or implicitly, to be
2588 gcc_assert (fargs
->sym
->attr
.dimension
== 0);
2591 /* Create a temporary to hold the value. */
2592 type
= gfc_typenode_for_spec (&fsym
->ts
);
2593 temp_vars
[n
] = gfc_create_var (type
, fsym
->name
);
2595 if (fsym
->ts
.type
== BT_CHARACTER
)
2597 /* Copy string arguments. */
2600 gcc_assert (fsym
->ts
.cl
&& fsym
->ts
.cl
->length
2601 && fsym
->ts
.cl
->length
->expr_type
== EXPR_CONSTANT
);
2603 arglen
= TYPE_MAX_VALUE (TYPE_DOMAIN (type
));
2604 tmp
= gfc_build_addr_expr (build_pointer_type (type
),
2607 gfc_conv_expr (&rse
, args
->expr
);
2608 gfc_conv_string_parameter (&rse
);
2609 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
2610 gfc_add_block_to_block (&se
->pre
, &rse
.pre
);
2612 gfc_trans_string_copy (&se
->pre
, arglen
, tmp
, rse
.string_length
,
2614 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
2615 gfc_add_block_to_block (&se
->pre
, &rse
.post
);
2619 /* For everything else, just evaluate the expression. */
2620 gfc_conv_expr (&lse
, args
->expr
);
2622 gfc_add_block_to_block (&se
->pre
, &lse
.pre
);
2623 gfc_add_modify_expr (&se
->pre
, temp_vars
[n
], lse
.expr
);
2624 gfc_add_block_to_block (&se
->pre
, &lse
.post
);
2630 /* Use the temporary variables in place of the real ones. */
2631 for (fargs
= sym
->formal
, n
= 0; fargs
; fargs
= fargs
->next
, n
++)
2632 gfc_shadow_sym (fargs
->sym
, temp_vars
[n
], &saved_vars
[n
]);
2634 gfc_conv_expr (se
, sym
->value
);
2636 if (sym
->ts
.type
== BT_CHARACTER
)
2638 gfc_conv_const_charlen (sym
->ts
.cl
);
2640 /* Force the expression to the correct length. */
2641 if (!INTEGER_CST_P (se
->string_length
)
2642 || tree_int_cst_lt (se
->string_length
,
2643 sym
->ts
.cl
->backend_decl
))
2645 type
= gfc_get_character_type (sym
->ts
.kind
, sym
->ts
.cl
);
2646 tmp
= gfc_create_var (type
, sym
->name
);
2647 tmp
= gfc_build_addr_expr (build_pointer_type (type
), tmp
);
2648 gfc_trans_string_copy (&se
->pre
, sym
->ts
.cl
->backend_decl
, tmp
,
2649 se
->string_length
, se
->expr
);
2652 se
->string_length
= sym
->ts
.cl
->backend_decl
;
2655 /* Restore the original variables. */
2656 for (fargs
= sym
->formal
, n
= 0; fargs
; fargs
= fargs
->next
, n
++)
2657 gfc_restore_sym (fargs
->sym
, &saved_vars
[n
]);
2658 gfc_free (saved_vars
);
2662 /* Translate a function expression. */
2665 gfc_conv_function_expr (gfc_se
* se
, gfc_expr
* expr
)
2669 if (expr
->value
.function
.isym
)
2671 gfc_conv_intrinsic_function (se
, expr
);
2675 /* We distinguish statement functions from general functions to improve
2676 runtime performance. */
2677 if (expr
->symtree
->n
.sym
->attr
.proc
== PROC_ST_FUNCTION
)
2679 gfc_conv_statement_function (se
, expr
);
2683 /* expr.value.function.esym is the resolved (specific) function symbol for
2684 most functions. However this isn't set for dummy procedures. */
2685 sym
= expr
->value
.function
.esym
;
2687 sym
= expr
->symtree
->n
.sym
;
2688 gfc_conv_function_call (se
, sym
, expr
->value
.function
.actual
, NULL_TREE
);
2693 gfc_conv_array_constructor_expr (gfc_se
* se
, gfc_expr
* expr
)
2695 gcc_assert (se
->ss
!= NULL
&& se
->ss
!= gfc_ss_terminator
);
2696 gcc_assert (se
->ss
->expr
== expr
&& se
->ss
->type
== GFC_SS_CONSTRUCTOR
);
2698 gfc_conv_tmp_array_ref (se
);
2699 gfc_advance_se_ss_chain (se
);
2703 /* Build a static initializer. EXPR is the expression for the initial value.
2704 The other parameters describe the variable of the component being
2705 initialized. EXPR may be null. */
2708 gfc_conv_initializer (gfc_expr
* expr
, gfc_typespec
* ts
, tree type
,
2709 bool array
, bool pointer
)
2713 if (!(expr
|| pointer
))
2718 /* Arrays need special handling. */
2720 return gfc_build_null_descriptor (type
);
2722 return gfc_conv_array_initializer (type
, expr
);
2725 return fold_convert (type
, null_pointer_node
);
2731 gfc_init_se (&se
, NULL
);
2732 gfc_conv_structure (&se
, expr
, 1);
2736 return gfc_conv_string_init (ts
->cl
->backend_decl
,expr
);
2739 gfc_init_se (&se
, NULL
);
2740 gfc_conv_constant (&se
, expr
);
2747 gfc_trans_subarray_assign (tree dest
, gfc_component
* cm
, gfc_expr
* expr
)
2759 gfc_start_block (&block
);
2761 /* Initialize the scalarizer. */
2762 gfc_init_loopinfo (&loop
);
2764 gfc_init_se (&lse
, NULL
);
2765 gfc_init_se (&rse
, NULL
);
2768 rss
= gfc_walk_expr (expr
);
2769 if (rss
== gfc_ss_terminator
)
2771 /* The rhs is scalar. Add a ss for the expression. */
2772 rss
= gfc_get_ss ();
2773 rss
->next
= gfc_ss_terminator
;
2774 rss
->type
= GFC_SS_SCALAR
;
2778 /* Create a SS for the destination. */
2779 lss
= gfc_get_ss ();
2780 lss
->type
= GFC_SS_COMPONENT
;
2782 lss
->shape
= gfc_get_shape (cm
->as
->rank
);
2783 lss
->next
= gfc_ss_terminator
;
2784 lss
->data
.info
.dimen
= cm
->as
->rank
;
2785 lss
->data
.info
.descriptor
= dest
;
2786 lss
->data
.info
.data
= gfc_conv_array_data (dest
);
2787 lss
->data
.info
.offset
= gfc_conv_array_offset (dest
);
2788 for (n
= 0; n
< cm
->as
->rank
; n
++)
2790 lss
->data
.info
.dim
[n
] = n
;
2791 lss
->data
.info
.start
[n
] = gfc_conv_array_lbound (dest
, n
);
2792 lss
->data
.info
.stride
[n
] = gfc_index_one_node
;
2794 mpz_init (lss
->shape
[n
]);
2795 mpz_sub (lss
->shape
[n
], cm
->as
->upper
[n
]->value
.integer
,
2796 cm
->as
->lower
[n
]->value
.integer
);
2797 mpz_add_ui (lss
->shape
[n
], lss
->shape
[n
], 1);
2800 /* Associate the SS with the loop. */
2801 gfc_add_ss_to_loop (&loop
, lss
);
2802 gfc_add_ss_to_loop (&loop
, rss
);
2804 /* Calculate the bounds of the scalarization. */
2805 gfc_conv_ss_startstride (&loop
);
2807 /* Setup the scalarizing loops. */
2808 gfc_conv_loop_setup (&loop
);
2810 /* Setup the gfc_se structures. */
2811 gfc_copy_loopinfo_to_se (&lse
, &loop
);
2812 gfc_copy_loopinfo_to_se (&rse
, &loop
);
2815 gfc_mark_ss_chain_used (rss
, 1);
2817 gfc_mark_ss_chain_used (lss
, 1);
2819 /* Start the scalarized loop body. */
2820 gfc_start_scalarized_body (&loop
, &body
);
2822 gfc_conv_tmp_array_ref (&lse
);
2823 if (cm
->ts
.type
== BT_CHARACTER
)
2824 lse
.string_length
= cm
->ts
.cl
->backend_decl
;
2826 gfc_conv_expr (&rse
, expr
);
2828 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, cm
->ts
, true, false);
2829 gfc_add_expr_to_block (&body
, tmp
);
2831 gcc_assert (rse
.ss
== gfc_ss_terminator
);
2833 /* Generate the copying loops. */
2834 gfc_trans_scalarizing_loops (&loop
, &body
);
2836 /* Wrap the whole thing up. */
2837 gfc_add_block_to_block (&block
, &loop
.pre
);
2838 gfc_add_block_to_block (&block
, &loop
.post
);
2840 for (n
= 0; n
< cm
->as
->rank
; n
++)
2841 mpz_clear (lss
->shape
[n
]);
2842 gfc_free (lss
->shape
);
2844 gfc_cleanup_loop (&loop
);
2846 return gfc_finish_block (&block
);
2850 /* Assign a single component of a derived type constructor. */
2853 gfc_trans_subcomponent_assign (tree dest
, gfc_component
* cm
, gfc_expr
* expr
)
2863 gfc_start_block (&block
);
2867 gfc_init_se (&se
, NULL
);
2868 /* Pointer component. */
2871 /* Array pointer. */
2872 if (expr
->expr_type
== EXPR_NULL
)
2873 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
2876 rss
= gfc_walk_expr (expr
);
2877 se
.direct_byref
= 1;
2879 gfc_conv_expr_descriptor (&se
, expr
, rss
);
2880 gfc_add_block_to_block (&block
, &se
.pre
);
2881 gfc_add_block_to_block (&block
, &se
.post
);
2886 /* Scalar pointers. */
2887 se
.want_pointer
= 1;
2888 gfc_conv_expr (&se
, expr
);
2889 gfc_add_block_to_block (&block
, &se
.pre
);
2890 gfc_add_modify_expr (&block
, dest
,
2891 fold_convert (TREE_TYPE (dest
), se
.expr
));
2892 gfc_add_block_to_block (&block
, &se
.post
);
2895 else if (cm
->dimension
)
2897 if (cm
->allocatable
&& expr
->expr_type
== EXPR_NULL
)
2898 gfc_conv_descriptor_data_set (&block
, dest
, null_pointer_node
);
2899 else if (cm
->allocatable
)
2903 gfc_init_se (&se
, NULL
);
2905 rss
= gfc_walk_expr (expr
);
2906 se
.want_pointer
= 0;
2907 gfc_conv_expr_descriptor (&se
, expr
, rss
);
2908 gfc_add_block_to_block (&block
, &se
.pre
);
2910 tmp
= fold_convert (TREE_TYPE (dest
), se
.expr
);
2911 gfc_add_modify_expr (&block
, dest
, tmp
);
2913 if (cm
->ts
.type
== BT_DERIVED
&& cm
->ts
.derived
->attr
.alloc_comp
)
2914 tmp
= gfc_copy_alloc_comp (cm
->ts
.derived
, se
.expr
, dest
,
2917 tmp
= gfc_duplicate_allocatable (dest
, se
.expr
,
2918 TREE_TYPE(cm
->backend_decl
),
2921 gfc_add_expr_to_block (&block
, tmp
);
2923 gfc_add_block_to_block (&block
, &se
.post
);
2924 gfc_conv_descriptor_data_set (&block
, se
.expr
, null_pointer_node
);
2926 /* Shift the lbound and ubound of temporaries to being unity, rather
2927 than zero, based. Calculate the offset for all cases. */
2928 offset
= gfc_conv_descriptor_offset (dest
);
2929 gfc_add_modify_expr (&block
, offset
, gfc_index_zero_node
);
2930 tmp2
=gfc_create_var (gfc_array_index_type
, NULL
);
2931 for (n
= 0; n
< expr
->rank
; n
++)
2933 if (expr
->expr_type
!= EXPR_VARIABLE
2934 && expr
->expr_type
!= EXPR_CONSTANT
)
2936 tmp
= gfc_conv_descriptor_ubound (dest
, gfc_rank_cst
[n
]);
2937 gfc_add_modify_expr (&block
, tmp
,
2938 fold_build2 (PLUS_EXPR
,
2939 gfc_array_index_type
,
2940 tmp
, gfc_index_one_node
));
2941 tmp
= gfc_conv_descriptor_lbound (dest
, gfc_rank_cst
[n
]);
2942 gfc_add_modify_expr (&block
, tmp
, gfc_index_one_node
);
2944 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
2945 gfc_conv_descriptor_lbound (dest
,
2947 gfc_conv_descriptor_stride (dest
,
2949 gfc_add_modify_expr (&block
, tmp2
, tmp
);
2950 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, offset
, tmp2
);
2951 gfc_add_modify_expr (&block
, offset
, tmp
);
2956 tmp
= gfc_trans_subarray_assign (dest
, cm
, expr
);
2957 gfc_add_expr_to_block (&block
, tmp
);
2960 else if (expr
->ts
.type
== BT_DERIVED
)
2962 if (expr
->expr_type
!= EXPR_STRUCTURE
)
2964 gfc_init_se (&se
, NULL
);
2965 gfc_conv_expr (&se
, expr
);
2966 gfc_add_modify_expr (&block
, dest
,
2967 fold_convert (TREE_TYPE (dest
), se
.expr
));
2971 /* Nested constructors. */
2972 tmp
= gfc_trans_structure_assign (dest
, expr
);
2973 gfc_add_expr_to_block (&block
, tmp
);
2978 /* Scalar component. */
2979 gfc_init_se (&se
, NULL
);
2980 gfc_init_se (&lse
, NULL
);
2982 gfc_conv_expr (&se
, expr
);
2983 if (cm
->ts
.type
== BT_CHARACTER
)
2984 lse
.string_length
= cm
->ts
.cl
->backend_decl
;
2986 tmp
= gfc_trans_scalar_assign (&lse
, &se
, cm
->ts
, true, false);
2987 gfc_add_expr_to_block (&block
, tmp
);
2989 return gfc_finish_block (&block
);
2992 /* Assign a derived type constructor to a variable. */
2995 gfc_trans_structure_assign (tree dest
, gfc_expr
* expr
)
3003 gfc_start_block (&block
);
3004 cm
= expr
->ts
.derived
->components
;
3005 for (c
= expr
->value
.constructor
; c
; c
= c
->next
, cm
= cm
->next
)
3007 /* Skip absent members in default initializers. */
3011 field
= cm
->backend_decl
;
3012 tmp
= build3 (COMPONENT_REF
, TREE_TYPE (field
), dest
, field
, NULL_TREE
);
3013 tmp
= gfc_trans_subcomponent_assign (tmp
, cm
, c
->expr
);
3014 gfc_add_expr_to_block (&block
, tmp
);
3016 return gfc_finish_block (&block
);
3019 /* Build an expression for a constructor. If init is nonzero then
3020 this is part of a static variable initializer. */
3023 gfc_conv_structure (gfc_se
* se
, gfc_expr
* expr
, int init
)
3030 VEC(constructor_elt
,gc
) *v
= NULL
;
3032 gcc_assert (se
->ss
== NULL
);
3033 gcc_assert (expr
->expr_type
== EXPR_STRUCTURE
);
3034 type
= gfc_typenode_for_spec (&expr
->ts
);
3038 /* Create a temporary variable and fill it in. */
3039 se
->expr
= gfc_create_var (type
, expr
->ts
.derived
->name
);
3040 tmp
= gfc_trans_structure_assign (se
->expr
, expr
);
3041 gfc_add_expr_to_block (&se
->pre
, tmp
);
3045 cm
= expr
->ts
.derived
->components
;
3047 for (c
= expr
->value
.constructor
; c
; c
= c
->next
, cm
= cm
->next
)
3049 /* Skip absent members in default initializers and allocatable
3050 components. Although the latter have a default initializer
3051 of EXPR_NULL,... by default, the static nullify is not needed
3052 since this is done every time we come into scope. */
3053 if (!c
->expr
|| cm
->allocatable
)
3056 val
= gfc_conv_initializer (c
->expr
, &cm
->ts
,
3057 TREE_TYPE (cm
->backend_decl
), cm
->dimension
, cm
->pointer
);
3059 /* Append it to the constructor list. */
3060 CONSTRUCTOR_APPEND_ELT (v
, cm
->backend_decl
, val
);
3062 se
->expr
= build_constructor (type
, v
);
3066 /* Translate a substring expression. */
3069 gfc_conv_substring_expr (gfc_se
* se
, gfc_expr
* expr
)
3075 gcc_assert (ref
->type
== REF_SUBSTRING
);
3077 se
->expr
= gfc_build_string_const(expr
->value
.character
.length
,
3078 expr
->value
.character
.string
);
3079 se
->string_length
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se
->expr
)));
3080 TYPE_STRING_FLAG (TREE_TYPE (se
->expr
))=1;
3082 gfc_conv_substring(se
,ref
,expr
->ts
.kind
,NULL
,&expr
->where
);
3086 /* Entry point for expression translation. Evaluates a scalar quantity.
3087 EXPR is the expression to be translated, and SE is the state structure if
3088 called from within the scalarized. */
3091 gfc_conv_expr (gfc_se
* se
, gfc_expr
* expr
)
3093 if (se
->ss
&& se
->ss
->expr
== expr
3094 && (se
->ss
->type
== GFC_SS_SCALAR
|| se
->ss
->type
== GFC_SS_REFERENCE
))
3096 /* Substitute a scalar expression evaluated outside the scalarization
3098 se
->expr
= se
->ss
->data
.scalar
.expr
;
3099 se
->string_length
= se
->ss
->string_length
;
3100 gfc_advance_se_ss_chain (se
);
3104 switch (expr
->expr_type
)
3107 gfc_conv_expr_op (se
, expr
);
3111 gfc_conv_function_expr (se
, expr
);
3115 gfc_conv_constant (se
, expr
);
3119 gfc_conv_variable (se
, expr
);
3123 se
->expr
= null_pointer_node
;
3126 case EXPR_SUBSTRING
:
3127 gfc_conv_substring_expr (se
, expr
);
3130 case EXPR_STRUCTURE
:
3131 gfc_conv_structure (se
, expr
, 0);
3135 gfc_conv_array_constructor_expr (se
, expr
);
3144 /* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs
3145 of an assignment. */
3147 gfc_conv_expr_lhs (gfc_se
* se
, gfc_expr
* expr
)
3149 gfc_conv_expr (se
, expr
);
3150 /* All numeric lvalues should have empty post chains. If not we need to
3151 figure out a way of rewriting an lvalue so that it has no post chain. */
3152 gcc_assert (expr
->ts
.type
== BT_CHARACTER
|| !se
->post
.head
);
3155 /* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
3156 numeric expressions. Used for scalar values where inserting cleanup code
3159 gfc_conv_expr_val (gfc_se
* se
, gfc_expr
* expr
)
3163 gcc_assert (expr
->ts
.type
!= BT_CHARACTER
);
3164 gfc_conv_expr (se
, expr
);
3167 val
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
3168 gfc_add_modify_expr (&se
->pre
, val
, se
->expr
);
3170 gfc_add_block_to_block (&se
->pre
, &se
->post
);
3174 /* Helper to translate and expression and convert it to a particular type. */
3176 gfc_conv_expr_type (gfc_se
* se
, gfc_expr
* expr
, tree type
)
3178 gfc_conv_expr_val (se
, expr
);
3179 se
->expr
= convert (type
, se
->expr
);
3183 /* Converts an expression so that it can be passed by reference. Scalar
3187 gfc_conv_expr_reference (gfc_se
* se
, gfc_expr
* expr
)
3191 if (se
->ss
&& se
->ss
->expr
== expr
3192 && se
->ss
->type
== GFC_SS_REFERENCE
)
3194 se
->expr
= se
->ss
->data
.scalar
.expr
;
3195 se
->string_length
= se
->ss
->string_length
;
3196 gfc_advance_se_ss_chain (se
);
3200 if (expr
->ts
.type
== BT_CHARACTER
)
3202 gfc_conv_expr (se
, expr
);
3203 gfc_conv_string_parameter (se
);
3207 if (expr
->expr_type
== EXPR_VARIABLE
)
3209 se
->want_pointer
= 1;
3210 gfc_conv_expr (se
, expr
);
3213 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
3214 gfc_add_modify_expr (&se
->pre
, var
, se
->expr
);
3215 gfc_add_block_to_block (&se
->pre
, &se
->post
);
3221 gfc_conv_expr (se
, expr
);
3223 /* Create a temporary var to hold the value. */
3224 if (TREE_CONSTANT (se
->expr
))
3226 tree tmp
= se
->expr
;
3227 STRIP_TYPE_NOPS (tmp
);
3228 var
= build_decl (CONST_DECL
, NULL
, TREE_TYPE (tmp
));
3229 DECL_INITIAL (var
) = tmp
;
3230 TREE_STATIC (var
) = 1;
3235 var
= gfc_create_var (TREE_TYPE (se
->expr
), NULL
);
3236 gfc_add_modify_expr (&se
->pre
, var
, se
->expr
);
3238 gfc_add_block_to_block (&se
->pre
, &se
->post
);
3240 /* Take the address of that value. */
3241 se
->expr
= build_fold_addr_expr (var
);
3246 gfc_trans_pointer_assign (gfc_code
* code
)
3248 return gfc_trans_pointer_assignment (code
->expr
, code
->expr2
);
3252 /* Generate code for a pointer assignment. */
3255 gfc_trans_pointer_assignment (gfc_expr
* expr1
, gfc_expr
* expr2
)
3265 gfc_start_block (&block
);
3267 gfc_init_se (&lse
, NULL
);
3269 lss
= gfc_walk_expr (expr1
);
3270 rss
= gfc_walk_expr (expr2
);
3271 if (lss
== gfc_ss_terminator
)
3273 /* Scalar pointers. */
3274 lse
.want_pointer
= 1;
3275 gfc_conv_expr (&lse
, expr1
);
3276 gcc_assert (rss
== gfc_ss_terminator
);
3277 gfc_init_se (&rse
, NULL
);
3278 rse
.want_pointer
= 1;
3279 gfc_conv_expr (&rse
, expr2
);
3280 gfc_add_block_to_block (&block
, &lse
.pre
);
3281 gfc_add_block_to_block (&block
, &rse
.pre
);
3282 gfc_add_modify_expr (&block
, lse
.expr
,
3283 fold_convert (TREE_TYPE (lse
.expr
), rse
.expr
));
3284 gfc_add_block_to_block (&block
, &rse
.post
);
3285 gfc_add_block_to_block (&block
, &lse
.post
);
3289 /* Array pointer. */
3290 gfc_conv_expr_descriptor (&lse
, expr1
, lss
);
3291 switch (expr2
->expr_type
)
3294 /* Just set the data pointer to null. */
3295 gfc_conv_descriptor_data_set (&lse
.pre
, lse
.expr
, null_pointer_node
);
3299 /* Assign directly to the pointer's descriptor. */
3300 lse
.direct_byref
= 1;
3301 gfc_conv_expr_descriptor (&lse
, expr2
, rss
);
3305 /* Assign to a temporary descriptor and then copy that
3306 temporary to the pointer. */
3308 tmp
= gfc_create_var (TREE_TYPE (desc
), "ptrtemp");
3311 lse
.direct_byref
= 1;
3312 gfc_conv_expr_descriptor (&lse
, expr2
, rss
);
3313 gfc_add_modify_expr (&lse
.pre
, desc
, tmp
);
3316 gfc_add_block_to_block (&block
, &lse
.pre
);
3317 gfc_add_block_to_block (&block
, &lse
.post
);
3319 return gfc_finish_block (&block
);
3323 /* Makes sure se is suitable for passing as a function string parameter. */
3324 /* TODO: Need to check all callers fo this function. It may be abused. */
3327 gfc_conv_string_parameter (gfc_se
* se
)
3331 if (TREE_CODE (se
->expr
) == STRING_CST
)
3333 se
->expr
= gfc_build_addr_expr (pchar_type_node
, se
->expr
);
3337 type
= TREE_TYPE (se
->expr
);
3338 if (TYPE_STRING_FLAG (type
))
3340 gcc_assert (TREE_CODE (se
->expr
) != INDIRECT_REF
);
3341 se
->expr
= gfc_build_addr_expr (pchar_type_node
, se
->expr
);
3344 gcc_assert (POINTER_TYPE_P (TREE_TYPE (se
->expr
)));
3345 gcc_assert (se
->string_length
3346 && TREE_CODE (TREE_TYPE (se
->string_length
)) == INTEGER_TYPE
);
3350 /* Generate code for assignment of scalar variables. Includes character
3351 strings and derived types with allocatable components. */
3354 gfc_trans_scalar_assign (gfc_se
* lse
, gfc_se
* rse
, gfc_typespec ts
,
3355 bool l_is_temp
, bool r_is_var
)
3361 gfc_init_block (&block
);
3363 if (ts
.type
== BT_CHARACTER
)
3365 gcc_assert (lse
->string_length
!= NULL_TREE
3366 && rse
->string_length
!= NULL_TREE
);
3368 gfc_conv_string_parameter (lse
);
3369 gfc_conv_string_parameter (rse
);
3371 gfc_add_block_to_block (&block
, &lse
->pre
);
3372 gfc_add_block_to_block (&block
, &rse
->pre
);
3374 gfc_trans_string_copy (&block
, lse
->string_length
, lse
->expr
,
3375 rse
->string_length
, rse
->expr
);
3377 else if (ts
.type
== BT_DERIVED
&& ts
.derived
->attr
.alloc_comp
)
3381 /* Are the rhs and the lhs the same? */
3384 cond
= fold_build2 (EQ_EXPR
, boolean_type_node
,
3385 build_fold_addr_expr (lse
->expr
),
3386 build_fold_addr_expr (rse
->expr
));
3387 cond
= gfc_evaluate_now (cond
, &lse
->pre
);
3390 /* Deallocate the lhs allocated components as long as it is not
3391 the same as the rhs. */
3394 tmp
= gfc_deallocate_alloc_comp (ts
.derived
, lse
->expr
, 0);
3396 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (), tmp
);
3397 gfc_add_expr_to_block (&lse
->pre
, tmp
);
3400 gfc_add_block_to_block (&block
, &lse
->pre
);
3401 gfc_add_block_to_block (&block
, &rse
->pre
);
3403 gfc_add_modify_expr (&block
, lse
->expr
,
3404 fold_convert (TREE_TYPE (lse
->expr
), rse
->expr
));
3406 /* Do a deep copy if the rhs is a variable, if it is not the
3410 tmp
= gfc_copy_alloc_comp (ts
.derived
, rse
->expr
, lse
->expr
, 0);
3411 tmp
= build3_v (COND_EXPR
, cond
, build_empty_stmt (), tmp
);
3412 gfc_add_expr_to_block (&block
, tmp
);
3417 gfc_add_block_to_block (&block
, &lse
->pre
);
3418 gfc_add_block_to_block (&block
, &rse
->pre
);
3420 gfc_add_modify_expr (&block
, lse
->expr
,
3421 fold_convert (TREE_TYPE (lse
->expr
), rse
->expr
));
3424 gfc_add_block_to_block (&block
, &lse
->post
);
3425 gfc_add_block_to_block (&block
, &rse
->post
);
3427 return gfc_finish_block (&block
);
3431 /* Try to translate array(:) = func (...), where func is a transformational
3432 array function, without using a temporary. Returns NULL is this isn't the
3436 gfc_trans_arrayfunc_assign (gfc_expr
* expr1
, gfc_expr
* expr2
)
3441 bool seen_array_ref
;
3443 /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
3444 if (expr2
->value
.function
.isym
&& !gfc_is_intrinsic_libcall (expr2
))
3447 /* Elemental functions don't need a temporary anyway. */
3448 if (expr2
->value
.function
.esym
!= NULL
3449 && expr2
->value
.function
.esym
->attr
.elemental
)
3452 /* Fail if EXPR1 can't be expressed as a descriptor. */
3453 if (gfc_ref_needs_temporary_p (expr1
->ref
))
3456 /* Functions returning pointers need temporaries. */
3457 if (expr2
->symtree
->n
.sym
->attr
.pointer
3458 || expr2
->symtree
->n
.sym
->attr
.allocatable
)
3461 /* Character array functions need temporaries unless the
3462 character lengths are the same. */
3463 if (expr2
->ts
.type
== BT_CHARACTER
&& expr2
->rank
> 0)
3465 if (expr1
->ts
.cl
->length
== NULL
3466 || expr1
->ts
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
3469 if (expr2
->ts
.cl
->length
== NULL
3470 || expr2
->ts
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
3473 if (mpz_cmp (expr1
->ts
.cl
->length
->value
.integer
,
3474 expr2
->ts
.cl
->length
->value
.integer
) != 0)
3478 /* Check that no LHS component references appear during an array
3479 reference. This is needed because we do not have the means to
3480 span any arbitrary stride with an array descriptor. This check
3481 is not needed for the rhs because the function result has to be
3483 seen_array_ref
= false;
3484 for (ref
= expr1
->ref
; ref
; ref
= ref
->next
)
3486 if (ref
->type
== REF_ARRAY
)
3487 seen_array_ref
= true;
3488 else if (ref
->type
== REF_COMPONENT
&& seen_array_ref
)
3492 /* Check for a dependency. */
3493 if (gfc_check_fncall_dependency (expr1
, INTENT_OUT
,
3494 expr2
->value
.function
.esym
,
3495 expr2
->value
.function
.actual
))
3498 /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
3500 gcc_assert (expr2
->value
.function
.isym
3501 || (gfc_return_by_reference (expr2
->value
.function
.esym
)
3502 && expr2
->value
.function
.esym
->result
->attr
.dimension
));
3504 ss
= gfc_walk_expr (expr1
);
3505 gcc_assert (ss
!= gfc_ss_terminator
);
3506 gfc_init_se (&se
, NULL
);
3507 gfc_start_block (&se
.pre
);
3508 se
.want_pointer
= 1;
3510 gfc_conv_array_parameter (&se
, expr1
, ss
, 0);
3512 se
.direct_byref
= 1;
3513 se
.ss
= gfc_walk_expr (expr2
);
3514 gcc_assert (se
.ss
!= gfc_ss_terminator
);
3515 gfc_conv_function_expr (&se
, expr2
);
3516 gfc_add_block_to_block (&se
.pre
, &se
.post
);
3518 return gfc_finish_block (&se
.pre
);
3521 /* Determine whether the given EXPR_CONSTANT is a zero initializer. */
3524 is_zero_initializer_p (gfc_expr
* expr
)
3526 if (expr
->expr_type
!= EXPR_CONSTANT
)
3528 /* We ignore Hollerith constants for the time being. */
3532 switch (expr
->ts
.type
)
3535 return mpz_cmp_si (expr
->value
.integer
, 0) == 0;
3538 return mpfr_zero_p (expr
->value
.real
)
3539 && MPFR_SIGN (expr
->value
.real
) >= 0;
3542 return expr
->value
.logical
== 0;
3545 return mpfr_zero_p (expr
->value
.complex.r
)
3546 && MPFR_SIGN (expr
->value
.complex.r
) >= 0
3547 && mpfr_zero_p (expr
->value
.complex.i
)
3548 && MPFR_SIGN (expr
->value
.complex.i
) >= 0;
3556 /* Try to efficiently translate array(:) = 0. Return NULL if this
3560 gfc_trans_zero_assign (gfc_expr
* expr
)
3562 tree dest
, len
, type
;
3566 sym
= expr
->symtree
->n
.sym
;
3567 dest
= gfc_get_symbol_decl (sym
);
3569 type
= TREE_TYPE (dest
);
3570 if (POINTER_TYPE_P (type
))
3571 type
= TREE_TYPE (type
);
3572 if (!GFC_ARRAY_TYPE_P (type
))
3575 /* Determine the length of the array. */
3576 len
= GFC_TYPE_ARRAY_SIZE (type
);
3577 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
3580 len
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, len
,
3581 TYPE_SIZE_UNIT (gfc_get_element_type (type
)));
3583 /* Convert arguments to the correct types. */
3584 if (!POINTER_TYPE_P (TREE_TYPE (dest
)))
3585 dest
= gfc_build_addr_expr (pvoid_type_node
, dest
);
3587 dest
= fold_convert (pvoid_type_node
, dest
);
3588 len
= fold_convert (size_type_node
, len
);
3590 /* Construct call to __builtin_memset. */
3591 tmp
= build_call_expr (built_in_decls
[BUILT_IN_MEMSET
],
3592 3, dest
, integer_zero_node
, len
);
3593 return fold_convert (void_type_node
, tmp
);
3597 /* Helper for gfc_trans_array_copy and gfc_trans_array_constructor_copy
3598 that constructs the call to __builtin_memcpy. */
3601 gfc_build_memcpy_call (tree dst
, tree src
, tree len
)
3605 /* Convert arguments to the correct types. */
3606 if (!POINTER_TYPE_P (TREE_TYPE (dst
)))
3607 dst
= gfc_build_addr_expr (pvoid_type_node
, dst
);
3609 dst
= fold_convert (pvoid_type_node
, dst
);
3611 if (!POINTER_TYPE_P (TREE_TYPE (src
)))
3612 src
= gfc_build_addr_expr (pvoid_type_node
, src
);
3614 src
= fold_convert (pvoid_type_node
, src
);
3616 len
= fold_convert (size_type_node
, len
);
3618 /* Construct call to __builtin_memcpy. */
3619 tmp
= build_call_expr (built_in_decls
[BUILT_IN_MEMCPY
], 3, dst
, src
, len
);
3620 return fold_convert (void_type_node
, tmp
);
3624 /* Try to efficiently translate dst(:) = src(:). Return NULL if this
3625 can't be done. EXPR1 is the destination/lhs and EXPR2 is the
3626 source/rhs, both are gfc_full_array_ref_p which have been checked for
3630 gfc_trans_array_copy (gfc_expr
* expr1
, gfc_expr
* expr2
)
3632 tree dst
, dlen
, dtype
;
3633 tree src
, slen
, stype
;
3635 dst
= gfc_get_symbol_decl (expr1
->symtree
->n
.sym
);
3636 src
= gfc_get_symbol_decl (expr2
->symtree
->n
.sym
);
3638 dtype
= TREE_TYPE (dst
);
3639 if (POINTER_TYPE_P (dtype
))
3640 dtype
= TREE_TYPE (dtype
);
3641 stype
= TREE_TYPE (src
);
3642 if (POINTER_TYPE_P (stype
))
3643 stype
= TREE_TYPE (stype
);
3645 if (!GFC_ARRAY_TYPE_P (dtype
) || !GFC_ARRAY_TYPE_P (stype
))
3648 /* Determine the lengths of the arrays. */
3649 dlen
= GFC_TYPE_ARRAY_SIZE (dtype
);
3650 if (!dlen
|| TREE_CODE (dlen
) != INTEGER_CST
)
3652 dlen
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, dlen
,
3653 TYPE_SIZE_UNIT (gfc_get_element_type (dtype
)));
3655 slen
= GFC_TYPE_ARRAY_SIZE (stype
);
3656 if (!slen
|| TREE_CODE (slen
) != INTEGER_CST
)
3658 slen
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, slen
,
3659 TYPE_SIZE_UNIT (gfc_get_element_type (stype
)));
3661 /* Sanity check that they are the same. This should always be
3662 the case, as we should already have checked for conformance. */
3663 if (!tree_int_cst_equal (slen
, dlen
))
3666 return gfc_build_memcpy_call (dst
, src
, dlen
);
3670 /* Try to efficiently translate array(:) = (/ ... /). Return NULL if
3671 this can't be done. EXPR1 is the destination/lhs for which
3672 gfc_full_array_ref_p is true, and EXPR2 is the source/rhs. */
3675 gfc_trans_array_constructor_copy (gfc_expr
* expr1
, gfc_expr
* expr2
)
3677 unsigned HOST_WIDE_INT nelem
;
3682 nelem
= gfc_constant_array_constructor_p (expr2
->value
.constructor
);
3686 dst
= gfc_get_symbol_decl (expr1
->symtree
->n
.sym
);
3687 dtype
= TREE_TYPE (dst
);
3688 if (POINTER_TYPE_P (dtype
))
3689 dtype
= TREE_TYPE (dtype
);
3690 if (!GFC_ARRAY_TYPE_P (dtype
))
3693 /* Determine the lengths of the array. */
3694 len
= GFC_TYPE_ARRAY_SIZE (dtype
);
3695 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
3698 /* Confirm that the constructor is the same size. */
3699 if (compare_tree_int (len
, nelem
) != 0)
3702 len
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, len
,
3703 TYPE_SIZE_UNIT (gfc_get_element_type (dtype
)));
3705 stype
= gfc_typenode_for_spec (&expr2
->ts
);
3706 src
= gfc_build_constant_array_constructor (expr2
, stype
);
3708 stype
= TREE_TYPE (src
);
3709 if (POINTER_TYPE_P (stype
))
3710 stype
= TREE_TYPE (stype
);
3712 return gfc_build_memcpy_call (dst
, src
, len
);
3716 /* Subroutine of gfc_trans_assignment that actually scalarizes the
3717 assignment. EXPR1 is the destination/RHS and EXPR2 is the source/LHS. */
3720 gfc_trans_assignment_1 (gfc_expr
* expr1
, gfc_expr
* expr2
, bool init_flag
)
3725 gfc_ss
*lss_section
;
3733 /* Assignment of the form lhs = rhs. */
3734 gfc_start_block (&block
);
3736 gfc_init_se (&lse
, NULL
);
3737 gfc_init_se (&rse
, NULL
);
3740 lss
= gfc_walk_expr (expr1
);
3742 if (lss
!= gfc_ss_terminator
)
3744 /* The assignment needs scalarization. */
3747 /* Find a non-scalar SS from the lhs. */
3748 while (lss_section
!= gfc_ss_terminator
3749 && lss_section
->type
!= GFC_SS_SECTION
)
3750 lss_section
= lss_section
->next
;
3752 gcc_assert (lss_section
!= gfc_ss_terminator
);
3754 /* Initialize the scalarizer. */
3755 gfc_init_loopinfo (&loop
);
3758 rss
= gfc_walk_expr (expr2
);
3759 if (rss
== gfc_ss_terminator
)
3761 /* The rhs is scalar. Add a ss for the expression. */
3762 rss
= gfc_get_ss ();
3763 rss
->next
= gfc_ss_terminator
;
3764 rss
->type
= GFC_SS_SCALAR
;
3767 /* Associate the SS with the loop. */
3768 gfc_add_ss_to_loop (&loop
, lss
);
3769 gfc_add_ss_to_loop (&loop
, rss
);
3771 /* Calculate the bounds of the scalarization. */
3772 gfc_conv_ss_startstride (&loop
);
3773 /* Resolve any data dependencies in the statement. */
3774 gfc_conv_resolve_dependencies (&loop
, lss
, rss
);
3775 /* Setup the scalarizing loops. */
3776 gfc_conv_loop_setup (&loop
);
3778 /* Setup the gfc_se structures. */
3779 gfc_copy_loopinfo_to_se (&lse
, &loop
);
3780 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3783 gfc_mark_ss_chain_used (rss
, 1);
3784 if (loop
.temp_ss
== NULL
)
3787 gfc_mark_ss_chain_used (lss
, 1);
3791 lse
.ss
= loop
.temp_ss
;
3792 gfc_mark_ss_chain_used (lss
, 3);
3793 gfc_mark_ss_chain_used (loop
.temp_ss
, 3);
3796 /* Start the scalarized loop body. */
3797 gfc_start_scalarized_body (&loop
, &body
);
3800 gfc_init_block (&body
);
3802 l_is_temp
= (lss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
);
3804 /* Translate the expression. */
3805 gfc_conv_expr (&rse
, expr2
);
3809 gfc_conv_tmp_array_ref (&lse
);
3810 gfc_advance_se_ss_chain (&lse
);
3813 gfc_conv_expr (&lse
, expr1
);
3815 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
3816 l_is_temp
|| init_flag
,
3817 expr2
->expr_type
== EXPR_VARIABLE
);
3818 gfc_add_expr_to_block (&body
, tmp
);
3820 if (lss
== gfc_ss_terminator
)
3822 /* Use the scalar assignment as is. */
3823 gfc_add_block_to_block (&block
, &body
);
3827 gcc_assert (lse
.ss
== gfc_ss_terminator
3828 && rse
.ss
== gfc_ss_terminator
);
3832 gfc_trans_scalarized_loop_boundary (&loop
, &body
);
3834 /* We need to copy the temporary to the actual lhs. */
3835 gfc_init_se (&lse
, NULL
);
3836 gfc_init_se (&rse
, NULL
);
3837 gfc_copy_loopinfo_to_se (&lse
, &loop
);
3838 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3840 rse
.ss
= loop
.temp_ss
;
3843 gfc_conv_tmp_array_ref (&rse
);
3844 gfc_advance_se_ss_chain (&rse
);
3845 gfc_conv_expr (&lse
, expr1
);
3847 gcc_assert (lse
.ss
== gfc_ss_terminator
3848 && rse
.ss
== gfc_ss_terminator
);
3850 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
3852 gfc_add_expr_to_block (&body
, tmp
);
3855 /* Generate the copying loops. */
3856 gfc_trans_scalarizing_loops (&loop
, &body
);
3858 /* Wrap the whole thing up. */
3859 gfc_add_block_to_block (&block
, &loop
.pre
);
3860 gfc_add_block_to_block (&block
, &loop
.post
);
3862 gfc_cleanup_loop (&loop
);
3865 return gfc_finish_block (&block
);
3869 /* Check whether EXPR, which is an EXPR_VARIABLE, is a copyable array. */
3872 copyable_array_p (gfc_expr
* expr
)
3874 /* First check it's an array. */
3875 if (expr
->rank
< 1 || !expr
->ref
)
3878 /* Next check that it's of a simple enough type. */
3879 switch (expr
->ts
.type
)
3891 return !expr
->ts
.derived
->attr
.alloc_comp
;
3900 /* Translate an assignment. */
3903 gfc_trans_assignment (gfc_expr
* expr1
, gfc_expr
* expr2
, bool init_flag
)
3907 /* Special case a single function returning an array. */
3908 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->rank
> 0)
3910 tmp
= gfc_trans_arrayfunc_assign (expr1
, expr2
);
3915 /* Special case assigning an array to zero. */
3916 if (expr1
->expr_type
== EXPR_VARIABLE
3919 && gfc_full_array_ref_p (expr1
->ref
)
3920 && is_zero_initializer_p (expr2
))
3922 tmp
= gfc_trans_zero_assign (expr1
);
3927 /* Special case copying one array to another. */
3928 if (expr1
->expr_type
== EXPR_VARIABLE
3929 && copyable_array_p (expr1
)
3930 && gfc_full_array_ref_p (expr1
->ref
)
3931 && expr2
->expr_type
== EXPR_VARIABLE
3932 && copyable_array_p (expr2
)
3933 && gfc_full_array_ref_p (expr2
->ref
)
3934 && gfc_compare_types (&expr1
->ts
, &expr2
->ts
)
3935 && !gfc_check_dependency (expr1
, expr2
, 0))
3937 tmp
= gfc_trans_array_copy (expr1
, expr2
);
3942 /* Special case initializing an array from a constant array constructor. */
3943 if (expr1
->expr_type
== EXPR_VARIABLE
3944 && copyable_array_p (expr1
)
3945 && gfc_full_array_ref_p (expr1
->ref
)
3946 && expr2
->expr_type
== EXPR_ARRAY
3947 && gfc_compare_types (&expr1
->ts
, &expr2
->ts
))
3949 tmp
= gfc_trans_array_constructor_copy (expr1
, expr2
);
3954 /* Fallback to the scalarizer to generate explicit loops. */
3955 return gfc_trans_assignment_1 (expr1
, expr2
, init_flag
);
3959 gfc_trans_init_assign (gfc_code
* code
)
3961 return gfc_trans_assignment (code
->expr
, code
->expr2
, true);
3965 gfc_trans_assign (gfc_code
* code
)
3967 return gfc_trans_assignment (code
->expr
, code
->expr2
, false);