summaryrefslogtreecommitdiff
path: root/gcc/fortran/simplify.c
diff options
context:
space:
mode:
authorjvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-13 01:59:35 +0000
committerjvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-13 01:59:35 +0000
commit126387b5b6b5a55db23d87e27562c91cc235c906 (patch)
tree918735c4a29176e24e41c0c81fa94027f00f96f3 /gcc/fortran/simplify.c
parentca449354ee517a86554d5e98ba5ca273d3ce7449 (diff)
downloadgcc-126387b5b6b5a55db23d87e27562c91cc235c906.tar.gz
2010-04-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
* array.c (extract_element): Restore function from trunk. (gfc_get_array_element): Restore function from trunk. (gfc_expand_constructor): Restore check against flag_max_array_constructor. * constructor.c (node_copy_and_append): Delete unused. * gfortran.h: Delete comment and extra include. * constructor.h: Bump copyright and clean up TODO comments. * resolve.c: Whitespace. 2010-04-12 Daniel Franke <franke.daniel@gmail.com> * simplify.c (compute_dot_product): Replaced usage of ADVANCE macro with direct access access to elements. Adjusted prototype, fixed all callers. (gfc_simplify_dot_product): Removed duplicate check for zero-sized array. (gfc_simplify_matmul): Removed usage of ADVANCE macro. (gfc_simplify_spread): Removed workaround, directly insert elements at a given array position. (gfc_simplify_transpose): Likewise. (gfc_simplify_pack): Replaced usage of ADVANCE macro with corresponding function calls. (gfc_simplify_unpack): Likewise. 2010-04-12 Daniel Franke <franke.daniel@gmail.com> * simplify.c (only_convert_cmplx_boz): Renamed to ... (convert_boz): ... this and moved to start of file. (gfc_simplify_abs): Whitespace fix. (gfc_simplify_acos): Whitespace fix. (gfc_simplify_acosh): Whitespace fix. (gfc_simplify_aint): Whitespace fix. (gfc_simplify_dint): Whitespace fix. (gfc_simplify_anint): Whitespace fix. (gfc_simplify_and): Replaced if-gate by more common switch-over-type. (gfc_simplify_dnint): Whitespace fix. (gfc_simplify_asin): Whitespace fix. (gfc_simplify_asinh): Moved creation of result-expr out of switch. (gfc_simplify_atan): Likewise. (gfc_simplify_atanh): Whitespace fix. (gfc_simplify_atan2): Whitespace fix. (gfc_simplify_bessel_j0): Removed ATTRIBUTE_UNUSED. (gfc_simplify_bessel_j1): Likewise. (gfc_simplify_bessel_jn): Likewise. (gfc_simplify_bessel_y0): Likewise. (gfc_simplify_bessel_y1): Likewise. (gfc_simplify_bessel_yn): Likewise. (gfc_simplify_ceiling): Reorderd statements. (simplify_cmplx): Use convert_boz(), check for constant arguments. Whitespace fix. (gfc_simplify_cmplx): Use correct default kind. Removed check for constant arguments. (gfc_simplify_complex): Replaced if-gate. Removed check for constant arguments. (gfc_simplify_conjg): Whitespace fix. (gfc_simplify_cos): Whitespace fix. (gfc_simplify_cosh): Replaced if-gate by more common switch-over-type. (gfc_simplify_dcmplx): Removed check for constant arguments. (gfc_simplify_dble): Use convert_boz() and gfc_convert_constant(). (gfc_simplify_digits): Whitespace fix. (gfc_simplify_dim): Whitespace fix. (gfc_simplify_dprod): Reordered statements. (gfc_simplify_erf): Whitespace fix. (gfc_simplify_erfc): Whitespace fix. (gfc_simplify_epsilon): Whitespace fix. (gfc_simplify_exp): Whitespace fix. (gfc_simplify_exponent): Use convert_boz(). (gfc_simplify_floor): Reorderd statements. (gfc_simplify_gamma): Whitespace fix. (gfc_simplify_huge): Whitespace fix. (gfc_simplify_iand): Whitespace fix. (gfc_simplify_ieor): Whitespace fix. (simplify_intconv): Use gfc_convert_constant(). (gfc_simplify_int): Use simplify_intconv(). (gfc_simplify_int2): Reorderd statements. (gfc_simplify_idint): Reorderd statements. (gfc_simplify_ior): Whitespace fix. (gfc_simplify_ishftc): Removed duplicate type check. (gfc_simplify_len): Use range_check() instead of manual range check. (gfc_simplify_lgamma): Removed ATTRIBUTE_UNUSED. Whitespace fix. (gfc_simplify_log): Whitespace fix. (gfc_simplify_log10): Whitespace fix. (gfc_simplify_minval): Whitespace fix. (gfc_simplify_maxval): Whitespace fix. (gfc_simplify_mod): Whitespace fix. (gfc_simplify_modulo): Whitespace fix. (simplify_nint): Reorderd statements. (gfc_simplify_not): Whitespace fix. (gfc_simplify_or): Replaced if-gate by more common switch-over-type. (gfc_simplify_radix): Removed unused result-variable. Whitespace fix. (gfc_simplify_range): Removed unused result-variable. Whitespace fix. (gfc_simplify_real): Use convert_boz() and gfc_convert_constant(). (gfc_simplify_realpart): Whitespace fix. (gfc_simplify_selected_char_kind): Removed unused result-variable. (gfc_simplify_selected_int_kind): Removed unused result-variable. (gfc_simplify_selected_real_kind): Removed unused result-variable. (gfc_simplify_sign): Whitespace fix. (gfc_simplify_sin): Whitespace fix. (gfc_simplify_sinh): Replaced if-gate by more common switch-over-type. (gfc_simplify_sqrt): Avoided goto by inlining check. Whitespace fix. (gfc_simplify_tan): Replaced if-gate by more common switch-over-type. (gfc_simplify_tanh): Replaced if-gate by more common switch-over-type. (gfc_simplify_xor): Replaced if-gate by more common switch-over-type. 2010-04-12 Daniel Franke <franke.daniel@gmail.com> * gfortran.h (gfc_start_constructor): Removed. (gfc_get_array_element): Removed. * array.c (gfc_start_constructor): Removed, use gfc_get_array_expr instead. Fixed all callers. (extract_element): Removed. (gfc_expand_constructor): Temporarily removed check for max-array-constructor. Will be re-introduced later if still required. (gfc_get_array_element): Removed, use gfc_constructor_lookup_expr instead. Fixed all callers. * expr.c (find_array_section): Replaced manual lookup of elements by gfc_constructor_lookup. 2010-04-12 Daniel Franke <franke.daniel@gmail.com> * gfortran.h (gfc_get_null_expr): New prototype. (gfc_get_operator_expr): New prototype. (gfc_get_character_expr): New prototype. (gfc_get_iokind_expr): New prototype. * expr.c (gfc_get_null_expr): New. (gfc_get_character_expr): New. (gfc_get_iokind_expr): New. (gfc_get_operator_expr): Moved here from matchexp.c (build_node). * matchexp.c (build_node): Renamed and moved to expr.c (gfc_get_operator_expr). Reordered arguments to match other functions. Fixed all callers. (gfc_get_parentheses): Use specific function to build expr. * array.c (gfc_match_array_constructor): Likewise. * arith.c (eval_intrinsic): Likewise. (gfc_hollerith2int): Likewise. (gfc_hollerith2real): Likewise. (gfc_hollerith2complex): Likewise. (gfc_hollerith2logical): Likewise. * data.c (create_character_intializer): Likewise. * decl.c (gfc_match_null): Likewise. (enum_initializer): Likewise. * io.c (gfc_match_format): Likewise. (match_io): Likewise. * match.c (gfc_match_nullify): Likewise. * primary.c (match_string_constant): Likewise. (match_logical_constant): Likewise. (build_actual_constructor): Likewise. * resolve.c (build_default_init_expr): Likewise. * symbol.c (generate_isocbinding_symbol): Likewise. (gfc_build_class_symbol): Likewise. (gfc_find_derived_vtab): Likewise. * simplify.c (simplify_achar_char): Likewise. (gfc_simplify_adjustl): Likewise. (gfc_simplify_adjustr): Likewise. (gfc_simplify_and): Likewise. (gfc_simplify_bit_size): Likewise. (gfc_simplify_is_iostat_end): Likewise. (gfc_simplify_is_iostat_eor): Likewise. (gfc_simplify_isnan): Likewise. (simplify_bound): Likewise. (gfc_simplify_leadz): Likewise. (gfc_simplify_len_trim): Likewise. (gfc_simplify_logical): Likewise. (gfc_simplify_maxexponent): Likewise. (gfc_simplify_minexponent): Likewise. (gfc_simplify_new_line): Likewise. (gfc_simplify_null): Likewise. (gfc_simplify_or): Likewise. (gfc_simplify_precision): Likewise. (gfc_simplify_repeat): Likewise. (gfc_simplify_scan): Likewise. (gfc_simplify_size): Likewise. (gfc_simplify_trailz): Likewise. (gfc_simplify_trim): Likewise. (gfc_simplify_verify): Likewise. (gfc_simplify_xor): Likewise. * trans-io.c (build_dt): Likewise. (gfc_new_nml_name_expr): Removed. 2010-04-12 Daniel Franke <franke.daniel@gmail.com> * arith.h (gfc_constant_result): Removed prototype. * constructor.h (gfc_build_array_expr): Removed prototype. (gfc_build_structure_constructor_expr): Removed prototype. * gfortran.h (gfc_int_expr): Removed prototype. (gfc_logical_expr): Removed prototype. (gfc_get_array_expr): New prototype. (gfc_get_structure_constructor_expr): New prototype. (gfc_get_constant_expr): New prototype. (gfc_get_int_expr): New prototype. (gfc_get_logical_expr): New prototype. * arith.c (gfc_constant_result): Moved and renamed to expr.c (gfc_get_constant_expr). Fixed all callers. * constructor.c (gfc_build_array_expr): Moved and renamed to expr.c (gfc_get_array_expr). Split gfc_typespec argument to type and kind. Fixed all callers. (gfc_build_structure_constructor_expr): Moved and renamed to expr.c (gfc_get_structure_constructor_expr). Split gfc_typespec argument to type and kind. Fixed all callers. * expr.c (gfc_logical_expr): Renamed to ... (gfc_get_logical_expr): ... this. Added kind argument. Fixed all callers. (gfc_int_expr): Renamed to ... (gfc_get_int_expr): ... this. Added kind and where arguments. Fixed all callers. (gfc_get_constant_expr): New. (gfc_get_array_expr): New. (gfc_get_structure_constructor_expr): New. * simplify.c (int_expr_with_kind): Removed, callers use gfc_get_int_expr instead. 2010-04-12 Daniel Franke <franke.daniel@gmail.com> * constructor.h: New. * constructor.c: New. * Make-lang.in: Add new files to F95_PARSER_OBJS. * arith.c (reducy_unary): Use constructor API. (reduce_binary_ac): Likewise. (reduce_binary_ca): Likewise. (reduce_binary_aa): Likewise. * check.c (gfc_check_pack): Likewise. (gfc_check_reshape): Likewise. (gfc_check_unpack): Likewise. * decl.c (add_init_expr_to_sym): Likewise. (build_struct): Likewise. * dependency.c (gfc_check_dependency): Likewise. (contains_forall_index_p): Likewise. * dump-parse-tree.c (show_constructor): Likewise. * expr.c (free_expr0): Likewise. (gfc_copy_expr): Likewise. (gfc_is_constant_expr): Likewise. (simplify_constructor): Likewise. (find_array_element): Likewise. (find_component_ref): Likewise. (find_array_section): Likewise. (find_substring_ref): Likewise. (simplify_const_ref): Likewise. (scalarize_intrinsic_call): Likewise. (check_alloc_comp_init): Likewise. (gfc_default_initializer): Likewise. (gfc_traverse_expr): Likewise. * iresolve.c (check_charlen_present): Likewise. (gfc_resolve_reshape): Likewise. (gfc_resolve_transfer): Likewise. * module.c (mio_constructor): Likewise. * primary.c (build_actual_constructor): Likewise. (gfc_match_structure_constructor): Likewise. * resolve.c (resolve_structure_cons): Likewise. * simplify.c (is_constant_array_expr): Likewise. (init_result_expr): Likewise. (transformational_result): Likewise. (simplify_transformation_to_scalar): Likewise. (simplify_transformation_to_array): Likewise. (gfc_simplify_dot_product): Likewise. (simplify_bound): Likewise. (simplify_matmul): Likewise. (simplify_minval_maxval): Likewise. (gfc_simplify_pack): Likewise. (gfc_simplify_reshape): Likewise. (gfc_simplify_shape): Likewise. (gfc_simplify_spread): Likewise. (gfc_simplify_transpose): Likewise. (gfc_simplify_unpack): Likewise.q (gfc_convert_constant): Likewise. (gfc_convert_char_constant): Likewise. * target-memory.c (size_array): Likewise. (encode_array): Likewise. (encode_derived): Likewise. (interpret_array): Likewise. (gfc_interpret_derived): Likewise. (expr_to_char): Likewise. (gfc_merge_initializers): Likewise. * trans-array.c (gfc_get_array_constructor_size): Likewise. (gfc_trans_array_constructor_value): Likewise. (get_array_ctor_strlen): Likewise. (gfc_constant_array_constructor_p): Likewise. (gfc_build_constant_array_constructor): Likewise. (gfc_trans_array_constructor): Likewise. (gfc_conv_array_initializer): Likewise. * trans-decl.c (check_constant_initializer): Likewise. * trans-expr.c (flatten_array_ctors_without_strlen): Likewise. (gfc_apply_interface_mapping_to_cons): Likewise. (gfc_trans_structure_assign): Likewise. (gfc_conv_structure): Likewise. * array.c (check_duplicate_iterator): Likewise. (match_array_list): Likewise. (match_array_cons_element): Likewise. (gfc_match_array_constructor): Likewise. (check_constructor_type): Likewise. (check_constructor): Likewise. (expand): Likewise. (expand_constructor): Likewise. (extract_element): Likewise. (gfc_expanded_ac): Likewise. (resolve_array_list): Likewise. (gfc_resolve_character_array_constructor): Likewise. (copy_iterator): Renamed to ... (gfc_copy_iterator): ... this. (gfc_append_constructor): Removed. (gfc_insert_constructor): Removed unused function. (gfc_get_constructor): Removed. (gfc_free_constructor): Removed. (qgfc_copy_constructor): Removed. * gfortran.h (struct gfc_expr): Removed member 'con_by_offset'. Removed all references. Replaced constructor list by splay-tree. (struct gfc_constructor): Removed member 'next', moved 'offset' from the inner struct, added member 'base'. (gfc_append_constructor): Removed prototype. (gfc_insert_constructor): Removed prototype. (gfc_get_constructor): Removed prototype. (gfc_free_constructor): Removed prototype. (qgfc_copy_constructor): Removed prototype. (gfc_copy_iterator): New prototype. * trans-array.h (gfc_constant_array_constructor_p): Adjusted prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158253 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r--gcc/fortran/simplify.c1827
1 files changed, 749 insertions, 1078 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 50cd6da7591..b909b1c2add 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -26,10 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "arith.h"
#include "intrinsic.h"
#include "target-memory.h"
+#include "constructor.h"
-/* Savely advance an array constructor by 'n' elements.
- Mainly used by simplifiers of transformational intrinsics. */
-#define ADVANCE(ctor, n) do { int i; for (i = 0; i < n && ctor; ++i) ctor = ctor->next; } while (0)
gfc_expr gfc_bad_expr;
@@ -45,15 +43,12 @@ gfc_expr gfc_bad_expr;
be a part of the new expression.
NULL pointer indicating that no simplification was possible and
- the original expression should remain intact. If the
- simplification function sets the type and/or the function name
- via the pointer gfc_simple_expression, then this type is
- retained.
+ the original expression should remain intact.
An expression pointer to gfc_bad_expr (a static placeholder)
- indicating that some error has prevented simplification. For
- example, sqrt(-1.0). The error is generated within the function
- and should be propagated upwards
+ indicating that some error has prevented simplification. The
+ error is generated within the function and should be propagated
+ upwards
By the time a simplification function gets control, it has been
decided that the function call is really supposed to be the
@@ -62,7 +57,8 @@ gfc_expr gfc_bad_expr;
subroutine may have to look at the type of an argument as part of
its processing.
- Array arguments are never passed to these subroutines.
+ Array arguments are only passed to these subroutines that implement
+ the simplification of transformational intrinsics.
The functions in this file don't have much comment with them, but
everything is reasonably straight-forward. The Standard, chapter 13
@@ -136,20 +132,6 @@ get_kind (bt type, gfc_expr *k, const char *name, int default_kind)
}
-/* Helper function to get an integer constant with a kind number given
- by an integer constant expression. */
-static gfc_expr *
-int_expr_with_kind (int i, gfc_expr *kind, const char *name)
-{
- gfc_expr *res = gfc_int_expr (i);
- res->ts.kind = get_kind (BT_INTEGER, kind, name, gfc_default_integer_kind);
- if (res->ts.kind == -1)
- return NULL;
- else
- return res;
-}
-
-
/* Converts an mpz_t signed variable into an unsigned one, assuming
two's complement representations and a binary width of bitsize.
The conversion is a no-op unless x is negative; otherwise, it can
@@ -214,6 +196,27 @@ convert_mpz_to_signed (mpz_t x, int bitsize)
}
}
+
+/* In-place convert BOZ to REAL of the specified kind. */
+
+static gfc_expr *
+convert_boz (gfc_expr *x, int kind)
+{
+ if (x && x->ts.type == BT_INTEGER && x->is_boz)
+ {
+ gfc_typespec ts;
+ gfc_clear_ts (&ts);
+ ts.type = BT_REAL;
+ ts.kind = kind;
+
+ if (!gfc_convert_boz (x, &ts))
+ return &gfc_bad_expr;
+ }
+
+ return x;
+}
+
+
/* Test that the expression is an constant array. */
static bool
@@ -227,7 +230,8 @@ is_constant_array_expr (gfc_expr *e)
if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
return false;
- for (c = e->value.constructor; c; c = c->next)
+ for (c = gfc_constructor_first (e->value.constructor);
+ c; c = gfc_constructor_next (c))
if (c->expr->expr_type != EXPR_CONSTANT)
return false;
@@ -242,11 +246,11 @@ init_result_expr (gfc_expr *e, int init, gfc_expr *array)
{
if (e && e->expr_type == EXPR_ARRAY)
{
- gfc_constructor *ctor = e->value.constructor;
+ gfc_constructor *ctor = gfc_constructor_first (e->value.constructor);
while (ctor)
{
init_result_expr (ctor->expr, init, array);
- ctor = ctor->next;
+ ctor = gfc_constructor_next (ctor);
}
}
else if (e && e->expr_type == EXPR_CONSTANT)
@@ -324,18 +328,18 @@ init_result_expr (gfc_expr *e, int init, gfc_expr *array)
/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul. */
static gfc_expr *
-compute_dot_product (gfc_constructor *ctor_a, int stride_a,
- gfc_constructor *ctor_b, int stride_b)
+compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a,
+ gfc_expr *matrix_b, int stride_b, int offset_b)
{
- gfc_expr *result;
- gfc_expr *a = ctor_a->expr, *b = ctor_b->expr;
-
- gcc_assert (gfc_compare_types (&a->ts, &b->ts));
+ gfc_expr *result, *a, *b;
- result = gfc_constant_result (a->ts.type, a->ts.kind, &a->where);
+ result = gfc_get_constant_expr (matrix_a->ts.type, matrix_a->ts.kind,
+ &matrix_a->where);
init_result_expr (result, 0, NULL);
- while (ctor_a && ctor_b)
+ a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
+ b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
+ while (a && b)
{
/* Copying of expressions is required as operands are free'd
by the gfc_arith routines. */
@@ -343,24 +347,27 @@ compute_dot_product (gfc_constructor *ctor_a, int stride_a,
{
case BT_LOGICAL:
result = gfc_or (result,
- gfc_and (gfc_copy_expr (ctor_a->expr),
- gfc_copy_expr (ctor_b->expr)));
+ gfc_and (gfc_copy_expr (a),
+ gfc_copy_expr (b)));
break;
case BT_INTEGER:
case BT_REAL:
case BT_COMPLEX:
result = gfc_add (result,
- gfc_multiply (gfc_copy_expr (ctor_a->expr),
- gfc_copy_expr (ctor_b->expr)));
+ gfc_multiply (gfc_copy_expr (a),
+ gfc_copy_expr (b)));
break;
default:
gcc_unreachable();
}
- ADVANCE (ctor_a, stride_a);
- ADVANCE (ctor_b, stride_b);
+ offset_a += stride_a;
+ a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
+
+ offset_b += stride_b;
+ b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
}
return result;
@@ -378,9 +385,9 @@ transformational_result (gfc_expr *array, gfc_expr *dim, bt type,
int i, nelem;
if (!dim || array->rank == 1)
- return gfc_constant_result (type, kind, where);
+ return gfc_get_constant_expr (type, kind, where);
- result = gfc_start_constructor (type, kind, where);
+ result = gfc_get_array_expr (type, kind, where);
result->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
result->rank = array->rank - 1;
@@ -392,8 +399,9 @@ transformational_result (gfc_expr *array, gfc_expr *dim, bt type,
for (i = 0; i < nelem; ++i)
{
- gfc_expr *e = gfc_constant_result (type, kind, where);
- gfc_append_constructor (result, e);
+ gfc_constructor_append_expr (&result->value.constructor,
+ gfc_get_constant_expr (type, kind, where),
+ NULL);
}
return result;
@@ -446,21 +454,21 @@ simplify_transformation_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *
&& !mask->value.logical)
return result;
- array_ctor = array->value.constructor;
+ array_ctor = gfc_constructor_first (array->value.constructor);
mask_ctor = NULL;
if (mask && mask->expr_type == EXPR_ARRAY)
- mask_ctor = mask->value.constructor;
+ mask_ctor = gfc_constructor_first (mask->value.constructor);
while (array_ctor)
{
a = array_ctor->expr;
- array_ctor = array_ctor->next;
+ array_ctor = gfc_constructor_next (array_ctor);
/* A constant MASK equals .TRUE. here and can be ignored. */
if (mask_ctor)
{
m = mask_ctor->expr;
- mask_ctor = mask_ctor->next;
+ mask_ctor = gfc_constructor_next (mask_ctor);
if (!m->value.logical)
continue;
}
@@ -505,22 +513,22 @@ simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *d
arrayvec = (gfc_expr**) gfc_getmem (sizeof (gfc_expr*) * arraysize);
- array_ctor = array->value.constructor;
+ array_ctor = gfc_constructor_first (array->value.constructor);
mask_ctor = NULL;
if (mask && mask->expr_type == EXPR_ARRAY)
- mask_ctor = mask->value.constructor;
+ mask_ctor = gfc_constructor_first (mask->value.constructor);
for (i = 0; i < arraysize; ++i)
{
arrayvec[i] = array_ctor->expr;
- array_ctor = array_ctor->next;
+ array_ctor = gfc_constructor_next (array_ctor);
if (mask_ctor)
{
if (!mask_ctor->expr->value.logical)
arrayvec[i] = NULL;
- mask_ctor = mask_ctor->next;
+ mask_ctor = gfc_constructor_next (mask_ctor);
}
}
@@ -530,11 +538,11 @@ simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *d
mpz_clear (size);
resultvec = (gfc_expr**) gfc_getmem (sizeof (gfc_expr*) * resultsize);
- result_ctor = result->value.constructor;
+ result_ctor = gfc_constructor_first (result->value.constructor);
for (i = 0; i < resultsize; ++i)
{
resultvec[i] = result_ctor->expr;
- result_ctor = result_ctor->next;
+ result_ctor = gfc_constructor_next (result_ctor);
}
gfc_extract_int (dim, &dim_index);
@@ -592,11 +600,11 @@ simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *d
}
/* Place updated expression in result constructor. */
- result_ctor = result->value.constructor;
+ result_ctor = gfc_constructor_first (result->value.constructor);
for (i = 0; i < resultsize; ++i)
{
result_ctor->expr = resultvec[i];
- result_ctor = result_ctor->next;
+ result_ctor = gfc_constructor_next (result_ctor);
}
gfc_free (arrayvec);
@@ -618,36 +626,25 @@ gfc_simplify_abs (gfc_expr *e)
switch (e->ts.type)
{
- case BT_INTEGER:
- result = gfc_constant_result (BT_INTEGER, e->ts.kind, &e->where);
-
- mpz_abs (result->value.integer, e->value.integer);
-
- result = range_check (result, "IABS");
- break;
-
- case BT_REAL:
- result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
-
- mpfr_abs (result->value.real, e->value.real, GFC_RND_MODE);
-
- result = range_check (result, "ABS");
- break;
-
- case BT_COMPLEX:
- result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+ case BT_INTEGER:
+ result = gfc_get_constant_expr (BT_INTEGER, e->ts.kind, &e->where);
+ mpz_abs (result->value.integer, e->value.integer);
+ return range_check (result, "IABS");
- gfc_set_model_kind (e->ts.kind);
+ case BT_REAL:
+ result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
+ mpfr_abs (result->value.real, e->value.real, GFC_RND_MODE);
+ return range_check (result, "ABS");
- mpc_abs (result->value.real, e->value.complex, GFC_RND_MODE);
- result = range_check (result, "CABS");
- break;
+ case BT_COMPLEX:
+ gfc_set_model_kind (e->ts.kind);
+ result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
+ mpc_abs (result->value.real, e->value.complex, GFC_RND_MODE);
+ return range_check (result, "CABS");
- default:
- gfc_internal_error ("gfc_simplify_abs(): Bad type");
+ default:
+ gfc_internal_error ("gfc_simplify_abs(): Bad type");
}
-
- return result;
}
@@ -697,11 +694,9 @@ simplify_achar_char (gfc_expr *e, gfc_expr *k, const char *name, bool ascii)
return &gfc_bad_expr;
}
- result = gfc_constant_result (BT_CHARACTER, kind, &e->where);
- result->value.character.string = gfc_get_wide_string (2);
- result->value.character.length = 1;
+ result = gfc_get_character_expr (kind, &e->where, NULL, 1);
result->value.character.string[0] = mpz_get_ui (e->value.integer);
- result->value.character.string[1] = '\0'; /* For debugger */
+
return result;
}
@@ -735,18 +730,19 @@ gfc_simplify_acos (gfc_expr *x)
&x->where);
return &gfc_bad_expr;
}
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_acos (result->value.real, x->value.real, GFC_RND_MODE);
break;
+
case BT_COMPLEX:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpc_acos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
break;
+
default:
gfc_internal_error ("in gfc_simplify_acos(): Bad type");
}
-
return range_check (result, "ACOS");
}
@@ -768,13 +764,15 @@ gfc_simplify_acosh (gfc_expr *x)
return &gfc_bad_expr;
}
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_acosh (result->value.real, x->value.real, GFC_RND_MODE);
break;
+
case BT_COMPLEX:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpc_acosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
break;
+
default:
gfc_internal_error ("in gfc_simplify_acosh(): Bad type");
}
@@ -794,11 +792,6 @@ gfc_simplify_adjustl (gfc_expr *e)
len = e->value.character.length;
- result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
-
- result->value.character.length = len;
- result->value.character.string = gfc_get_wide_string (len + 1);
-
for (count = 0, i = 0; i < len; ++i)
{
ch = e->value.character.string[i];
@@ -807,14 +800,10 @@ gfc_simplify_adjustl (gfc_expr *e)
++count;
}
+ result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
for (i = 0; i < len - count; ++i)
result->value.character.string[i] = e->value.character.string[count + i];
- for (i = len - count; i < len; ++i)
- result->value.character.string[i] = ' ';
-
- result->value.character.string[len] = '\0'; /* For debugger */
-
return result;
}
@@ -831,11 +820,6 @@ gfc_simplify_adjustr (gfc_expr *e)
len = e->value.character.length;
- result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
-
- result->value.character.length = len;
- result->value.character.string = gfc_get_wide_string (len + 1);
-
for (count = 0, i = len - 1; i >= 0; --i)
{
ch = e->value.character.string[i];
@@ -844,14 +828,13 @@ gfc_simplify_adjustr (gfc_expr *e)
++count;
}
+ result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
for (i = 0; i < count; ++i)
result->value.character.string[i] = ' ';
for (i = count; i < len; ++i)
result->value.character.string[i] = e->value.character.string[i - count];
- result->value.character.string[len] = '\0'; /* For debugger */
-
return result;
}
@@ -864,7 +847,7 @@ gfc_simplify_aimag (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
mpfr_set (result->value.real, mpc_imagref (e->value.complex), GFC_RND_MODE);
return range_check (result, "AIMAG");
@@ -885,10 +868,10 @@ gfc_simplify_aint (gfc_expr *e, gfc_expr *k)
return NULL;
rtrunc = gfc_copy_expr (e);
-
mpfr_trunc (rtrunc->value.real, e->value.real);
result = gfc_real2real (rtrunc, kind);
+
gfc_free_expr (rtrunc);
return range_check (result, "AINT");
@@ -923,10 +906,10 @@ gfc_simplify_dint (gfc_expr *e)
return NULL;
rtrunc = gfc_copy_expr (e);
-
mpfr_trunc (rtrunc->value.real, e->value.real);
result = gfc_real2real (rtrunc, gfc_default_double_kind);
+
gfc_free_expr (rtrunc);
return range_check (result, "DINT");
@@ -946,8 +929,7 @@ gfc_simplify_anint (gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (e->ts.type, kind, &e->where);
-
+ result = gfc_get_constant_expr (e->ts.type, kind, &e->where);
mpfr_round (result->value.real, e->value.real);
return range_check (result, "ANINT");
@@ -964,17 +946,20 @@ gfc_simplify_and (gfc_expr *x, gfc_expr *y)
return NULL;
kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
- if (x->ts.type == BT_INTEGER)
- {
- result = gfc_constant_result (BT_INTEGER, kind, &x->where);
- mpz_and (result->value.integer, x->value.integer, y->value.integer);
- return range_check (result, "AND");
- }
- else /* BT_LOGICAL */
+
+ switch (x->ts.type)
{
- result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
- result->value.logical = x->value.logical && y->value.logical;
- return result;
+ case BT_INTEGER:
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
+ mpz_and (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "AND");
+
+ case BT_LOGICAL:
+ return gfc_get_logical_expr (kind, &x->where,
+ x->value.logical && y->value.logical);
+
+ default:
+ gcc_unreachable ();
}
}
@@ -1006,8 +991,7 @@ gfc_simplify_dnint (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, gfc_default_double_kind, &e->where);
-
+ result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &e->where);
mpfr_round (result->value.real, e->value.real);
return range_check (result, "DNINT");
@@ -1032,13 +1016,15 @@ gfc_simplify_asin (gfc_expr *x)
&x->where);
return &gfc_bad_expr;
}
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_asin (result->value.real, x->value.real, GFC_RND_MODE);
break;
+
case BT_COMPLEX:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpc_asin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
break;
+
default:
gfc_internal_error ("in gfc_simplify_asin(): Bad type");
}
@@ -1055,16 +1041,18 @@ gfc_simplify_asinh (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
+
switch (x->ts.type)
{
case BT_REAL:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
mpfr_asinh (result->value.real, x->value.real, GFC_RND_MODE);
break;
+
case BT_COMPLEX:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
mpc_asinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
break;
+
default:
gfc_internal_error ("in gfc_simplify_asinh(): Bad type");
}
@@ -1080,17 +1068,19 @@ gfc_simplify_atan (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
-
+
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
+
switch (x->ts.type)
{
case BT_REAL:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
mpfr_atan (result->value.real, x->value.real, GFC_RND_MODE);
break;
+
case BT_COMPLEX:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
mpc_atan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
break;
+
default:
gfc_internal_error ("in gfc_simplify_atan(): Bad type");
}
@@ -1117,14 +1107,15 @@ gfc_simplify_atanh (gfc_expr *x)
"to 1", &x->where);
return &gfc_bad_expr;
}
-
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_atanh (result->value.real, x->value.real, GFC_RND_MODE);
break;
+
case BT_COMPLEX:
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpc_atanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
break;
+
default:
gfc_internal_error ("in gfc_simplify_atanh(): Bad type");
}
@@ -1148,8 +1139,7 @@ gfc_simplify_atan2 (gfc_expr *y, gfc_expr *x)
return &gfc_bad_expr;
}
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_atan2 (result->value.real, y->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "ATAN2");
@@ -1157,14 +1147,14 @@ gfc_simplify_atan2 (gfc_expr *y, gfc_expr *x)
gfc_expr *
-gfc_simplify_bessel_j0 (gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_bessel_j0 (gfc_expr *x)
{
gfc_expr *result;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_j0 (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "BESSEL_J0");
@@ -1172,14 +1162,14 @@ gfc_simplify_bessel_j0 (gfc_expr *x ATTRIBUTE_UNUSED)
gfc_expr *
-gfc_simplify_bessel_j1 (gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_bessel_j1 (gfc_expr *x)
{
gfc_expr *result;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_j1 (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "BESSEL_J1");
@@ -1187,8 +1177,7 @@ gfc_simplify_bessel_j1 (gfc_expr *x ATTRIBUTE_UNUSED)
gfc_expr *
-gfc_simplify_bessel_jn (gfc_expr *order ATTRIBUTE_UNUSED,
- gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_bessel_jn (gfc_expr *order, gfc_expr *x)
{
gfc_expr *result;
long n;
@@ -1197,7 +1186,7 @@ gfc_simplify_bessel_jn (gfc_expr *order ATTRIBUTE_UNUSED,
return NULL;
n = mpz_get_si (order->value.integer);
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_jn (result->value.real, n, x->value.real, GFC_RND_MODE);
return range_check (result, "BESSEL_JN");
@@ -1205,14 +1194,14 @@ gfc_simplify_bessel_jn (gfc_expr *order ATTRIBUTE_UNUSED,
gfc_expr *
-gfc_simplify_bessel_y0 (gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_bessel_y0 (gfc_expr *x)
{
gfc_expr *result;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_y0 (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "BESSEL_Y0");
@@ -1220,14 +1209,14 @@ gfc_simplify_bessel_y0 (gfc_expr *x ATTRIBUTE_UNUSED)
gfc_expr *
-gfc_simplify_bessel_y1 (gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_bessel_y1 (gfc_expr *x)
{
gfc_expr *result;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_y1 (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "BESSEL_Y1");
@@ -1235,8 +1224,7 @@ gfc_simplify_bessel_y1 (gfc_expr *x ATTRIBUTE_UNUSED)
gfc_expr *
-gfc_simplify_bessel_yn (gfc_expr *order ATTRIBUTE_UNUSED,
- gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_bessel_yn (gfc_expr *order, gfc_expr *x)
{
gfc_expr *result;
long n;
@@ -1245,7 +1233,7 @@ gfc_simplify_bessel_yn (gfc_expr *order ATTRIBUTE_UNUSED,
return NULL;
n = mpz_get_si (order->value.integer);
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_yn (result->value.real, n, x->value.real, GFC_RND_MODE);
return range_check (result, "BESSEL_YN");
@@ -1255,14 +1243,9 @@ gfc_simplify_bessel_yn (gfc_expr *order ATTRIBUTE_UNUSED,
gfc_expr *
gfc_simplify_bit_size (gfc_expr *e)
{
- gfc_expr *result;
- int i;
-
- i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
- result = gfc_constant_result (BT_INTEGER, e->ts.kind, &e->where);
- mpz_set_ui (result->value.integer, gfc_integer_kinds[i].bit_size);
-
- return result;
+ int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
+ return gfc_get_int_expr (e->ts.kind, &e->where,
+ gfc_integer_kinds[i].bit_size);
}
@@ -1275,9 +1258,10 @@ gfc_simplify_btest (gfc_expr *e, gfc_expr *bit)
return NULL;
if (gfc_extract_int (bit, &b) != NULL || b < 0)
- return gfc_logical_expr (0, &e->where);
+ return gfc_get_logical_expr (gfc_default_logical_kind, &e->where, false);
- return gfc_logical_expr (mpz_tstbit (e->value.integer, b), &e->where);
+ return gfc_get_logical_expr (gfc_default_logical_kind, &e->where,
+ mpz_tstbit (e->value.integer, b));
}
@@ -1294,11 +1278,10 @@ gfc_simplify_ceiling (gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, kind, &e->where);
-
ceil = gfc_copy_expr (e);
-
mpfr_ceil (ceil->value.real, e->value.real);
+
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
gfc_mpfr_to_mpz (result->value.integer, ceil->value.real, &e->where);
gfc_free_expr (ceil);
@@ -1314,117 +1297,75 @@ gfc_simplify_char (gfc_expr *e, gfc_expr *k)
}
-/* Common subroutine for simplifying CMPLX and DCMPLX. */
+/* Common subroutine for simplifying CMPLX, COMPLEX and DCMPLX. */
static gfc_expr *
simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind)
{
gfc_expr *result;
- result = gfc_constant_result (BT_COMPLEX, kind, &x->where);
+ if (convert_boz (x, kind) == &gfc_bad_expr)
+ return &gfc_bad_expr;
+
+ if (convert_boz (y, kind) == &gfc_bad_expr)
+ return &gfc_bad_expr;
+
+ if (x->expr_type != EXPR_CONSTANT
+ || (y != NULL && y->expr_type != EXPR_CONSTANT))
+ return NULL;
+
+ result = gfc_get_constant_expr (BT_COMPLEX, kind, &x->where);
switch (x->ts.type)
{
- case BT_INTEGER:
- if (!x->is_boz)
+ case BT_INTEGER:
mpc_set_z (result->value.complex, x->value.integer, GFC_MPC_RND_MODE);
- break;
+ break;
- case BT_REAL:
- mpc_set_fr (result->value.complex, x->value.real, GFC_RND_MODE);
- break;
+ case BT_REAL:
+ mpc_set_fr (result->value.complex, x->value.real, GFC_RND_MODE);
+ break;
- case BT_COMPLEX:
- mpc_set (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- break;
+ case BT_COMPLEX:
+ mpc_set (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
- default:
- gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (x)");
+ default:
+ gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (x)");
}
- if (y != NULL)
- {
- switch (y->ts.type)
- {
- case BT_INTEGER:
- if (!y->is_boz)
- mpfr_set_z (mpc_imagref (result->value.complex),
- y->value.integer, GFC_RND_MODE);
- break;
-
- case BT_REAL:
- mpfr_set (mpc_imagref (result->value.complex),
- y->value.real, GFC_RND_MODE);
- break;
+ if (!y)
+ return range_check (result, name);
- default:
- gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (y)");
- }
- }
-
- /* Handle BOZ. */
- if (x->is_boz)
+ switch (y->ts.type)
{
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.kind = result->ts.kind;
- ts.type = BT_REAL;
- if (!gfc_convert_boz (x, &ts))
- return &gfc_bad_expr;
- mpfr_set (mpc_realref (result->value.complex),
- x->value.real, GFC_RND_MODE);
- }
+ case BT_INTEGER:
+ mpfr_set_z (mpc_imagref (result->value.complex),
+ y->value.integer, GFC_RND_MODE);
+ break;
- if (y && y->is_boz)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.kind = result->ts.kind;
- ts.type = BT_REAL;
- if (!gfc_convert_boz (y, &ts))
- return &gfc_bad_expr;
- mpfr_set (mpc_imagref (result->value.complex),
- y->value.real, GFC_RND_MODE);
+ case BT_REAL:
+ mpfr_set (mpc_imagref (result->value.complex),
+ y->value.real, GFC_RND_MODE);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (y)");
}
return range_check (result, name);
}
-/* Function called when we won't simplify an expression like CMPLX (or
- COMPLEX or DCMPLX) but still want to convert BOZ arguments. */
-
-static gfc_expr *
-only_convert_cmplx_boz (gfc_expr *x, gfc_expr *y, int kind)
-{
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_REAL;
- ts.kind = kind;
-
- if (x->is_boz && !gfc_convert_boz (x, &ts))
- return &gfc_bad_expr;
-
- if (y && y->is_boz && !gfc_convert_boz (y, &ts))
- return &gfc_bad_expr;
-
- return NULL;
-}
-
-
gfc_expr *
gfc_simplify_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *k)
{
int kind;
- kind = get_kind (BT_REAL, k, "CMPLX", gfc_default_real_kind);
+ kind = get_kind (BT_REAL, k, "CMPLX", gfc_default_complex_kind);
if (kind == -1)
return &gfc_bad_expr;
- if (x->expr_type != EXPR_CONSTANT
- || (y != NULL && y->expr_type != EXPR_CONSTANT))
- return only_convert_cmplx_boz (x, y, kind);
-
return simplify_cmplx ("CMPLX", x, y, kind);
}
@@ -1434,24 +1375,16 @@ gfc_simplify_complex (gfc_expr *x, gfc_expr *y)
{
int kind;
- if (x->ts.type == BT_INTEGER)
- {
- if (y->ts.type == BT_INTEGER)
- kind = gfc_default_real_kind;
- else
- kind = y->ts.kind;
- }
+ if (x->ts.type == BT_INTEGER && y->ts.type == BT_INTEGER)
+ kind = gfc_default_complex_kind;
+ else if (x->ts.type == BT_REAL || y->ts.type == BT_INTEGER)
+ kind = x->ts.kind;
+ else if (x->ts.type == BT_INTEGER || y->ts.type == BT_REAL)
+ kind = y->ts.kind;
+ else if (x->ts.type == BT_REAL && y->ts.type == BT_REAL)
+ kind = (x->ts.kind > y->ts.kind) ? x->ts.kind : y->ts.kind;
else
- {
- if (y->ts.type == BT_REAL)
- kind = (x->ts.kind > y->ts.kind) ? x->ts.kind : y->ts.kind;
- else
- kind = x->ts.kind;
- }
-
- if (x->expr_type != EXPR_CONSTANT
- || (y != NULL && y->expr_type != EXPR_CONSTANT))
- return only_convert_cmplx_boz (x, y, kind);
+ gcc_unreachable ();
return simplify_cmplx ("COMPLEX", x, y, kind);
}
@@ -1467,6 +1400,7 @@ gfc_simplify_conjg (gfc_expr *e)
result = gfc_copy_expr (e);
mpc_conj (result->value.complex, result->value.complex, GFC_MPC_RND_MODE);
+
return range_check (result, "CONJG");
}
@@ -1479,23 +1413,24 @@ gfc_simplify_cos (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
switch (x->ts.type)
{
- case BT_REAL:
- mpfr_cos (result->value.real, x->value.real, GFC_RND_MODE);
- break;
- case BT_COMPLEX:
- gfc_set_model_kind (x->ts.kind);
- mpc_cos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- break;
- default:
- gfc_internal_error ("in gfc_simplify_cos(): Bad type");
+ case BT_REAL:
+ mpfr_cos (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
+
+ case BT_COMPLEX:
+ gfc_set_model_kind (x->ts.kind);
+ mpc_cos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
+
+ default:
+ gfc_internal_error ("in gfc_simplify_cos(): Bad type");
}
return range_check (result, "COS");
-
}
@@ -1507,14 +1442,21 @@ gfc_simplify_cosh (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
- if (x->ts.type == BT_REAL)
- mpfr_cosh (result->value.real, x->value.real, GFC_RND_MODE);
- else if (x->ts.type == BT_COMPLEX)
- mpc_cosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- else
- gcc_unreachable ();
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ mpfr_cosh (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
+
+ case BT_COMPLEX:
+ mpc_cosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
return range_check (result, "COSH");
}
@@ -1549,11 +1491,6 @@ gfc_simplify_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
gfc_expr *
gfc_simplify_dcmplx (gfc_expr *x, gfc_expr *y)
{
-
- if (x->expr_type != EXPR_CONSTANT
- || (y != NULL && y->expr_type != EXPR_CONSTANT))
- return only_convert_cmplx_boz (x, y, gfc_default_double_kind);
-
return simplify_cmplx ("DCMPLX", x, y, gfc_default_double_kind);
}
@@ -1566,38 +1503,12 @@ gfc_simplify_dble (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- switch (e->ts.type)
- {
- case BT_INTEGER:
- if (!e->is_boz)
- result = gfc_int2real (e, gfc_default_double_kind);
- break;
-
- case BT_REAL:
- result = gfc_real2real (e, gfc_default_double_kind);
- break;
-
- case BT_COMPLEX:
- result = gfc_complex2real (e, gfc_default_double_kind);
- break;
-
- default:
- gfc_internal_error ("gfc_simplify_dble(): bad type at %L", &e->where);
- }
+ if (convert_boz (e, gfc_default_double_kind) == &gfc_bad_expr)
+ return &gfc_bad_expr;
- if (e->ts.type == BT_INTEGER && e->is_boz)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_REAL;
- ts.kind = gfc_default_double_kind;
- result = gfc_copy_expr (e);
- if (!gfc_convert_boz (result, &ts))
- {
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
- }
+ result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind);
+ if (result == &gfc_bad_expr)
+ return &gfc_bad_expr;
return range_check (result, "DBLE");
}
@@ -1609,22 +1520,23 @@ gfc_simplify_digits (gfc_expr *x)
int i, digits;
i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
+
switch (x->ts.type)
{
- case BT_INTEGER:
- digits = gfc_integer_kinds[i].digits;
- break;
+ case BT_INTEGER:
+ digits = gfc_integer_kinds[i].digits;
+ break;
- case BT_REAL:
- case BT_COMPLEX:
- digits = gfc_real_kinds[i].digits;
- break;
+ case BT_REAL:
+ case BT_COMPLEX:
+ digits = gfc_real_kinds[i].digits;
+ break;
- default:
- gcc_unreachable ();
+ default:
+ gcc_unreachable ();
}
- return gfc_int_expr (digits);
+ return gfc_get_int_expr (gfc_default_integer_kind, NULL, digits);
}
@@ -1638,29 +1550,29 @@ gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
return NULL;
kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
- result = gfc_constant_result (x->ts.type, kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, kind, &x->where);
switch (x->ts.type)
{
- case BT_INTEGER:
- if (mpz_cmp (x->value.integer, y->value.integer) > 0)
- mpz_sub (result->value.integer, x->value.integer, y->value.integer);
- else
- mpz_set_ui (result->value.integer, 0);
+ case BT_INTEGER:
+ if (mpz_cmp (x->value.integer, y->value.integer) > 0)
+ mpz_sub (result->value.integer, x->value.integer, y->value.integer);
+ else
+ mpz_set_ui (result->value.integer, 0);
- break;
+ break;
- case BT_REAL:
- if (mpfr_cmp (x->value.real, y->value.real) > 0)
- mpfr_sub (result->value.real, x->value.real, y->value.real,
- GFC_RND_MODE);
- else
- mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
+ case BT_REAL:
+ if (mpfr_cmp (x->value.real, y->value.real) > 0)
+ mpfr_sub (result->value.real, x->value.real, y->value.real,
+ GFC_RND_MODE);
+ else
+ mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
- break;
+ break;
- default:
- gfc_internal_error ("gfc_simplify_dim(): Bad type");
+ default:
+ gfc_internal_error ("gfc_simplify_dim(): Bad type");
}
return range_check (result, "DIM");
@@ -1670,8 +1582,6 @@ gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
gfc_expr*
gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
{
- gfc_expr *result;
-
if (!is_constant_array_expr (vector_a)
|| !is_constant_array_expr (vector_b))
return NULL;
@@ -1680,16 +1590,7 @@ gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
gcc_assert (vector_b->rank == 1);
gcc_assert (gfc_compare_types (&vector_a->ts, &vector_b->ts));
- if (vector_a->value.constructor && vector_b->value.constructor)
- return compute_dot_product (vector_a->value.constructor, 1,
- vector_b->value.constructor, 1);
-
- /* Zero sized array ... */
- result = gfc_constant_result (vector_a->ts.type,
- vector_a->ts.kind,
- &vector_a->where);
- init_result_expr (result, 0, NULL);
- return result;
+ return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0);
}
@@ -1701,15 +1602,14 @@ gfc_simplify_dprod (gfc_expr *x, gfc_expr *y)
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, gfc_default_double_kind, &x->where);
-
a1 = gfc_real2real (x, gfc_default_double_kind);
a2 = gfc_real2real (y, gfc_default_double_kind);
+ result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &x->where);
mpfr_mul (result->value.real, a1->value.real, a2->value.real, GFC_RND_MODE);
- gfc_free_expr (a1);
gfc_free_expr (a2);
+ gfc_free_expr (a1);
return range_check (result, "DPROD");
}
@@ -1723,8 +1623,7 @@ gfc_simplify_erf (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_erf (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "ERF");
@@ -1739,8 +1638,7 @@ gfc_simplify_erfc (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_erfc (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "ERFC");
@@ -1871,7 +1769,7 @@ gfc_simplify_erfc_scaled (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
if (mpfr_cmp_d (x->value.real, ARG_LIMIT) >= 0)
asympt_erfc_scaled (result->value.real, x->value.real);
else
@@ -1892,8 +1790,7 @@ gfc_simplify_epsilon (gfc_expr *e)
i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
- result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
-
+ result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
mpfr_set (result->value.real, gfc_real_kinds[i].epsilon, GFC_RND_MODE);
return range_check (result, "EPSILON");
@@ -1908,21 +1805,21 @@ gfc_simplify_exp (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
switch (x->ts.type)
{
- case BT_REAL:
- mpfr_exp (result->value.real, x->value.real, GFC_RND_MODE);
- break;
+ case BT_REAL:
+ mpfr_exp (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
- case BT_COMPLEX:
- gfc_set_model_kind (x->ts.kind);
- mpc_exp (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- break;
+ case BT_COMPLEX:
+ gfc_set_model_kind (x->ts.kind);
+ mpc_exp (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
- default:
- gfc_internal_error ("in gfc_simplify_exp(): Bad type");
+ default:
+ gfc_internal_error ("in gfc_simplify_exp(): Bad type");
}
return range_check (result, "EXP");
@@ -1938,8 +1835,8 @@ gfc_simplify_exponent (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
- &x->where);
+ result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
+ &x->where);
gfc_set_model (x->value.real);
@@ -1966,21 +1863,14 @@ gfc_simplify_float (gfc_expr *a)
if (a->is_boz)
{
- gfc_typespec ts;
- gfc_clear_ts (&ts);
-
- ts.type = BT_REAL;
- ts.kind = gfc_default_real_kind;
+ if (convert_boz (a, gfc_default_real_kind) == &gfc_bad_expr)
+ return &gfc_bad_expr;
result = gfc_copy_expr (a);
- if (!gfc_convert_boz (result, &ts))
- {
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
}
else
result = gfc_int2real (a, gfc_default_real_kind);
+
return range_check (result, "FLOAT");
}
@@ -1999,12 +1889,12 @@ gfc_simplify_floor (gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, kind, &e->where);
-
gfc_set_model_kind (kind);
+
mpfr_init (floor);
mpfr_floor (floor, e->value.real);
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
gfc_mpfr_to_mpz (result->value.integer, floor, &e->where);
mpfr_clear (floor);
@@ -2022,7 +1912,7 @@ gfc_simplify_fraction (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
if (mpfr_sgn (x->value.real) == 0)
{
@@ -2059,8 +1949,7 @@ gfc_simplify_gamma (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_gamma (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "GAMMA");
@@ -2074,21 +1963,20 @@ gfc_simplify_huge (gfc_expr *e)
int i;
i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
-
- result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
switch (e->ts.type)
{
- case BT_INTEGER:
- mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
- break;
+ case BT_INTEGER:
+ mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
+ break;
- case BT_REAL:
- mpfr_set (result->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
- break;
+ case BT_REAL:
+ mpfr_set (result->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
+ break;
- default:
- gcc_unreachable ();
+ default:
+ gcc_unreachable ();
}
return result;
@@ -2103,7 +1991,7 @@ gfc_simplify_hypot (gfc_expr *x, gfc_expr *y)
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_hypot (result->value.real, x->value.real, y->value.real, GFC_RND_MODE);
return range_check (result, "HYPOT");
}
@@ -2117,6 +2005,7 @@ gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
{
gfc_expr *result;
gfc_char_t index;
+ int k;
if (e->expr_type != EXPR_CONSTANT)
return NULL;
@@ -2133,10 +2022,11 @@ gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
gfc_warning ("Argument of IACHAR function at %L outside of range 0..127",
&e->where);
- if ((result = int_expr_with_kind (index, kind, "IACHAR")) == NULL)
+ k = get_kind (BT_INTEGER, kind, "IACHAR", gfc_default_integer_kind);
+ if (k == -1)
return &gfc_bad_expr;
- result->where = e->where;
+ result = gfc_get_int_expr (k, &e->where, index);
return range_check (result, "IACHAR");
}
@@ -2150,8 +2040,7 @@ gfc_simplify_iand (gfc_expr *x, gfc_expr *y)
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
mpz_and (result->value.integer, x->value.integer, y->value.integer);
return range_check (result, "IAND");
@@ -2232,7 +2121,7 @@ gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_expr *z)
return &gfc_bad_expr;
}
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
convert_mpz_to_unsigned (result->value.integer,
gfc_integer_kinds[k].bit_size);
@@ -2306,6 +2195,7 @@ gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
{
gfc_expr *result;
gfc_char_t index;
+ int k;
if (e->expr_type != EXPR_CONSTANT)
return NULL;
@@ -2318,10 +2208,12 @@ gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
index = e->value.character.string[0];
- if ((result = int_expr_with_kind (index, kind, "ICHAR")) == NULL)
+ k = get_kind (BT_INTEGER, kind, "ICHAR", gfc_default_integer_kind);
+ if (k == -1)
return &gfc_bad_expr;
- result->where = e->where;
+ result = gfc_get_int_expr (k, &e->where, index);
+
return range_check (result, "ICHAR");
}
@@ -2334,8 +2226,7 @@ gfc_simplify_ieor (gfc_expr *x, gfc_expr *y)
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
mpz_xor (result->value.integer, x->value.integer, y->value.integer);
return range_check (result, "IEOR");
@@ -2362,7 +2253,7 @@ gfc_simplify_index (gfc_expr *x, gfc_expr *y, gfc_expr *b, gfc_expr *kind)
if (k == -1)
return &gfc_bad_expr;
- result = gfc_constant_result (BT_INTEGER, k, &x->where);
+ result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);
len = x->value.character.length;
lensub = y->value.character.length;
@@ -2487,73 +2378,34 @@ done:
}
-gfc_expr *
-gfc_simplify_int (gfc_expr *e, gfc_expr *k)
+static gfc_expr *
+simplify_intconv (gfc_expr *e, int kind, const char *name)
{
gfc_expr *result = NULL;
- int kind;
-
- kind = get_kind (BT_INTEGER, k, "INT", gfc_default_integer_kind);
- if (kind == -1)
- return &gfc_bad_expr;
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- switch (e->ts.type)
- {
- case BT_INTEGER:
- result = gfc_int2int (e, kind);
- break;
-
- case BT_REAL:
- result = gfc_real2int (e, kind);
- break;
-
- case BT_COMPLEX:
- result = gfc_complex2int (e, kind);
- break;
-
- default:
- gfc_error ("Argument of INT at %L is not a valid type", &e->where);
- return &gfc_bad_expr;
- }
+ result = gfc_convert_constant (e, BT_INTEGER, kind);
+ if (result == &gfc_bad_expr)
+ return &gfc_bad_expr;
- return range_check (result, "INT");
+ return range_check (result, name);
}
-static gfc_expr *
-simplify_intconv (gfc_expr *e, int kind, const char *name)
+gfc_expr *
+gfc_simplify_int (gfc_expr *e, gfc_expr *k)
{
- gfc_expr *result = NULL;
-
- if (e->expr_type != EXPR_CONSTANT)
- return NULL;
-
- switch (e->ts.type)
- {
- case BT_INTEGER:
- result = gfc_int2int (e, kind);
- break;
-
- case BT_REAL:
- result = gfc_real2int (e, kind);
- break;
-
- case BT_COMPLEX:
- result = gfc_complex2int (e, kind);
- break;
+ int kind;
- default:
- gfc_error ("Argument of %s at %L is not a valid type", name, &e->where);
- return &gfc_bad_expr;
- }
+ kind = get_kind (BT_INTEGER, k, "INT", gfc_default_integer_kind);
+ if (kind == -1)
+ return &gfc_bad_expr;
- return range_check (result, name);
+ return simplify_intconv (e, kind, "INT");
}
-
gfc_expr *
gfc_simplify_int2 (gfc_expr *e)
{
@@ -2583,15 +2435,15 @@ gfc_simplify_ifix (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
- &e->where);
-
rtrunc = gfc_copy_expr (e);
-
mpfr_trunc (rtrunc->value.real, e->value.real);
+
+ result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
+ &e->where);
gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);
gfc_free_expr (rtrunc);
+
return range_check (result, "IFIX");
}
@@ -2604,15 +2456,15 @@ gfc_simplify_idint (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
- &e->where);
-
rtrunc = gfc_copy_expr (e);
-
mpfr_trunc (rtrunc->value.real, e->value.real);
+
+ result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
+ &e->where);
gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);
gfc_free_expr (rtrunc);
+
return range_check (result, "IDINT");
}
@@ -2625,9 +2477,9 @@ gfc_simplify_ior (gfc_expr *x, gfc_expr *y)
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
mpz_ior (result->value.integer, x->value.integer, y->value.integer);
+
return range_check (result, "IOR");
}
@@ -2635,48 +2487,35 @@ gfc_simplify_ior (gfc_expr *x, gfc_expr *y)
gfc_expr *
gfc_simplify_is_iostat_end (gfc_expr *x)
{
- gfc_expr *result;
-
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind,
- &x->where);
- result->value.logical = (mpz_cmp_si (x->value.integer, LIBERROR_END) == 0);
-
- return result;
+ return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
+ mpz_cmp_si (x->value.integer,
+ LIBERROR_END) == 0);
}
gfc_expr *
gfc_simplify_is_iostat_eor (gfc_expr *x)
{
- gfc_expr *result;
-
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind,
- &x->where);
- result->value.logical = (mpz_cmp_si (x->value.integer, LIBERROR_EOR) == 0);
-
- return result;
+ return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
+ mpz_cmp_si (x->value.integer,
+ LIBERROR_EOR) == 0);
}
gfc_expr *
gfc_simplify_isnan (gfc_expr *x)
{
- gfc_expr *result;
-
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind,
- &x->where);
- result->value.logical = mpfr_nan_p (x->value.real);
-
- return result;
+ return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
+ mpfr_nan_p (x->value.real));
}
@@ -2711,7 +2550,7 @@ gfc_simplify_ishft (gfc_expr *e, gfc_expr *s)
return &gfc_bad_expr;
}
- result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
if (shift == 0)
{
@@ -2814,7 +2653,7 @@ gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
return &gfc_bad_expr;
}
- result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
mpz_set (result->value.integer, e->value.integer);
@@ -2877,14 +2716,7 @@ gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
gfc_expr *
gfc_simplify_kind (gfc_expr *e)
{
-
- if (e->ts.type == BT_DERIVED)
- {
- gfc_error ("Argument of KIND at %L is a DERIVED type", &e->where);
- return &gfc_bad_expr;
- }
-
- return gfc_int_expr (e->ts.kind);
+ return gfc_get_int_expr (gfc_default_integer_kind, NULL, e->ts.kind);
}
@@ -2909,7 +2741,7 @@ simplify_bound_dim (gfc_expr *array, gfc_expr *kind, int d, int upper,
if (k == -1)
return &gfc_bad_expr;
- result = gfc_constant_result (BT_INTEGER, k, &array->where);
+ result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
/* Then, we need to know the extent of the given dimension. */
@@ -3016,7 +2848,6 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
/* Multi-dimensional bounds. */
gfc_expr *bounds[GFC_MAX_DIMENSIONS];
gfc_expr *e;
- gfc_constructor *head, *tail;
int k;
/* UBOUND(ARRAY) is not valid for an assumed-size array. */
@@ -3042,18 +2873,12 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
}
/* Allocate the result expression. */
- e = gfc_get_expr ();
- e->where = array->where;
- e->expr_type = EXPR_ARRAY;
- e->ts.type = BT_INTEGER;
k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
- gfc_default_integer_kind);
+ gfc_default_integer_kind);
if (k == -1)
- {
- gfc_free_expr (e);
- return &gfc_bad_expr;
- }
- e->ts.kind = k;
+ return &gfc_bad_expr;
+
+ e = gfc_get_array_expr (BT_INTEGER, k, &array->where);
/* The result is a rank 1 array; its size is the rank of the first
argument to {L,U}BOUND. */
@@ -3062,22 +2887,9 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
mpz_init_set_ui (e->shape[0], array->rank);
/* Create the constructor for this array. */
- head = tail = NULL;
for (d = 0; d < array->rank; d++)
- {
- /* Get a new constructor element. */
- if (head == NULL)
- head = tail = gfc_get_constructor ();
- else
- {
- tail->next = gfc_get_constructor ();
- tail = tail->next;
- }
-
- tail->where = e->where;
- tail->expr = bounds[d];
- }
- e->value.constructor = head;
+ gfc_constructor_append_expr (&e->value.constructor,
+ bounds[d], &e->where);
return e;
}
@@ -3111,7 +2923,6 @@ gfc_simplify_lbound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
gfc_expr *
gfc_simplify_leadz (gfc_expr *e)
{
- gfc_expr *result;
unsigned long lz, bs;
int i;
@@ -3127,11 +2938,7 @@ gfc_simplify_leadz (gfc_expr *e)
else
lz = bs - mpz_sizeinbase (e->value.integer, 2);
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
- &e->where);
- mpz_set_ui (result->value.integer, lz);
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, lz);
}
@@ -3146,33 +2953,20 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
if (e->expr_type == EXPR_CONSTANT)
{
- result = gfc_constant_result (BT_INTEGER, k, &e->where);
+ result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
mpz_set_si (result->value.integer, e->value.character.length);
- if (gfc_range_check (result) == ARITH_OK)
- return result;
- else
- {
- gfc_free_expr (result);
- return NULL;
- }
+ return range_check (result, "LEN");
}
-
- if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
- && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
- && e->ts.u.cl->length->ts.type == BT_INTEGER)
+ else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
+ && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
+ && e->ts.u.cl->length->ts.type == BT_INTEGER)
{
- result = gfc_constant_result (BT_INTEGER, k, &e->where);
+ result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
mpz_set (result->value.integer, e->ts.u.cl->length->value.integer);
- if (gfc_range_check (result) == ARITH_OK)
- return result;
- else
- {
- gfc_free_expr (result);
- return NULL;
- }
+ return range_check (result, "LEN");
}
-
- return NULL;
+ else
+ return NULL;
}
@@ -3180,7 +2974,7 @@ gfc_expr *
gfc_simplify_len_trim (gfc_expr *e, gfc_expr *kind)
{
gfc_expr *result;
- int count, len, lentrim, i;
+ int count, len, i;
int k = get_kind (BT_INTEGER, kind, "LEN_TRIM", gfc_default_integer_kind);
if (k == -1)
@@ -3189,23 +2983,19 @@ gfc_simplify_len_trim (gfc_expr *e, gfc_expr *kind)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, k, &e->where);
len = e->value.character.length;
-
for (count = 0, i = 1; i <= len; i++)
if (e->value.character.string[len - i] == ' ')
count++;
else
break;
- lentrim = len - count;
-
- mpz_set_si (result->value.integer, lentrim);
+ result = gfc_get_int_expr (k, &e->where, len - count);
return range_check (result, "LEN_TRIM");
}
gfc_expr *
-gfc_simplify_lgamma (gfc_expr *x ATTRIBUTE_UNUSED)
+gfc_simplify_lgamma (gfc_expr *x)
{
gfc_expr *result;
int sg;
@@ -3213,8 +3003,7 @@ gfc_simplify_lgamma (gfc_expr *x ATTRIBUTE_UNUSED)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_lgamma (result->value.real, &sg, x->value.real, GFC_RND_MODE);
return range_check (result, "LGAMMA");
@@ -3227,7 +3016,8 @@ gfc_simplify_lge (gfc_expr *a, gfc_expr *b)
if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
return NULL;
- return gfc_logical_expr (gfc_compare_string (a, b) >= 0, &a->where);
+ return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
+ gfc_compare_string (a, b) >= 0);
}
@@ -3237,8 +3027,8 @@ gfc_simplify_lgt (gfc_expr *a, gfc_expr *b)
if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
return NULL;
- return gfc_logical_expr (gfc_compare_string (a, b) > 0,
- &a->where);
+ return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
+ gfc_compare_string (a, b) > 0);
}
@@ -3248,7 +3038,8 @@ gfc_simplify_lle (gfc_expr *a, gfc_expr *b)
if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
return NULL;
- return gfc_logical_expr (gfc_compare_string (a, b) <= 0, &a->where);
+ return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
+ gfc_compare_string (a, b) <= 0);
}
@@ -3258,7 +3049,8 @@ gfc_simplify_llt (gfc_expr *a, gfc_expr *b)
if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
return NULL;
- return gfc_logical_expr (gfc_compare_string (a, b) < 0, &a->where);
+ return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
+ gfc_compare_string (a, b) < 0);
}
@@ -3270,8 +3062,7 @@ gfc_simplify_log (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
switch (x->ts.type)
{
@@ -3324,8 +3115,7 @@ gfc_simplify_log10 (gfc_expr *x)
return &gfc_bad_expr;
}
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
mpfr_log10 (result->value.real, x->value.real, GFC_RND_MODE);
return range_check (result, "LOG10");
@@ -3335,7 +3125,6 @@ gfc_simplify_log10 (gfc_expr *x)
gfc_expr *
gfc_simplify_logical (gfc_expr *e, gfc_expr *k)
{
- gfc_expr *result;
int kind;
kind = get_kind (BT_LOGICAL, k, "LOGICAL", gfc_default_logical_kind);
@@ -3345,11 +3134,7 @@ gfc_simplify_logical (gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_LOGICAL, kind, &e->where);
-
- result->value.logical = e->value.logical;
-
- return result;
+ return gfc_get_logical_expr (kind, &e->where, e->value.logical);
}
@@ -3357,17 +3142,17 @@ gfc_expr*
gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
{
gfc_expr *result;
- gfc_constructor *ma_ctor, *mb_ctor;
- int row, result_rows, col, result_columns, stride_a, stride_b;
+ int row, result_rows, col, result_columns;
+ int stride_a, offset_a, stride_b, offset_b;
if (!is_constant_array_expr (matrix_a)
|| !is_constant_array_expr (matrix_b))
return NULL;
gcc_assert (gfc_compare_types (&matrix_a->ts, &matrix_b->ts));
- result = gfc_start_constructor (matrix_a->ts.type,
- matrix_a->ts.kind,
- &matrix_a->where);
+ result = gfc_get_array_expr (matrix_a->ts.type,
+ matrix_a->ts.kind,
+ &matrix_a->where);
if (matrix_a->rank == 1 && matrix_b->rank == 2)
{
@@ -3406,25 +3191,22 @@ gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
else
gcc_unreachable();
- ma_ctor = matrix_a->value.constructor;
- mb_ctor = matrix_b->value.constructor;
-
+ offset_a = offset_b = 0;
for (col = 0; col < result_columns; ++col)
{
- ma_ctor = matrix_a->value.constructor;
+ offset_a = 0;
for (row = 0; row < result_rows; ++row)
{
- gfc_expr *e;
- e = compute_dot_product (ma_ctor, stride_a,
- mb_ctor, 1);
-
- gfc_append_constructor (result, e);
+ gfc_expr *e = compute_dot_product (matrix_a, stride_a, offset_a,
+ matrix_b, 1, offset_b);
+ gfc_constructor_append_expr (&result->value.constructor,
+ e, NULL);
- ADVANCE (ma_ctor, 1);
- }
+ offset_a += 1;
+ }
- ADVANCE (mb_ctor, stride_b);
+ offset_b += stride_b;
}
return result;
@@ -3584,26 +3366,25 @@ gfc_simplify_max (gfc_expr *e)
static gfc_expr *
simplify_minval_maxval (gfc_expr *expr, int sign)
{
- gfc_constructor *ctr, *extremum;
+ gfc_constructor *c, *extremum;
gfc_intrinsic_sym * specific;
extremum = NULL;
specific = expr->value.function.isym;
- ctr = expr->value.constructor;
-
- for (; ctr; ctr = ctr->next)
+ for (c = gfc_constructor_first (expr->value.constructor);
+ c; c = gfc_constructor_next (c))
{
- if (ctr->expr->expr_type != EXPR_CONSTANT)
+ if (c->expr->expr_type != EXPR_CONSTANT)
return NULL;
if (extremum == NULL)
{
- extremum = ctr;
+ extremum = c;
continue;
}
- min_max_choose (ctr->expr, extremum->expr, sign);
+ min_max_choose (c->expr, extremum->expr, sign);
}
if (extremum == NULL)
@@ -3627,7 +3408,7 @@ gfc_simplify_minval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
{
if (array->expr_type != EXPR_ARRAY || array->rank != 1 || dim || mask)
return NULL;
-
+
return simplify_minval_maxval (array, -1);
}
@@ -3637,6 +3418,7 @@ gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
{
if (array->expr_type != EXPR_ARRAY || array->rank != 1 || dim || mask)
return NULL;
+
return simplify_minval_maxval (array, 1);
}
@@ -3644,30 +3426,18 @@ gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
gfc_expr *
gfc_simplify_maxexponent (gfc_expr *x)
{
- gfc_expr *result;
- int i;
-
- i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
-
- result = gfc_int_expr (gfc_real_kinds[i].max_exponent);
- result->where = x->where;
-
- return result;
+ int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
+ return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
+ gfc_real_kinds[i].max_exponent);
}
gfc_expr *
gfc_simplify_minexponent (gfc_expr *x)
{
- gfc_expr *result;
- int i;
-
- i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
-
- result = gfc_int_expr (gfc_real_kinds[i].min_exponent);
- result->where = x->where;
-
- return result;
+ int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
+ return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
+ gfc_real_kinds[i].min_exponent);
}
@@ -3682,41 +3452,41 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
return NULL;
kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
- result = gfc_constant_result (a->ts.type, kind, &a->where);
+ result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
switch (a->ts.type)
{
- case BT_INTEGER:
- if (mpz_cmp_ui (p->value.integer, 0) == 0)
- {
- /* Result is processor-dependent. */
- gfc_error ("Second argument MOD at %L is zero", &a->where);
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
- mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
- break;
+ case BT_INTEGER:
+ if (mpz_cmp_ui (p->value.integer, 0) == 0)
+ {
+ /* Result is processor-dependent. */
+ gfc_error ("Second argument MOD at %L is zero", &a->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
+ break;
- case BT_REAL:
- if (mpfr_cmp_ui (p->value.real, 0) == 0)
- {
- /* Result is processor-dependent. */
- gfc_error ("Second argument of MOD at %L is zero", &p->where);
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
+ case BT_REAL:
+ if (mpfr_cmp_ui (p->value.real, 0) == 0)
+ {
+ /* Result is processor-dependent. */
+ gfc_error ("Second argument of MOD at %L is zero", &p->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
- gfc_set_model_kind (kind);
- mpfr_init (tmp);
- mpfr_div (tmp, a->value.real, p->value.real, GFC_RND_MODE);
- mpfr_trunc (tmp, tmp);
- mpfr_mul (tmp, tmp, p->value.real, GFC_RND_MODE);
- mpfr_sub (result->value.real, a->value.real, tmp, GFC_RND_MODE);
- mpfr_clear (tmp);
- break;
+ gfc_set_model_kind (kind);
+ mpfr_init (tmp);
+ mpfr_div (tmp, a->value.real, p->value.real, GFC_RND_MODE);
+ mpfr_trunc (tmp, tmp);
+ mpfr_mul (tmp, tmp, p->value.real, GFC_RND_MODE);
+ mpfr_sub (result->value.real, a->value.real, tmp, GFC_RND_MODE);
+ mpfr_clear (tmp);
+ break;
- default:
- gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
+ default:
+ gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
}
return range_check (result, "MOD");
@@ -3734,43 +3504,43 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
return NULL;
kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
- result = gfc_constant_result (a->ts.type, kind, &a->where);
+ result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
switch (a->ts.type)
{
- case BT_INTEGER:
- if (mpz_cmp_ui (p->value.integer, 0) == 0)
- {
- /* Result is processor-dependent. This processor just opts
- to not handle it at all. */
- gfc_error ("Second argument of MODULO at %L is zero", &a->where);
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
- mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
+ case BT_INTEGER:
+ if (mpz_cmp_ui (p->value.integer, 0) == 0)
+ {
+ /* Result is processor-dependent. This processor just opts
+ to not handle it at all. */
+ gfc_error ("Second argument of MODULO at %L is zero", &a->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
- break;
+ break;
- case BT_REAL:
- if (mpfr_cmp_ui (p->value.real, 0) == 0)
- {
- /* Result is processor-dependent. */
- gfc_error ("Second argument of MODULO at %L is zero", &p->where);
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
+ case BT_REAL:
+ if (mpfr_cmp_ui (p->value.real, 0) == 0)
+ {
+ /* Result is processor-dependent. */
+ gfc_error ("Second argument of MODULO at %L is zero", &p->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
- gfc_set_model_kind (kind);
- mpfr_init (tmp);
- mpfr_div (tmp, a->value.real, p->value.real, GFC_RND_MODE);
- mpfr_floor (tmp, tmp);
- mpfr_mul (tmp, tmp, p->value.real, GFC_RND_MODE);
- mpfr_sub (result->value.real, a->value.real, tmp, GFC_RND_MODE);
- mpfr_clear (tmp);
- break;
+ gfc_set_model_kind (kind);
+ mpfr_init (tmp);
+ mpfr_div (tmp, a->value.real, p->value.real, GFC_RND_MODE);
+ mpfr_floor (tmp, tmp);
+ mpfr_mul (tmp, tmp, p->value.real, GFC_RND_MODE);
+ mpfr_sub (result->value.real, a->value.real, tmp, GFC_RND_MODE);
+ mpfr_clear (tmp);
+ break;
- default:
- gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
+ default:
+ gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
}
return range_check (result, "MODULO");
@@ -3859,12 +3629,10 @@ simplify_nint (const char *name, gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_INTEGER, kind, &e->where);
-
itrunc = gfc_copy_expr (e);
-
mpfr_round (itrunc->value.real, e->value.real);
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real, &e->where);
gfc_free_expr (itrunc);
@@ -3878,11 +3646,9 @@ gfc_simplify_new_line (gfc_expr *e)
{
gfc_expr *result;
- result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
- result->value.character.string = gfc_get_wide_string (2);
- result->value.character.length = 1;
+ result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, 1);
result->value.character.string[0] = '\n';
- result->value.character.string[1] = '\0'; /* For debugger */
+
return result;
}
@@ -3909,8 +3675,7 @@ gfc_simplify_not (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
-
+ result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
mpz_com (result->value.integer, e->value.integer);
return range_check (result, "NOT");
@@ -3922,14 +3687,13 @@ gfc_simplify_null (gfc_expr *mold)
{
gfc_expr *result;
- if (mold == NULL)
+ if (mold)
{
- result = gfc_get_expr ();
- result->ts.type = BT_UNKNOWN;
+ result = gfc_copy_expr (mold);
+ result->expr_type = EXPR_NULL;
}
else
- result = gfc_copy_expr (mold);
- result->expr_type = EXPR_NULL;
+ result = gfc_get_null_expr (NULL);
return result;
}
@@ -3940,7 +3704,8 @@ gfc_simplify_num_images (void)
{
gfc_expr *result;
/* FIXME: gfc_current_locus is wrong. */
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind, &gfc_current_locus);
+ result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
+ &gfc_current_locus);
mpz_set_si (result->value.integer, 1);
return result;
}
@@ -3956,17 +3721,19 @@ gfc_simplify_or (gfc_expr *x, gfc_expr *y)
return NULL;
kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
- if (x->ts.type == BT_INTEGER)
- {
- result = gfc_constant_result (BT_INTEGER, kind, &x->where);
- mpz_ior (result->value.integer, x->value.integer, y->value.integer);
- return range_check (result, "OR");
- }
- else /* BT_LOGICAL */
+
+ switch (x->ts.type)
{
- result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
- result->value.logical = x->value.logical || y->value.logical;
- return result;
+ case BT_INTEGER:
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
+ mpz_ior (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "OR");
+
+ case BT_LOGICAL:
+ return gfc_get_logical_expr (kind, &x->where,
+ x->value.logical || y->value.logical);
+ default:
+ gcc_unreachable();
}
}
@@ -3983,12 +3750,12 @@ gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
&& !is_constant_array_expr(mask)))
return NULL;
- result = gfc_start_constructor (array->ts.type,
- array->ts.kind,
- &array->where);
+ result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
- array_ctor = array->value.constructor;
- vector_ctor = vector ? vector->value.constructor : NULL;
+ array_ctor = gfc_constructor_first (array->value.constructor);
+ vector_ctor = vector
+ ? gfc_constructor_first (vector->value.constructor)
+ : NULL;
if (mask->expr_type == EXPR_CONSTANT
&& mask->value.logical)
@@ -3996,38 +3763,41 @@ gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
/* Copy all elements of ARRAY to RESULT. */
while (array_ctor)
{
- gfc_append_constructor (result,
- gfc_copy_expr (array_ctor->expr));
+ gfc_constructor_append_expr (&result->value.constructor,
+ gfc_copy_expr (array_ctor->expr),
+ NULL);
- ADVANCE (array_ctor, 1);
- ADVANCE (vector_ctor, 1);
+ array_ctor = gfc_constructor_next (array_ctor);
+ vector_ctor = gfc_constructor_next (vector_ctor);
}
}
else if (mask->expr_type == EXPR_ARRAY)
{
/* Copy only those elements of ARRAY to RESULT whose
MASK equals .TRUE.. */
- mask_ctor = mask->value.constructor;
+ mask_ctor = gfc_constructor_first (mask->value.constructor);
while (mask_ctor)
{
if (mask_ctor->expr->value.logical)
{
- gfc_append_constructor (result,
- gfc_copy_expr (array_ctor->expr));
- ADVANCE (vector_ctor, 1);
+ gfc_constructor_append_expr (&result->value.constructor,
+ gfc_copy_expr (array_ctor->expr),
+ NULL);
+ vector_ctor = gfc_constructor_next (vector_ctor);
}
- ADVANCE (array_ctor, 1);
- ADVANCE (mask_ctor, 1);
+ array_ctor = gfc_constructor_next (array_ctor);
+ mask_ctor = gfc_constructor_next (mask_ctor);
}
}
/* Append any left-over elements from VECTOR to RESULT. */
while (vector_ctor)
{
- gfc_append_constructor (result,
- gfc_copy_expr (vector_ctor->expr));
- ADVANCE (vector_ctor, 1);
+ gfc_constructor_append_expr (&result->value.constructor,
+ gfc_copy_expr (vector_ctor->expr),
+ NULL);
+ vector_ctor = gfc_constructor_next (vector_ctor);
}
result->shape = gfc_get_shape (1);
@@ -4043,15 +3813,9 @@ gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
gfc_expr *
gfc_simplify_precision (gfc_expr *e)
{
- gfc_expr *result;
- int i;
-
- i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
-
- result = gfc_int_expr (gfc_real_kinds[i].precision);
- result->where = e->where;
-
- return result;
+ int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where,
+ gfc_real_kinds[i].precision);
}
@@ -4082,59 +3846,49 @@ gfc_simplify_product (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
gfc_expr *
gfc_simplify_radix (gfc_expr *e)
{
- gfc_expr *result;
int i;
-
i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
+
switch (e->ts.type)
{
- case BT_INTEGER:
- i = gfc_integer_kinds[i].radix;
- break;
+ case BT_INTEGER:
+ i = gfc_integer_kinds[i].radix;
+ break;
- case BT_REAL:
- i = gfc_real_kinds[i].radix;
- break;
+ case BT_REAL:
+ i = gfc_real_kinds[i].radix;
+ break;
- default:
- gcc_unreachable ();
+ default:
+ gcc_unreachable ();
}
- result = gfc_int_expr (i);
- result->where = e->where;
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
}
gfc_expr *
gfc_simplify_range (gfc_expr *e)
{
- gfc_expr *result;
int i;
- long j;
-
i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
switch (e->ts.type)
{
- case BT_INTEGER:
- j = gfc_integer_kinds[i].range;
- break;
+ case BT_INTEGER:
+ i = gfc_integer_kinds[i].range;
+ break;
- case BT_REAL:
- case BT_COMPLEX:
- j = gfc_real_kinds[i].range;
- break;
+ case BT_REAL:
+ case BT_COMPLEX:
+ i = gfc_real_kinds[i].range;
+ break;
- default:
- gcc_unreachable ();
+ default:
+ gcc_unreachable ();
}
- result = gfc_int_expr (j);
- result->where = e->where;
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
}
@@ -4155,39 +3909,12 @@ gfc_simplify_real (gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- switch (e->ts.type)
- {
- case BT_INTEGER:
- if (!e->is_boz)
- result = gfc_int2real (e, kind);
- break;
-
- case BT_REAL:
- result = gfc_real2real (e, kind);
- break;
-
- case BT_COMPLEX:
- result = gfc_complex2real (e, kind);
- break;
-
- default:
- gfc_internal_error ("bad type in REAL");
- /* Not reached */
- }
+ if (convert_boz (e, kind) == &gfc_bad_expr)
+ return &gfc_bad_expr;
- if (e->ts.type == BT_INTEGER && e->is_boz)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_REAL;
- ts.kind = kind;
- result = gfc_copy_expr (e);
- if (!gfc_convert_boz (result, &ts))
- {
- gfc_free_expr (result);
- return &gfc_bad_expr;
- }
- }
+ result = gfc_convert_constant (e, BT_REAL, kind);
+ if (result == &gfc_bad_expr)
+ return &gfc_bad_expr;
return range_check (result, "REAL");
}
@@ -4201,8 +3928,9 @@ gfc_simplify_realpart (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);
+
return range_check (result, "REALPART");
}
@@ -4303,19 +4031,15 @@ gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
len = e->value.character.length;
nlen = ncop * len;
- result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (BT_CHARACTER, e->ts.kind, &e->where);
if (ncop == 0)
- {
- result->value.character.string = gfc_get_wide_string (1);
- result->value.character.length = 0;
- result->value.character.string[0] = '\0';
- return result;
- }
+ return gfc_get_character_expr (e->ts.kind, &e->where, NULL, 0);
- result->value.character.length = nlen;
- result->value.character.string = gfc_get_wide_string (nlen + 1);
+ len = e->value.character.length;
+ nlen = ncop * len;
+ result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, nlen);
for (i = 0; i < ncop; i++)
for (j = 0; j < len; j++)
result->value.character.string[j+i*len]= e->value.character.string[j];
@@ -4333,11 +4057,10 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
{
int order[GFC_MAX_DIMENSIONS], shape[GFC_MAX_DIMENSIONS];
int i, rank, npad, x[GFC_MAX_DIMENSIONS];
- gfc_constructor *head, *tail;
mpz_t index, size;
unsigned long j;
size_t nsource;
- gfc_expr *e;
+ gfc_expr *e, *result;
/* Check that argument expression types are OK. */
if (!is_constant_array_expr (source)
@@ -4350,11 +4073,10 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
mpz_init (index);
rank = 0;
- head = tail = NULL;
for (;;)
{
- e = gfc_get_array_element (shape_exp, rank);
+ e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank);
if (e == NULL)
break;
@@ -4363,7 +4085,6 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
gcc_assert (rank >= 0 && rank < GFC_MAX_DIMENSIONS);
gcc_assert (shape[rank] >= 0);
- gfc_free_expr (e);
rank++;
}
@@ -4382,11 +4103,10 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
for (i = 0; i < rank; i++)
{
- e = gfc_get_array_element (order_exp, i);
+ e = gfc_constructor_lookup_expr (order_exp->value.constructor, i);
gcc_assert (e);
gfc_extract_int (e, &order[i]);
- gfc_free_expr (e);
gcc_assert (order[i] >= 1 && order[i] <= rank);
order[i]--;
@@ -4417,6 +4137,13 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
for (i = 0; i < rank; i++)
x[i] = 0;
+ result = gfc_get_array_expr (source->ts.type, source->ts.kind,
+ &source->where);
+ result->rank = rank;
+ result->shape = gfc_get_shape (rank);
+ for (i = 0; i < rank; i++)
+ mpz_init_set_ui (result->shape[i], shape[i]);
+
while (nsource > 0 || npad > 0)
{
/* Figure out which element to extract. */
@@ -4435,27 +4162,19 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
j = mpz_get_ui (index);
if (j < nsource)
- e = gfc_get_array_element (source, j);
+ e = gfc_constructor_lookup_expr (source->value.constructor, j);
else
{
gcc_assert (npad > 0);
j = j - nsource;
j = j % npad;
- e = gfc_get_array_element (pad, j);
+ e = gfc_constructor_lookup_expr (pad->value.constructor, j);
}
gcc_assert (e);
- if (head == NULL)
- head = tail = gfc_get_constructor ();
- else
- {
- tail->next = gfc_get_constructor ();
- tail = tail->next;
- }
-
- tail->where = e->where;
- tail->expr = e;
+ gfc_constructor_append_expr (&result->value.constructor,
+ gfc_copy_expr (e), &e->where);
/* Calculate the next element. */
i = 0;
@@ -4472,19 +4191,7 @@ inc:
mpz_clear (index);
- e = gfc_get_expr ();
- e->where = source->where;
- e->expr_type = EXPR_ARRAY;
- e->value.constructor = head;
- e->shape = gfc_get_shape (rank);
-
- for (i = 0; i < rank; i++)
- mpz_init_set_ui (e->shape[i], shape[i]);
-
- e->ts = source->ts;
- e->rank = rank;
-
- return e;
+ return result;
}
@@ -4500,8 +4207,7 @@ gfc_simplify_rrspacing (gfc_expr *x)
i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
- result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
-
+ result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
mpfr_abs (result->value.real, x->value.real, GFC_RND_MODE);
/* Special case x = -0 and 0. */
@@ -4532,7 +4238,7 @@ gfc_simplify_scale (gfc_expr *x, gfc_expr *i)
if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
if (mpfr_sgn (x->value.real) == 0)
{
@@ -4646,8 +4352,6 @@ gfc_simplify_scan (gfc_expr *e, gfc_expr *c, gfc_expr *b, gfc_expr *kind)
else
back = 0;
- result = gfc_constant_result (BT_INTEGER, k, &e->where);
-
len = e->value.character.length;
lenc = c->value.character.length;
@@ -4680,7 +4384,8 @@ gfc_simplify_scan (gfc_expr *e, gfc_expr *c, gfc_expr *b, gfc_expr *kind)
}
}
}
- mpz_set_ui (result->value.integer, indx);
+
+ result = gfc_get_int_expr (k, &e->where, indx);
return range_check (result, "SCAN");
}
@@ -4689,7 +4394,6 @@ gfc_expr *
gfc_simplify_selected_char_kind (gfc_expr *e)
{
int kind;
- gfc_expr *result;
if (e->expr_type != EXPR_CONSTANT)
return NULL;
@@ -4702,10 +4406,7 @@ gfc_simplify_selected_char_kind (gfc_expr *e)
else
kind = -1;
- result = gfc_int_expr (kind);
- result->where = e->where;
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
}
@@ -4713,7 +4414,6 @@ gfc_expr *
gfc_simplify_selected_int_kind (gfc_expr *e)
{
int i, kind, range;
- gfc_expr *result;
if (e->expr_type != EXPR_CONSTANT || gfc_extract_int (e, &range) != NULL)
return NULL;
@@ -4728,10 +4428,7 @@ gfc_simplify_selected_int_kind (gfc_expr *e)
if (kind == INT_MAX)
kind = -1;
- result = gfc_int_expr (kind);
- result->where = e->where;
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
}
@@ -4739,7 +4436,6 @@ gfc_expr *
gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q)
{
int range, precision, i, kind, found_precision, found_range;
- gfc_expr *result;
if (p == NULL)
precision = 0;
@@ -4786,10 +4482,8 @@ gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q)
kind -= 2;
}
- result = gfc_int_expr (kind);
- result->where = (p != NULL) ? p->where : q->where;
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind,
+ p ? &p->where : &q->where, kind);
}
@@ -4803,7 +4497,7 @@ gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i)
if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
if (mpfr_sgn (x->value.real) == 0)
{
@@ -4849,14 +4543,14 @@ gfc_simplify_shape (gfc_expr *source)
gfc_try t;
if (source->rank == 0)
- return gfc_start_constructor (BT_INTEGER, gfc_default_integer_kind,
- &source->where);
+ return gfc_get_array_expr (BT_INTEGER, gfc_default_integer_kind,
+ &source->where);
if (source->expr_type != EXPR_VARIABLE)
return NULL;
- result = gfc_start_constructor (BT_INTEGER, gfc_default_integer_kind,
- &source->where);
+ result = gfc_get_array_expr (BT_INTEGER, gfc_default_integer_kind,
+ &source->where);
ar = gfc_find_array_ref (source);
@@ -4864,8 +4558,8 @@ gfc_simplify_shape (gfc_expr *source)
for (n = 0; n < source->rank; n++)
{
- e = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
- &source->where);
+ e = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
+ &source->where);
if (t == SUCCESS)
{
@@ -4889,7 +4583,7 @@ gfc_simplify_shape (gfc_expr *source)
}
}
- gfc_append_constructor (result, e);
+ gfc_constructor_append_expr (&result->value.constructor, e, NULL);
}
return result;
@@ -4900,7 +4594,6 @@ gfc_expr *
gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
mpz_t size;
- gfc_expr *result;
int d;
int k = get_kind (BT_INTEGER, kind, "SIZE", gfc_default_integer_kind);
@@ -4922,9 +4615,7 @@ gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
return NULL;
}
- result = gfc_constant_result (BT_INTEGER, k, &array->where);
- mpz_set (result->value.integer, size);
- return result;
+ return gfc_get_int_expr (k, &array->where, mpz_get_si (size));
}
@@ -4936,27 +4627,27 @@ gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
switch (x->ts.type)
{
- case BT_INTEGER:
- mpz_abs (result->value.integer, x->value.integer);
- if (mpz_sgn (y->value.integer) < 0)
- mpz_neg (result->value.integer, result->value.integer);
- break;
+ case BT_INTEGER:
+ mpz_abs (result->value.integer, x->value.integer);
+ if (mpz_sgn (y->value.integer) < 0)
+ mpz_neg (result->value.integer, result->value.integer);
+ break;
- case BT_REAL:
- if (gfc_option.flag_sign_zero)
- mpfr_copysign (result->value.real, x->value.real, y->value.real,
- GFC_RND_MODE);
- else
- mpfr_setsign (result->value.real, x->value.real,
- mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
- break;
+ case BT_REAL:
+ if (gfc_option.flag_sign_zero)
+ mpfr_copysign (result->value.real, x->value.real, y->value.real,
+ GFC_RND_MODE);
+ else
+ mpfr_setsign (result->value.real, x->value.real,
+ mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
+ break;
- default:
- gfc_internal_error ("Bad type in gfc_simplify_sign");
+ default:
+ gfc_internal_error ("Bad type in gfc_simplify_sign");
}
return result;
@@ -4971,21 +4662,21 @@ gfc_simplify_sin (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
switch (x->ts.type)
{
- case BT_REAL:
- mpfr_sin (result->value.real, x->value.real, GFC_RND_MODE);
- break;
+ case BT_REAL:
+ mpfr_sin (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
- case BT_COMPLEX:
- gfc_set_model (x->value.real);
- mpc_sin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- break;
+ case BT_COMPLEX:
+ gfc_set_model (x->value.real);
+ mpc_sin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
- default:
- gfc_internal_error ("in gfc_simplify_sin(): Bad type");
+ default:
+ gfc_internal_error ("in gfc_simplify_sin(): Bad type");
}
return range_check (result, "SIN");
@@ -5000,15 +4691,21 @@ gfc_simplify_sinh (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
- if (x->ts.type == BT_REAL)
- mpfr_sinh (result->value.real, x->value.real, GFC_RND_MODE);
- else if (x->ts.type == BT_COMPLEX)
- mpc_sinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- else
- gcc_unreachable ();
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ mpfr_sinh (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
+ case BT_COMPLEX:
+ mpc_sinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
return range_check (result, "SINH");
}
@@ -5042,7 +4739,7 @@ gfc_simplify_spacing (gfc_expr *x)
i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
- result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
/* Special case x = 0 and -0. */
mpfr_abs (result->value.real, x->value.real, GFC_RND_MODE);
@@ -5106,31 +4803,29 @@ gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_exp
{
gcc_assert (dim == 0);
- result = gfc_start_constructor (source->ts.type,
- source->ts.kind,
- &source->where);
+ result = gfc_get_array_expr (source->ts.type, source->ts.kind,
+ &source->where);
result->rank = 1;
result->shape = gfc_get_shape (result->rank);
mpz_init_set_si (result->shape[0], ncopies);
for (i = 0; i < ncopies; ++i)
- gfc_append_constructor (result, gfc_copy_expr (source));
+ gfc_constructor_append_expr (&result->value.constructor,
+ gfc_copy_expr (source), NULL);
}
else if (source->expr_type == EXPR_ARRAY)
{
- int result_size, rstride[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS];
- gfc_constructor *ctor, *source_ctor, *result_ctor;
+ int offset, rstride[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS];
+ gfc_constructor *source_ctor;
gcc_assert (source->rank < GFC_MAX_DIMENSIONS);
gcc_assert (dim >= 0 && dim <= source->rank);
- result = gfc_start_constructor (source->ts.type,
- source->ts.kind,
- &source->where);
+ result = gfc_get_array_expr (source->ts.type, source->ts.kind,
+ &source->where);
result->rank = source->rank + 1;
result->shape = gfc_get_shape (result->rank);
- result_size = 1;
for (i = 0, j = 0; i < result->rank; ++i)
{
if (i != dim)
@@ -5140,26 +4835,18 @@ gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_exp
extent[i] = mpz_get_si (result->shape[i]);
rstride[i] = (i == 0) ? 1 : rstride[i-1] * extent[i-1];
- result_size *= extent[i];
}
- for (i = 0; i < result_size; ++i)
- gfc_append_constructor (result, NULL);
-
- source_ctor = source->value.constructor;
- result_ctor = result->value.constructor;
- while (source_ctor)
+ offset = 0;
+ for (source_ctor = gfc_constructor_first (source->value.constructor);
+ source_ctor; source_ctor = gfc_constructor_next (source_ctor))
{
- ctor = result_ctor;
-
for (i = 0; i < ncopies; ++i)
- {
- ctor->expr = gfc_copy_expr (source_ctor->expr);
- ADVANCE (ctor, rstride[dim]);
- }
+ gfc_constructor_insert_expr (&result->value.constructor,
+ gfc_copy_expr (source_ctor->expr),
+ NULL, offset + i * rstride[dim]);
- ADVANCE (result_ctor, (dim == 0 ? ncopies : 1));
- ADVANCE (source_ctor, 1);
+ offset += (dim == 0 ? ncopies : 1);
}
}
else
@@ -5178,37 +4865,36 @@ gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_exp
gfc_expr *
gfc_simplify_sqrt (gfc_expr *e)
{
- gfc_expr *result;
+ gfc_expr *result = NULL;
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
-
switch (e->ts.type)
{
- case BT_REAL:
- if (mpfr_cmp_si (e->value.real, 0) < 0)
- goto negative_arg;
- mpfr_sqrt (result->value.real, e->value.real, GFC_RND_MODE);
+ case BT_REAL:
+ if (mpfr_cmp_si (e->value.real, 0) < 0)
+ {
+ gfc_error ("Argument of SQRT at %L has a negative value",
+ &e->where);
+ return &gfc_bad_expr;
+ }
+ result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
+ mpfr_sqrt (result->value.real, e->value.real, GFC_RND_MODE);
+ break;
- break;
+ case BT_COMPLEX:
+ gfc_set_model (e->value.real);
- case BT_COMPLEX:
- gfc_set_model (e->value.real);
- mpc_sqrt (result->value.complex, e->value.complex, GFC_MPC_RND_MODE);
- break;
+ result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
+ mpc_sqrt (result->value.complex, e->value.complex, GFC_MPC_RND_MODE);
+ break;
- default:
- gfc_internal_error ("invalid argument of SQRT at %L", &e->where);
+ default:
+ gfc_internal_error ("invalid argument of SQRT at %L", &e->where);
}
return range_check (result, "SQRT");
-
-negative_arg:
- gfc_free_expr (result);
- gfc_error ("Argument of SQRT at %L has a negative value", &e->where);
- return &gfc_bad_expr;
}
@@ -5244,14 +4930,21 @@ gfc_simplify_tan (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
- if (x->ts.type == BT_REAL)
- mpfr_tan (result->value.real, x->value.real, GFC_RND_MODE);
- else if (x->ts.type == BT_COMPLEX)
- mpc_tan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- else
- gcc_unreachable ();
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ mpfr_tan (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
+
+ case BT_COMPLEX:
+ mpc_tan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
return range_check (result, "TAN");
}
@@ -5265,17 +4958,23 @@ gfc_simplify_tanh (gfc_expr *x)
if (x->expr_type != EXPR_CONSTANT)
return NULL;
- result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
- if (x->ts.type == BT_REAL)
- mpfr_tanh (result->value.real, x->value.real, GFC_RND_MODE);
- else if (x->ts.type == BT_COMPLEX)
- mpc_tanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
- else
- gcc_unreachable ();
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ mpfr_tanh (result->value.real, x->value.real, GFC_RND_MODE);
+ break;
- return range_check (result, "TANH");
+ case BT_COMPLEX:
+ mpc_tanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ return range_check (result, "TANH");
}
@@ -5287,7 +4986,7 @@ gfc_simplify_tiny (gfc_expr *e)
i = gfc_validate_kind (BT_REAL, e->ts.kind, false);
- result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+ result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);
return result;
@@ -5297,7 +4996,6 @@ gfc_simplify_tiny (gfc_expr *e)
gfc_expr *
gfc_simplify_trailz (gfc_expr *e)
{
- gfc_expr *result;
unsigned long tz, bs;
int i;
@@ -5308,10 +5006,8 @@ gfc_simplify_trailz (gfc_expr *e)
bs = gfc_integer_kinds[i].bit_size;
tz = mpz_scan1 (e->value.integer, 0);
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind, &e->where);
- mpz_set_ui (result->value.integer, MIN (tz, bs));
-
- return result;
+ return gfc_get_int_expr (gfc_default_integer_kind,
+ &e->where, MIN (tz, bs));
}
@@ -5343,12 +5039,12 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
source_size = gfc_target_expr_size (source);
/* Create an empty new expression with the appropriate characteristics. */
- result = gfc_constant_result (mold->ts.type, mold->ts.kind,
- &source->where);
+ result = gfc_get_constant_expr (mold->ts.type, mold->ts.kind,
+ &source->where);
result->ts = mold->ts;
mold_element = mold->expr_type == EXPR_ARRAY
- ? mold->value.constructor->expr
+ ? gfc_constructor_first (mold->value.constructor)->expr
: mold;
/* Set result character length, if needed. Note that this needs to be
@@ -5415,16 +5111,16 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
gfc_expr *
gfc_simplify_transpose (gfc_expr *matrix)
{
- int i, matrix_rows;
+ int row, matrix_rows, col, matrix_cols;
gfc_expr *result;
- gfc_constructor *matrix_ctor;
if (!is_constant_array_expr (matrix))
return NULL;
gcc_assert (matrix->rank == 2);
- result = gfc_start_constructor (matrix->ts.type, matrix->ts.kind, &matrix->where);
+ result = gfc_get_array_expr (matrix->ts.type, matrix->ts.kind,
+ &matrix->where);
result->rank = 2;
result->shape = gfc_get_shape (result->rank);
mpz_set (result->shape[0], matrix->shape[1]);
@@ -5434,20 +5130,16 @@ gfc_simplify_transpose (gfc_expr *matrix)
result->ts.u.cl = matrix->ts.u.cl;
matrix_rows = mpz_get_si (matrix->shape[0]);
- matrix_ctor = matrix->value.constructor;
- for (i = 0; i < matrix_rows; ++i)
- {
- gfc_constructor *column_ctor = matrix_ctor;
- while (column_ctor)
- {
- gfc_append_constructor (result,
- gfc_copy_expr (column_ctor->expr));
-
- ADVANCE (column_ctor, matrix_rows);
- }
-
- ADVANCE (matrix_ctor, 1);
- }
+ matrix_cols = mpz_get_si (matrix->shape[1]);
+ for (row = 0; row < matrix_rows; ++row)
+ for (col = 0; col < matrix_cols; ++col)
+ {
+ gfc_expr *e = gfc_constructor_lookup_expr (matrix->value.constructor,
+ col * matrix_rows + row);
+ gfc_constructor_insert_expr (&result->value.constructor,
+ gfc_copy_expr (e), &matrix->where,
+ row * matrix_cols + col);
+ }
return result;
}
@@ -5463,9 +5155,6 @@ gfc_simplify_trim (gfc_expr *e)
return NULL;
len = e->value.character.length;
-
- result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
-
for (count = 0, i = 1; i <= len; ++i)
{
if (e->value.character.string[len - i] == ' ')
@@ -5476,14 +5165,10 @@ gfc_simplify_trim (gfc_expr *e)
lentrim = len - count;
- result->value.character.length = lentrim;
- result->value.character.string = gfc_get_wide_string (lentrim + 1);
-
+ result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, lentrim);
for (i = 0; i < lentrim; i++)
result->value.character.string[i] = e->value.character.string[i];
- result->value.character.string[lentrim] = '\0'; /* For debugger */
-
return result;
}
@@ -5507,18 +5192,20 @@ gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
&& !is_constant_array_expr(field)))
return NULL;
- result = gfc_start_constructor (vector->ts.type,
- vector->ts.kind,
- &vector->where);
+ result = gfc_get_array_expr (vector->ts.type, vector->ts.kind,
+ &vector->where);
result->rank = mask->rank;
result->shape = gfc_copy_shape (mask->shape, mask->rank);
if (vector->ts.type == BT_CHARACTER)
result->ts.u.cl = vector->ts.u.cl;
- vector_ctor = vector->value.constructor;
- mask_ctor = mask->value.constructor;
- field_ctor = field->expr_type == EXPR_ARRAY ? field->value.constructor : NULL;
+ vector_ctor = gfc_constructor_first (vector->value.constructor);
+ mask_ctor = gfc_constructor_first (mask->value.constructor);
+ field_ctor
+ = field->expr_type == EXPR_ARRAY
+ ? gfc_constructor_first (field->value.constructor)
+ : NULL;
while (mask_ctor)
{
@@ -5526,17 +5213,17 @@ gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
{
gcc_assert (vector_ctor);
e = gfc_copy_expr (vector_ctor->expr);
- ADVANCE (vector_ctor, 1);
+ vector_ctor = gfc_constructor_next (vector_ctor);
}
else if (field->expr_type == EXPR_ARRAY)
e = gfc_copy_expr (field_ctor->expr);
else
e = gfc_copy_expr (field);
- gfc_append_constructor (result, e);
+ gfc_constructor_append_expr (&result->value.constructor, e, NULL);
- ADVANCE (mask_ctor, 1);
- ADVANCE (field_ctor, 1);
+ mask_ctor = gfc_constructor_next (mask_ctor);
+ field_ctor = gfc_constructor_next (field_ctor);
}
return result;
@@ -5563,7 +5250,7 @@ gfc_simplify_verify (gfc_expr *s, gfc_expr *set, gfc_expr *b, gfc_expr *kind)
else
back = 0;
- result = gfc_constant_result (BT_INTEGER, k, &s->where);
+ result = gfc_get_constant_expr (BT_INTEGER, k, &s->where);
len = s->value.character.length;
lenset = set->value.character.length;
@@ -5623,20 +5310,22 @@ gfc_simplify_xor (gfc_expr *x, gfc_expr *y)
return NULL;
kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
- if (x->ts.type == BT_INTEGER)
- {
- result = gfc_constant_result (BT_INTEGER, kind, &x->where);
- mpz_xor (result->value.integer, x->value.integer, y->value.integer);
- return range_check (result, "XOR");
- }
- else /* BT_LOGICAL */
+
+ switch (x->ts.type)
{
- result = gfc_constant_result (BT_LOGICAL, kind, &x->where);
- result->value.logical = (x->value.logical && !y->value.logical)
- || (!x->value.logical && y->value.logical);
- return result;
- }
+ case BT_INTEGER:
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
+ mpz_xor (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "XOR");
+
+ case BT_LOGICAL:
+ return gfc_get_logical_expr (kind, &x->where,
+ (x->value.logical && !y->value.logical)
+ || (!x->value.logical && y->value.logical));
+ default:
+ gcc_unreachable ();
+ }
}
@@ -5651,7 +5340,7 @@ gfc_expr *
gfc_convert_constant (gfc_expr *e, bt type, int kind)
{
gfc_expr *g, *result, *(*f) (gfc_expr *, int);
- gfc_constructor *head, *c, *tail = NULL;
+ gfc_constructor *c;
switch (e->ts.type)
{
@@ -5771,45 +5460,37 @@ gfc_convert_constant (gfc_expr *e, bt type, int kind)
if (!gfc_is_constant_expr (e))
break;
- head = NULL;
+ result = gfc_get_array_expr (type, kind, &e->where);
+ result->shape = gfc_copy_shape (e->shape, e->rank);
+ result->rank = e->rank;
- for (c = e->value.constructor; c; c = c->next)
+ for (c = gfc_constructor_first (e->value.constructor);
+ c; c = gfc_constructor_next (c))
{
- if (head == NULL)
- head = tail = gfc_get_constructor ();
- else
- {
- tail->next = gfc_get_constructor ();
- tail = tail->next;
- }
-
- tail->where = c->where;
-
+ gfc_expr *tmp;
if (c->iterator == NULL)
- tail->expr = f (c->expr, kind);
+ tmp = f (c->expr, kind);
else
{
g = gfc_convert_constant (c->expr, type, kind);
if (g == &gfc_bad_expr)
- return g;
- tail->expr = g;
+ {
+ gfc_free_expr (result);
+ return g;
+ }
+ tmp = g;
}
- if (tail->expr == NULL)
+ if (tmp == NULL)
{
- gfc_free_constructor (head);
+ gfc_free_expr (result);
return NULL;
}
+
+ gfc_constructor_append_expr (&result->value.constructor,
+ tmp, &c->where);
}
- result = gfc_get_expr ();
- result->ts.type = type;
- result->ts.kind = kind;
- result->expr_type = EXPR_ARRAY;
- result->value.constructor = head;
- result->shape = gfc_copy_shape (e->shape, e->rank);
- result->where = e->where;
- result->rank = e->rank;
break;
default:
@@ -5833,7 +5514,7 @@ gfc_convert_char_constant (gfc_expr *e, bt type ATTRIBUTE_UNUSED, int kind)
if (e->expr_type == EXPR_CONSTANT)
{
/* Simple case of a scalar. */
- result = gfc_constant_result (BT_CHARACTER, kind, &e->where);
+ result = gfc_get_constant_expr (BT_CHARACTER, kind, &e->where);
if (result == NULL)
return &gfc_bad_expr;
@@ -5860,42 +5541,32 @@ gfc_convert_char_constant (gfc_expr *e, bt type ATTRIBUTE_UNUSED, int kind)
else if (e->expr_type == EXPR_ARRAY)
{
/* For an array constructor, we convert each constructor element. */
- gfc_constructor *head = NULL, *tail = NULL, *c;
+ gfc_constructor *c;
- for (c = e->value.constructor; c; c = c->next)
- {
- if (head == NULL)
- head = tail = gfc_get_constructor ();
- else
- {
- tail->next = gfc_get_constructor ();
- tail = tail->next;
- }
+ result = gfc_get_array_expr (type, kind, &e->where);
+ result->shape = gfc_copy_shape (e->shape, e->rank);
+ result->rank = e->rank;
+ result->ts.u.cl = e->ts.u.cl;
- tail->where = c->where;
- tail->expr = gfc_convert_char_constant (c->expr, type, kind);
- if (tail->expr == &gfc_bad_expr)
+ for (c = gfc_constructor_first (e->value.constructor);
+ c; c = gfc_constructor_next (c))
+ {
+ gfc_expr *tmp = gfc_convert_char_constant (c->expr, type, kind);
+ if (tmp == &gfc_bad_expr)
{
- tail->expr = NULL;
+ gfc_free_expr (result);
return &gfc_bad_expr;
}
- if (tail->expr == NULL)
+ if (tmp == NULL)
{
- gfc_free_constructor (head);
+ gfc_free_expr (result);
return NULL;
}
- }
- result = gfc_get_expr ();
- result->ts.type = type;
- result->ts.kind = kind;
- result->expr_type = EXPR_ARRAY;
- result->value.constructor = head;
- result->shape = gfc_copy_shape (e->shape, e->rank);
- result->where = e->where;
- result->rank = e->rank;
- result->ts.u.cl = e->ts.u.cl;
+ gfc_constructor_append_expr (&result->value.constructor,
+ tmp, &c->where);
+ }
return result;
}