unsigned long lz, bs;
int i;
- if (e->expr_type != EXPR_CONSTANT)
+ if (array->expr_type != EXPR_VARIABLE)
return NULL;
- i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
- bs = gfc_integer_kinds[i].bit_size;
- if (mpz_cmp_si (e->value.integer, 0) == 0)
- lz = bs;
- else if (mpz_cmp_si (e->value.integer, 0) < 0)
- lz = 0;
- else
- lz = bs - mpz_sizeinbase (e->value.integer, 2);
+ /* Follow any component references. */
+ as = array->symtree->n.sym->as;
+ for (ref = array->ref; ref; ref = ref->next)
+ {
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ switch (ref->u.ar.type)
+ {
+ case AR_ELEMENT:
+ if (ref->next == NULL)
+ {
+ gcc_assert (ref->u.ar.as->corank > 0
+ && ref->u.ar.as->rank == 0);
+ as = ref->u.ar.as;
+ goto done;
+ }
+ as = NULL;
+ continue;
return gfc_get_int_expr (gfc_default_integer_kind, &e->where, lz);
}
+ case AR_UNKNOWN:
+ return NULL;
-gfc_expr *
-gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
-{
- gfc_expr *result;
- int k = get_kind (BT_INTEGER, kind, "LEN", gfc_default_integer_kind);
+ case AR_SECTION:
+ as = ref->u.ar.as;
+ goto done;
+ }
- if (k == -1)
- return &gfc_bad_expr;
+ gcc_unreachable ();
if (e->expr_type == EXPR_CONSTANT)
{
int count, len, i;
int k = get_kind (BT_INTEGER, kind, "LEN_TRIM", gfc_default_integer_kind);
- if (k == -1)
- return &gfc_bad_expr;
+ done:
- if (e->expr_type != EXPR_CONSTANT)
+ if (as->type == AS_DEFERRED || as->type == AS_ASSUMED_SHAPE)
return NULL;
len = e->value.character.length;
gfc_expr *
-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);
- mpz_set_si (result->value.integer, 1);
- return result;
-}
-
-
-gfc_expr *
gfc_simplify_or (gfc_expr *x, gfc_expr *y)
{
gfc_expr *result;
result->value.character.string[i] = e->value.character.string[i];
return result;
+
+not_implemented:
+ gfc_error ("Not yet implemented: IMAGE_INDEX for coarray with non-constant "
+ "cobounds at %L", &coarray->where);
+ return &gfc_bad_expr;
+}
+
+
+gfc_expr *
+gfc_simplify_this_image (gfc_expr *coarray, gfc_expr *dim)
+{
+ gfc_ref *ref;
+ gfc_array_spec *as;
+ int d;
+
+ if (coarray == NULL)
+ {
+ gfc_expr *result;
+ /* FIXME: gfc_current_locus is wrong. */
+ result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
+ &gfc_current_locus);
+ mpz_set_si (result->value.integer, 1);
+ return result;
+ }
+
+ gcc_assert (coarray->expr_type == EXPR_VARIABLE);
+
+ /* Follow any component references. */
+ as = coarray->symtree->n.sym->as;
+ for (ref = coarray->ref; ref; ref = ref->next)
+ if (ref->type == REF_COMPONENT)
+ as = ref->u.ar.as;
+
+ if (as->type == AS_DEFERRED)
+ goto not_implemented; /* return NULL;*/
+
+ if (dim == NULL)
+ {
+ /* Multi-dimensional bounds. */
+ gfc_expr *bounds[GFC_MAX_DIMENSIONS];
+ gfc_expr *e;
+
+ /* Simplify the bounds for each dimension. */
+ for (d = 0; d < as->corank; d++)
+ {
+ bounds[d] = simplify_bound_dim (coarray, NULL, d + as->rank + 1, 0,
+ as, NULL, true);
+ if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
+ {
+ int j;
+
+ for (j = 0; j < d; j++)
+ gfc_free_expr (bounds[j]);
+ if (bounds[d] == NULL)
+ goto not_implemented;
+ return bounds[d];
+ }
+ }
+
+ /* Allocate the result expression. */
+ e = gfc_get_expr ();
+ e->where = coarray->where;
+ e->expr_type = EXPR_ARRAY;
+ e->ts.type = BT_INTEGER;
+ e->ts.kind = gfc_default_integer_kind;
+
+ e->rank = 1;
+ e->shape = gfc_get_shape (1);
+ mpz_init_set_ui (e->shape[0], as->corank);
+
+ /* Create the constructor for this array. */
+ for (d = 0; d < as->corank; d++)
+ gfc_constructor_append_expr (&e->value.constructor,
+ bounds[d], &e->where);
+
+ return e;
+ }
+ else
+ {
+ gfc_expr *e;
+ /* A DIM argument is specified. */
+ if (dim->expr_type != EXPR_CONSTANT)
+ goto not_implemented; /*return NULL;*/
+
+ d = mpz_get_si (dim->value.integer);
+
+ if (d < 1 || d > as->corank)
+ {
+ gfc_error ("DIM argument at %L is out of bounds", &dim->where);
+ return &gfc_bad_expr;
+ }
+
+ /*return simplify_bound_dim (coarray, NULL, d + as->rank, 0, as, NULL, true);*/
+ e = simplify_bound_dim (coarray, NULL, d + as->rank, 0, as, NULL, true);
+ if (e != NULL)
+ return e;
+ else
+ goto not_implemented;
+ }
+
+not_implemented:
+ gfc_error ("Not yet implemented: THIS_IMAGE for coarray with non-constant "
+ "cobounds at %L", &coarray->where);
+ return &gfc_bad_expr;
}