⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resolve.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
	  {	    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 + -