📄 resolve.c
字号:
{ if (as != NULL) gfc_internal_error ("find_array_spec(): unused as(1)"); as = c->as; } break; case REF_SUBSTRING: break; } if (as != NULL) gfc_internal_error ("find_array_spec(): unused as(2)");}/* Resolve an array reference. */static tryresolve_array_ref (gfc_array_ref * ar){ int i, check_scalar; for (i = 0; i < ar->dimen; i++) { check_scalar = ar->dimen_type[i] == DIMEN_RANGE; if (gfc_resolve_index (ar->start[i], check_scalar) == FAILURE) return FAILURE; if (gfc_resolve_index (ar->end[i], check_scalar) == FAILURE) return FAILURE; if (gfc_resolve_index (ar->stride[i], check_scalar) == FAILURE) return FAILURE; if (ar->dimen_type[i] == DIMEN_UNKNOWN) switch (ar->start[i]->rank) { case 0: ar->dimen_type[i] = DIMEN_ELEMENT; break; case 1: ar->dimen_type[i] = DIMEN_VECTOR; break; default: gfc_error ("Array index at %L is an array of rank %d", &ar->c_where[i], ar->start[i]->rank); return FAILURE; } } /* If the reference type is unknown, figure out what kind it is. */ if (ar->type == AR_UNKNOWN) { ar->type = AR_ELEMENT; for (i = 0; i < ar->dimen; i++) if (ar->dimen_type[i] == DIMEN_RANGE || ar->dimen_type[i] == DIMEN_VECTOR) { ar->type = AR_SECTION; break; } } if (!ar->as->cray_pointee && compare_spec_to_ref (ar) == FAILURE) return FAILURE; return SUCCESS;}static tryresolve_substring (gfc_ref * ref){ if (ref->u.ss.start != NULL) { if (gfc_resolve_expr (ref->u.ss.start) == FAILURE) return FAILURE; if (ref->u.ss.start->ts.type != BT_INTEGER) { gfc_error ("Substring start index at %L must be of type INTEGER", &ref->u.ss.start->where); return FAILURE; } if (ref->u.ss.start->rank != 0) { gfc_error ("Substring start index at %L must be scalar", &ref->u.ss.start->where); return FAILURE; } if (compare_bound_int (ref->u.ss.start, 1) == CMP_LT) { gfc_error ("Substring start index at %L is less than one", &ref->u.ss.start->where); return FAILURE; } } if (ref->u.ss.end != NULL) { if (gfc_resolve_expr (ref->u.ss.end) == FAILURE) return FAILURE; if (ref->u.ss.end->ts.type != BT_INTEGER) { gfc_error ("Substring end index at %L must be of type INTEGER", &ref->u.ss.end->where); return FAILURE; } if (ref->u.ss.end->rank != 0) { gfc_error ("Substring end index at %L must be scalar", &ref->u.ss.end->where); return FAILURE; } if (ref->u.ss.length != NULL && compare_bound (ref->u.ss.end, ref->u.ss.length->length) == CMP_GT) { gfc_error ("Substring end index at %L is out of bounds", &ref->u.ss.start->where); return FAILURE; } } return SUCCESS;}/* Resolve subtype references. */static tryresolve_ref (gfc_expr * expr){ int current_part_dimension, n_components, seen_part_dimension; gfc_ref *ref; for (ref = expr->ref; ref; ref = ref->next) if (ref->type == REF_ARRAY && ref->u.ar.as == NULL) { find_array_spec (expr); break; } for (ref = expr->ref; ref; ref = ref->next) switch (ref->type) { case REF_ARRAY: if (resolve_array_ref (&ref->u.ar) == FAILURE) return FAILURE; break; case REF_COMPONENT: break; case REF_SUBSTRING: resolve_substring (ref); break; } /* Check constraints on part references. */ current_part_dimension = 0; seen_part_dimension = 0; n_components = 0; for (ref = expr->ref; ref; ref = ref->next) { switch (ref->type) { case REF_ARRAY: switch (ref->u.ar.type) { case AR_FULL: case AR_SECTION: current_part_dimension = 1; break; case AR_ELEMENT: current_part_dimension = 0; break; case AR_UNKNOWN: gfc_internal_error ("resolve_ref(): Bad array reference"); } break; case REF_COMPONENT: if ((current_part_dimension || seen_part_dimension) && ref->u.c.component->pointer) { gfc_error ("Component to the right of a part reference with nonzero " "rank must not have the POINTER attribute at %L", &expr->where); return FAILURE; } n_components++; break; case REF_SUBSTRING: break; } if (((ref->type == REF_COMPONENT && n_components > 1) || ref->next == NULL) && current_part_dimension && seen_part_dimension) { gfc_error ("Two or more part references with nonzero rank must " "not be specified at %L", &expr->where); return FAILURE; } if (ref->type == REF_COMPONENT) { if (current_part_dimension) seen_part_dimension = 1; /* reset to make sure */ current_part_dimension = 0; } } return SUCCESS;}/* Given an expression, determine its shape. This is easier than it sounds. Leaves the shape array NULL if it is not possible to determine the shape. */static voidexpression_shape (gfc_expr * e){ mpz_t array[GFC_MAX_DIMENSIONS]; int i; if (e->rank == 0 || e->shape != NULL) return; for (i = 0; i < e->rank; i++) if (gfc_array_dimen_size (e, i, &array[i]) == FAILURE) goto fail; e->shape = gfc_get_shape (e->rank); memcpy (e->shape, array, e->rank * sizeof (mpz_t)); return;fail: for (i--; i >= 0; i--) mpz_clear (array[i]);}/* Given a variable expression node, compute the rank of the expression by examining the base symbol and any reference structures it may have. */static voidexpression_rank (gfc_expr * e){ gfc_ref *ref; int i, rank; if (e->ref == NULL) { if (e->expr_type == EXPR_ARRAY) goto done; /* Constructors can have a rank different from one via RESHAPE(). */ if (e->symtree == NULL) { e->rank = 0; goto done; } e->rank = (e->symtree->n.sym->as == NULL) ? 0 : e->symtree->n.sym->as->rank; goto done; } rank = 0; for (ref = e->ref; ref; ref = ref->next) { if (ref->type != REF_ARRAY) continue; if (ref->u.ar.type == AR_FULL) { rank = ref->u.ar.as->rank; break; } if (ref->u.ar.type == AR_SECTION) { /* Figure out the rank of the section. */ if (rank != 0) gfc_internal_error ("expression_rank(): Two array specs"); for (i = 0; i < ref->u.ar.dimen; i++) if (ref->u.ar.dimen_type[i] == DIMEN_RANGE || ref->u.ar.dimen_type[i] == DIMEN_VECTOR) rank++; break; } } e->rank = rank;done: expression_shape (e);}/* Resolve a variable expression. */static tryresolve_variable (gfc_expr * e){ gfc_symbol *sym; if (e->ref && resolve_ref (e) == FAILURE) return FAILURE; if (e->symtree == NULL) return FAILURE; sym = e->symtree->n.sym; if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function) { e->ts.type = BT_PROCEDURE; return SUCCESS; } if (sym->ts.type != BT_UNKNOWN) gfc_variable_attr (e, &e->ts); else { /* Must be a simple variable reference. */ if (gfc_set_default_type (sym, 1, NULL) == FAILURE) return FAILURE; e->ts = sym->ts; } if (check_assumed_size_reference (sym, e)) return FAILURE; return SUCCESS;}/* Resolve an expression. That is, make sure that types of operands agree with their operators, intrinsic operators are converted to function calls for overloaded types and unresolved function references are resolved. */trygfc_resolve_expr (gfc_expr * e){ try t; if (e == NULL) return SUCCESS; switch (e->expr_type) { case EXPR_OP: t = resolve_operator (e); break; case EXPR_FUNCTION: t = resolve_function (e); break; case EXPR_VARIABLE: t = resolve_variable (e); if (t == SUCCESS) expression_rank (e); break; case EXPR_SUBSTRING: t = resolve_ref (e); break; case EXPR_CONSTANT: case EXPR_NULL: t = SUCCESS; break; case EXPR_ARRAY: t = FAILURE; if (resolve_ref (e) == FAILURE) break; t = gfc_resolve_array_constructor (e); /* Also try to expand a constructor. */ if (t == SUCCESS) { expression_rank (e); gfc_expand_constructor (e); } break; case EXPR_STRUCTURE: t = resolve_ref (e); if (t == FAILURE) break; t = resolve_structure_cons (e); if (t == FAILURE) break; t = gfc_simplify_expr (e, 0); break; default: gfc_internal_error ("gfc_resolve_expr(): Bad expression type"); } return t;}/* Resolve an expression from an iterator. They must be scalar and have INTEGER or (optionally) REAL type. */static trygfc_resolve_iterator_expr (gfc_expr * expr, bool real_ok, const char * name_msgid){ if (gfc_resolve_expr (expr) == FAILURE) return FAILURE; if (expr->rank != 0) { gfc_error ("%s at %L must be a scalar", _(name_msgid), &expr->where); return FAILURE; } if (!(expr->ts.type == BT_INTEGER || (expr->ts.type == BT_REAL && real_ok))) { if (real_ok) gfc_error ("%s at %L must be INTEGER or REAL", _(name_msgid), &expr->where); else gfc_error ("%s at %L must be INTEGER", _(name_msgid), &expr->where); return FAILURE; } return SUCCESS;}/* Resolve the expressions in an iterator structure. If REAL_OK is false allow only INTEGER type iterators, otherwise allow REAL types. */trygfc_resolve_iterator (gfc_iterator * iter, bool real_ok){ if (iter->var->ts.type == BT_REAL) gfc_notify_std (GFC_STD_F95_DEL, "Obsolete: REAL DO loop iterator at %L", &iter->var->where); if (gfc_resolve_iterator_expr (iter->var, real_ok, "Loop variable") == FAILURE) return FAILURE; if (gfc_pure (NULL) && gfc_impure_variable (iter->var->symtree->n.sym)) { gfc_error ("Cannot assign to loop variable in PURE procedure at %L", &iter->var->where); return FAILURE; } if (gfc_resolve_iterator_expr (iter->start, real_ok, "Start expression in DO loop") == FAILURE) return FAILURE; if (gfc_resolve_iterator_expr (iter->end, real_ok, "End expression in DO loop") == FAILURE) return FAILURE; if (gfc_resolve_iterator_expr (iter->step, real_ok, "Step expression in DO loop") == FAILURE) return FAILURE; if (iter->step->expr_type == EXPR_CONSTANT) { if ((iter->step->ts.type == BT_INTEGER && mpz_cmp_ui (iter->step->value.integer, 0) == 0) || (iter->step->ts.type == BT_REAL && mpfr_sgn (iter->step->value.real) == 0)) { gfc_error ("Step expression in DO loop at %L cannot be zero", &iter->step->where); return FAILURE; } } /* Convert start, end, and step to the same type as var. */ if (iter->start->ts.kind != iter->var->ts.kind || iter->start->ts.type != iter->var->ts.type) gfc_convert_type (iter->start, &iter->var->ts, 2); if (iter->end->ts.kind != iter->var->ts.kind || iter->end->ts.type != iter->var->ts.type) gfc_convert_type (iter->end, &iter->var->ts, 2); if (iter->step->ts.kind != iter->var->ts.kind || iter->step->ts.type != iter->var->ts.type) gfc_convert_type (iter->step, &iter->var->ts, 2); return SUCCESS;}/* Resolve a list of FORALL iterators. The FORALL index-name is constrained to be a scalar INTEGER variable. The subscripts and stride are scalar INTEGERs, and if stride is a constant it must be nonzero. */static voidresolve_forall_iterators (gfc_forall_iterator * iter){ while (iter) { if (gfc_resolve_expr (iter->var) == SUCCESS && (iter->var->ts.type != BT_INTEGER || iter->var->rank != 0)) gfc_error ("FORALL index-name at %L must be a scalar INTEGER", &iter->var->where); if (gfc_resolve_expr (iter->start) == SUCCESS && (iter->start->ts.type != BT_INTEGER || iter->start->rank != 0)) gfc_error
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -