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

📄 resolve.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
static tryresolve_structure_cons (gfc_expr * expr){  gfc_constructor *cons;  gfc_component *comp;  try t;  t = SUCCESS;  cons = expr->value.constructor;  /* A constructor may have references if it is the result of substituting a     parameter variable.  In this case we just pull out the component we     want.  */  if (expr->ref)    comp = expr->ref->u.c.sym->components;  else    comp = expr->ts.derived->components;  for (; comp; comp = comp->next, cons = cons->next)    {      if (! cons->expr)	{	  t = FAILURE;	  continue;	}      if (gfc_resolve_expr (cons->expr) == FAILURE)	{	  t = FAILURE;	  continue;	}      /* If we don't have the right type, try to convert it.  */      if (!gfc_compare_types (&cons->expr->ts, &comp->ts))	{	  t = FAILURE;	  if (comp->pointer && cons->expr->ts.type != BT_UNKNOWN)	    gfc_error ("The element in the derived type constructor at %L, "		       "for pointer component '%s', is %s but should be %s",		       &cons->expr->where, comp->name,		       gfc_basic_typename (cons->expr->ts.type),		       gfc_basic_typename (comp->ts.type));	  else	    t = gfc_convert_type (cons->expr, &comp->ts, 1);	}    }  return t;}/****************** Expression name resolution ******************//* Returns 0 if a symbol was not declared with a type or   attribute declaration statement, nonzero otherwise.  */static intwas_declared (gfc_symbol * sym){  symbol_attribute a;  a = sym->attr;  if (!a.implicit_type && sym->ts.type != BT_UNKNOWN)    return 1;  if (a.allocatable || a.dimension || a.dummy || a.external || a.intrinsic      || a.optional || a.pointer || a.save || a.target      || a.access != ACCESS_UNKNOWN || a.intent != INTENT_UNKNOWN)    return 1;  return 0;}/* Determine if a symbol is generic or not.  */static intgeneric_sym (gfc_symbol * sym){  gfc_symbol *s;  if (sym->attr.generic ||      (sym->attr.intrinsic && gfc_generic_intrinsic (sym->name)))    return 1;  if (was_declared (sym) || sym->ns->parent == NULL)    return 0;  gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);  return (s == NULL) ? 0 : generic_sym (s);}/* Determine if a symbol is specific or not.  */static intspecific_sym (gfc_symbol * sym){  gfc_symbol *s;  if (sym->attr.if_source == IFSRC_IFBODY      || sym->attr.proc == PROC_MODULE      || sym->attr.proc == PROC_INTERNAL      || sym->attr.proc == PROC_ST_FUNCTION      || (sym->attr.intrinsic &&	  gfc_specific_intrinsic (sym->name))      || sym->attr.external)    return 1;  if (was_declared (sym) || sym->ns->parent == NULL)    return 0;  gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);  return (s == NULL) ? 0 : specific_sym (s);}/* Figure out if the procedure is specific, generic or unknown.  */typedef enum{ PTYPE_GENERIC = 1, PTYPE_SPECIFIC, PTYPE_UNKNOWN }proc_type;static proc_typeprocedure_kind (gfc_symbol * sym){  if (generic_sym (sym))    return PTYPE_GENERIC;  if (specific_sym (sym))    return PTYPE_SPECIFIC;  return PTYPE_UNKNOWN;}/* Check references to assumed size arrays.  The flag need_full_assumed_size   is non-zero when matching actual arguments.  */static int need_full_assumed_size = 0;static boolcheck_assumed_size_reference (gfc_symbol * sym, gfc_expr * e){  gfc_ref * ref;  int dim;  int last = 1;  if (need_full_assumed_size	|| !(sym->as && sym->as->type == AS_ASSUMED_SIZE))      return false;  for (ref = e->ref; ref; ref = ref->next)    if (ref->type == REF_ARRAY)      for (dim = 0; dim < ref->u.ar.as->rank; dim++)	last = (ref->u.ar.end[dim] == NULL) && (ref->u.ar.type == DIMEN_ELEMENT);  if (last)    {      gfc_error ("The upper bound in the last dimension must "		 "appear in the reference to the assumed size "		 "array '%s' at %L.", sym->name, &e->where);      return true;    }  return false;}/* Look for bad assumed size array references in argument expressions  of elemental and array valued intrinsic procedures.  Since this is  called from procedure resolution functions, it only recurses at  operators.  */static boolresolve_assumed_size_actual (gfc_expr *e){  if (e == NULL)   return false;  switch (e->expr_type)    {    case EXPR_VARIABLE:      if (e->symtree	    && check_assumed_size_reference (e->symtree->n.sym, e))	return true;      break;    case EXPR_OP:      if (resolve_assumed_size_actual (e->value.op.op1)	    || resolve_assumed_size_actual (e->value.op.op2))	return true;      break;    default:      break;    }  return false;}/* Resolve an actual argument list.  Most of the time, this is just   resolving the expressions in the list.   The exception is that we sometimes have to decide whether arguments   that look like procedure arguments are really simple variable   references.  */static tryresolve_actual_arglist (gfc_actual_arglist * arg){  gfc_symbol *sym;  gfc_symtree *parent_st;  gfc_expr *e;  for (; arg; arg = arg->next)    {      e = arg->expr;      if (e == NULL)        {          /* Check the label is a valid branching target.  */          if (arg->label)            {              if (arg->label->defined == ST_LABEL_UNKNOWN)                {                  gfc_error ("Label %d referenced at %L is never defined",                             arg->label->value, &arg->label->where);                  return FAILURE;                }            }          continue;        }      if (e->ts.type != BT_PROCEDURE)	{	  if (gfc_resolve_expr (e) != SUCCESS)	    return FAILURE;	  continue;	}      /* See if the expression node should really be a variable	 reference.  */      sym = e->symtree->n.sym;      if (sym->attr.flavor == FL_PROCEDURE	  || sym->attr.intrinsic	  || sym->attr.external)	{	  if (sym->attr.proc == PROC_ST_FUNCTION)	    {	      gfc_error ("Statement function '%s' at %L is not allowed as an "			 "actual argument", sym->name, &e->where);	    }	  if (sym->attr.contained && !sym->attr.use_assoc	      && sym->ns->proc_name->attr.flavor != FL_MODULE)	    {	      gfc_error ("Internal procedure '%s' is not allowed as an "			 "actual argument at %L", sym->name, &e->where);	    }	  if (sym->attr.elemental && !sym->attr.intrinsic)	    {	      gfc_error ("ELEMENTAL non-INTRINSIC procedure '%s' is not "		         "allowed as an actual argument at %L", sym->name,			 &e->where);	    }	  /* If the symbol is the function that names the current (or	     parent) scope, then we really have a variable reference.  */	  if (sym->attr.function && sym->result == sym	      && (sym->ns->proc_name == sym		  || (sym->ns->parent != NULL		      && sym->ns->parent->proc_name == sym)))	    goto got_variable;	  continue;	}      /* See if the name is a module procedure in a parent unit.  */      if (was_declared (sym) || sym->ns->parent == NULL)	goto got_variable;      if (gfc_find_sym_tree (sym->name, sym->ns->parent, 1, &parent_st))	{	  gfc_error ("Symbol '%s' at %L is ambiguous", sym->name, &e->where);	  return FAILURE;	}      if (parent_st == NULL)	goto got_variable;      sym = parent_st->n.sym;      e->symtree = parent_st;		/* Point to the right thing.  */      if (sym->attr.flavor == FL_PROCEDURE	  || sym->attr.intrinsic	  || sym->attr.external)	{	  continue;	}    got_variable:      e->expr_type = EXPR_VARIABLE;      e->ts = sym->ts;      if (sym->as != NULL)	{	  e->rank = sym->as->rank;	  e->ref = gfc_get_ref ();	  e->ref->type = REF_ARRAY;	  e->ref->u.ar.type = AR_FULL;	  e->ref->u.ar.as = sym->as;	}    }  return SUCCESS;}/* This function does the checking of references to global procedures   as defined in sections 18.1 and 14.1, respectively, of the Fortran   77 and 95 standards.  It checks for a gsymbol for the name, making   one if it does not already exist.  If it already exists, then the   reference being resolved must correspond to the type of gsymbol.   Otherwise, the new symbol is equipped with the attributes of the    reference.  The corresponding code that is called in creating   global entities is parse.c.  */static voidresolve_global_procedure (gfc_symbol *sym, locus *where, int sub){  gfc_gsymbol * gsym;  uint type;  type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;  gsym = gfc_get_gsymbol (sym->name);  if ((gsym->type != GSYM_UNKNOWN && gsym->type != type))    global_used (gsym, where);  if (gsym->type == GSYM_UNKNOWN)    {      gsym->type = type;      gsym->where = *where;    }  gsym->used = 1;}/************* Function resolution *************//* Resolve a function call known to be generic.   Section 14.1.2.4.1.  */static matchresolve_generic_f0 (gfc_expr * expr, gfc_symbol * sym){  gfc_symbol *s;  if (sym->attr.generic)    {      s =	gfc_search_interface (sym->generic, 0, &expr->value.function.actual);      if (s != NULL)	{	  expr->value.function.name = s->name;	  expr->value.function.esym = s;	  expr->ts = s->ts;	  if (s->as != NULL)	    expr->rank = s->as->rank;	  return MATCH_YES;	}      /* TODO: Need to search for elemental references in generic interface */    }  if (sym->attr.intrinsic)    return gfc_intrinsic_func_interface (expr, 0);  return MATCH_NO;}static tryresolve_generic_f (gfc_expr * expr){  gfc_symbol *sym;  match m;  sym = expr->symtree->n.sym;  for (;;)    {      m = resolve_generic_f0 (expr, sym);      if (m == MATCH_YES)	return SUCCESS;      else if (m == MATCH_ERROR)	return FAILURE;generic:      if (sym->ns->parent == NULL)	break;      gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);      if (sym == NULL)	break;      if (!generic_sym (sym))	goto generic;    }  /* Last ditch attempt.  */  if (!gfc_generic_intrinsic (expr->symtree->n.sym->name))    {      gfc_error ("Generic function '%s' at %L is not an intrinsic function",		 expr->symtree->n.sym->name, &expr->where);      return FAILURE;    }  m = gfc_intrinsic_func_interface (expr, 0);  if (m == MATCH_YES)    return SUCCESS;  if (m == MATCH_NO)    gfc_error      ("Generic function '%s' at %L is not consistent with a specific "       "intrinsic interface", expr->symtree->n.sym->name, &expr->where);  return FAILURE;}/* Resolve a function call known to be specific.  */static matchresolve_specific_f0 (gfc_symbol * sym, gfc_expr * expr){  match m;  if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)    {      if (sym->attr.dummy)	{	  sym->attr.proc = PROC_DUMMY;	  goto found;	}      sym->attr.proc = PROC_EXTERNAL;      goto found;    }  if (sym->attr.proc == PROC_MODULE      || sym->attr.proc == PROC_ST_FUNCTION      || sym->attr.proc == PROC_INTERNAL)    goto found;  if (sym->attr.intrinsic)    {      m = gfc_intrinsic_func_interface (expr, 1);      if (m == MATCH_YES)	return MATCH_YES;      if (m == MATCH_NO)	gfc_error	  ("Function '%s' at %L is INTRINSIC but is not compatible with "	   "an intrinsic", sym->name, &expr->where);      return MATCH_ERROR;    }  return MATCH_NO;found:  gfc_procedure_use (sym, &expr->value.function.actual, &expr->where);  expr->ts = sym->ts;  expr->value.function.name = sym->name;  expr->value.function.esym = sym;  if (sym->as != NULL)    expr->rank = sym->as->rank;  return MATCH_YES;}static tryresolve_specific_f (gfc_expr * expr){  gfc_symbol *sym;  match m;  sym = expr->symtree->n.sym;  for (;;)    {      m = resolve_specific_f0 (sym, expr);      if (m == MATCH_YES)	return SUCCESS;      if (m == MATCH_ERROR)	return FAILURE;      if (sym->ns->parent == NULL)	break;      gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);      if (sym == NULL)	break;    }  gfc_error ("Unable to resolve the specific function '%s' at %L",	     expr->symtree->n.sym->name, &expr->where);  return SUCCESS;}/* Resolve a procedure call not known to be generic nor specific.  */static tryresolve_unknown_f (gfc_expr * expr){  gfc_symbol *sym;  gfc_typespec *ts;  sym = expr->symtree->n.sym;  if (sym->attr.dummy)    {      sym->attr.proc = PROC_DUMMY;      expr->value.function.name = sym->name;      goto set_type;    }  /* See if we have an intrinsic function reference.  */  if (gfc_intrinsic_name (sym->name, 0))    {      if (gfc_intrinsic_func_interface (expr, 1) == MATCH_YES)	return SUCCESS;      return FAILURE;    }  /* The reference is to an external name.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -