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

📄 cp-typeck.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     tree t1, t2;     int strict;{  return TYPE_RAISES_EXCEPTIONS (t1) == TYPE_RAISES_EXCEPTIONS (t2);}static intcomp_array_types (cmp, t1, t2, strict)     register int (*cmp)();     tree t1, t2;     int strict;{  tree d1 = TYPE_DOMAIN (t1);  tree d2 = TYPE_DOMAIN (t2);  /* Target types must match incl. qualifiers.  */  if (!(TREE_TYPE (t1) == TREE_TYPE (t2)	|| (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), strict)))    return 0;  /* Sizes must match unless one is missing or variable.  */  if (d1 == 0 || d2 == 0 || d1 == d2      || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST      || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST      || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST      || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)    return 1;  return ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))	   == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))	  && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))	      == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))	  && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))	      == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))	  && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))	      == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))));}/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment   or various other operations.  This is what ANSI C++ speaks of as   "being the same".   For C++: argument STRICT says we should be strict about this   comparison:	1 : strict (compared according to ANSI C)	0 : <= (compared according to C++)	-1: <= or >= (relaxed)   Otherwise, pointers involving base classes and derived classes   can be mixed as legal: i.e. a pointer to a base class may be assigned   to a pointer to one of its derived classes, as per C++. A pointer to   a derived class may be passed as a parameter to a function expecting a   pointer to a base classes. These allowances do not commute. In this   case, TYPE1 is assumed to be the base class, and TYPE2 is assumed to   be the derived class.  */intcomptypes (type1, type2, strict)     tree type1, type2;     int strict;{  register tree t1 = type1;  register tree t2 = type2;  /* Suppress errors caused by previously reported errors */  if (t1 == t2)    return 1;  /* This should never happen.  */  my_friendly_assert (t1 != error_mark_node, 307);  /* We don't want this to happen.  */  if (t2 == error_mark_node)    {      warning ("Internal error: t2 == error_mark_node in `comptypes'");      return 0;    }  if (strict < 0)    {      /* Treat an enum type as the unsigned integer type of the same width.  */      if (TREE_CODE (t1) == ENUMERAL_TYPE)	t1 = type_for_size (TYPE_PRECISION (t1), 1);      if (TREE_CODE (t2) == ENUMERAL_TYPE)	t2 = type_for_size (TYPE_PRECISION (t2), 1);    }  if (t1 == t2)    return 1;  /* Different classes of types can't be compatible.  */  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;  /* Qualifiers must match.  */  if (TYPE_READONLY (t1) != TYPE_READONLY (t2))    return 0;  if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))    return 0;  switch (TREE_CODE (t1))    {    case RECORD_TYPE:    case UNION_TYPE:      if (t1 == t2)	return 1;      if (strict <= 0)	goto look_hard;      return 0;    case OFFSET_TYPE:      return (comptypes (TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t1)),			 TYPE_POINTER_TO (TYPE_OFFSET_BASETYPE (t2)), strict)	      && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));    case METHOD_TYPE:      if (! compexcepttypes (t1, t2, strict))	return 0;      /* This case is anti-symmetrical!	 One can pass a base member (or member function)	 to something expecting a derived member (or member function),	 but not vice-versa!  */      return (comptypes (TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t2)),			 TYPE_POINTER_TO (TYPE_METHOD_BASETYPE (t1)), strict)	      && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)	      && compparms (TREE_CHAIN (TYPE_ARG_TYPES (t1)),			    TREE_CHAIN (TYPE_ARG_TYPES(t2)), strict));    case POINTER_TYPE:    case REFERENCE_TYPE:      t1 = TREE_TYPE (t1);      t2 = TREE_TYPE (t2);      if (t1 == t2)	return 1;      if (strict <= 0)	{	  if (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE)	    {	      int rval;	    look_hard:	      rval = t1 == t2 || UNIQUELY_DERIVED_FROM_P (t1, t2);	      if (rval)		return 1;	      if (strict < 0)		return UNIQUELY_DERIVED_FROM_P (t2, t1);	    }	  return 0;	}      else	return comptypes (t1, t2, strict);    case FUNCTION_TYPE:      if (! compexcepttypes (t1, t2, strict))	return 0;      return ((TREE_TYPE (t1) == TREE_TYPE (t2)	       || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))	      && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));    case ARRAY_TYPE:      /* Target types must match incl. qualifiers.  */      return comp_array_types (comptypes, t1, t2, strict);    }  return 0;}/* Return 1 if TTL and TTR are pointers to types that are equivalent,   ignoring their qualifiers.   NPTRS is the number of pointers we can strip off and keep cool.   This is used to permit (for aggr A, aggr B) A, B* to convert to A*,   but to not permit B** to convert to A**.  */intcomp_target_types (ttl, ttr, nptrs)     tree ttl, ttr;     int nptrs;{  ttl = TYPE_MAIN_VARIANT (ttl);  ttr = TYPE_MAIN_VARIANT (ttr);  if (ttl == ttr)    return 1;  if (TREE_CODE (ttr) != TREE_CODE (ttl))    return 0;  if (TREE_CODE (ttr) == POINTER_TYPE)    return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs - 1);  if (TREE_CODE (ttr) == REFERENCE_TYPE)    return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs);  if (TREE_CODE (ttr) == ARRAY_TYPE)    return comp_array_types (comp_target_types, ttl, ttr, 0);  else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)    if (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs))      switch (comp_target_parms (TYPE_ARG_TYPES (ttl), TYPE_ARG_TYPES (ttr), 0))	{	case 0:	  return 0;	case 1:	  return 1;	case 2:	  warning ("contravariance violation for method types ignored");	  return 1;	default:	  my_friendly_abort (112);	}    else      return 0;  /* for C++ */  else if (TREE_CODE (ttr) == OFFSET_TYPE)    {      /* Contravariance: we can assign a pointer to base member to a pointer	 to derived member.  Note difference from simple pointer case, where	 we can pass a pointer to derived to a pointer to base.  */      if (comptypes (TYPE_OFFSET_BASETYPE (ttr), TYPE_OFFSET_BASETYPE (ttl), 0))	return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs);      else if (comptypes (TYPE_OFFSET_BASETYPE (ttl), TYPE_OFFSET_BASETYPE (ttr), 0)	       && comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs))	{	  warning ("contravariance violation for member types ignored");	  return 1;	}    }  else if (IS_AGGR_TYPE (ttl))    {      if (nptrs < 0)	return 0;      return comptypes (TYPE_POINTER_TO (ttl), TYPE_POINTER_TO (ttr), 0);    }  return 0;}/* If two types share a common base type, return that basetype.   If there is not a unique most-derived base type, this function   returns ERROR_MARK_NODE.  */treecommon_base_type (tt1, tt2)     tree tt1, tt2;{  tree best = NULL_TREE, tmp;  int i;  /* If one is a baseclass of another, that's good enough.  */  if (UNIQUELY_DERIVED_FROM_P (tt1, tt2))    return tt1;  if (UNIQUELY_DERIVED_FROM_P (tt2, tt1))    return tt2;  /* If they share a virtual baseclass, that's good enough.  */  for (tmp = CLASSTYPE_VBASECLASSES (tt1); tmp; tmp = TREE_CHAIN (tmp))    {      if (binfo_member (BINFO_TYPE (tmp), CLASSTYPE_VBASECLASSES (tt2)))	return BINFO_TYPE (tmp);    }  /* Otherwise, try to find a unique baseclass of TT1     that is shared by TT2, and follow that down.  */  for (i = CLASSTYPE_N_BASECLASSES (tt1)-1; i >= 0; i--)    {      tree basetype = TYPE_BINFO_BASETYPE (tt1, i);      tree trial = common_base_type (basetype, tt2);      if (trial)	{	  if (trial == error_mark_node)	    return trial;	  if (best == NULL_TREE)	    best = trial;	  else if (best != trial)	    return error_mark_node;	}    }  /* Same for TT2.  */  for (i = CLASSTYPE_N_BASECLASSES (tt2)-1; i >= 0; i--)    {      tree basetype = TYPE_BINFO_BASETYPE (tt2, i);      tree trial = common_base_type (tt1, basetype);      if (trial)	{	  if (trial == error_mark_node)	    return trial;	  if (best == NULL_TREE)	    best = trial;	  else if (best != trial)	    return error_mark_node;	}    }  return best;}/* Subroutines of `comptypes'.  *//* Return 1 if two parameter type lists PARMS1 and PARMS2   are equivalent in the sense that functions with those parameter types   can have equivalent types.   If either list is empty, we win.   Otherwise, the two lists must be equivalent, element by element.   C++: See comment above about TYPE1, TYPE2, STRICT.   If STRICT == 3, it means checking is strict, but do not compare   default parameter values.  */intcompparms (parms1, parms2, strict)     tree parms1, parms2;     int strict;{  register tree t1 = parms1, t2 = parms2;  /* An unspecified parmlist matches any specified parmlist     whose argument types don't need default promotions.  */  if (t1 == 0)    return self_promoting_args_p (t2);  if (t2 == 0)    return self_promoting_args_p (t1);  while (1)    {      if (t1 == 0 && t2 == 0)	return 1;      /* If one parmlist is shorter than the other,	 they fail to match, unless STRICT is <= 0.  */      if (t1 == 0 || t2 == 0)	{	  if (strict > 0)	    return 0;	  if (strict < 0)	    return 1;	  if (strict == 0)	    return t1 && TREE_PURPOSE (t1);	}      if (! comptypes (TREE_VALUE (t2), TREE_VALUE (t1), strict))	{	  if (strict > 0)	    return 0;	  if (strict == 0)	    return t2 == void_list_node && TREE_PURPOSE (t1);	  return TREE_PURPOSE (t1) || TREE_PURPOSE (t2);	}      if (strict != 3 && TREE_PURPOSE (t1) && TREE_PURPOSE (t2))	{	  int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));	  if (cmp < 0)	    my_friendly_abort (113);	  if (cmp == 0)	    return 0;	}      t1 = TREE_CHAIN (t1);      t2 = TREE_CHAIN (t2);    }}/* This really wants return whether or not parameter type lists   would make their owning functions assignment compatible or not.  */intcomp_target_parms (parms1, parms2, strict)     tree parms1, parms2;     int strict;{  register tree t1 = parms1, t2 = parms2;  int warn_contravariance = 0;  /* An unspecified parmlist matches any specified parmlist     whose argument types don't need default promotions.  */  if (t1 == 0)    return self_promoting_args_p (t2);  if (t2 == 0)    return self_promoting_args_p (t1);  for (; t1 || t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))    {      tree p1, p2;      /* If one parmlist is shorter than the other,	 they fail to match, unless STRICT is <= 0.  */      if (t1 == 0 || t2 == 0)	{	  if (strict > 0)	    return 0;	  if (strict < 0)	    return 1 + warn_contravariance;	  return ((t1 && TREE_PURPOSE (t1)) + warn_contravariance);	}      p1 = TREE_VALUE (t1);      p2 = TREE_VALUE (t2);      if (p1 == p2)	continue;      if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)	  || (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE))	{	  if (strict <= 0	      && (TYPE_MAIN_VARIANT (TREE_TYPE (p1))		  == TYPE_MAIN_VARIANT (TREE_TYPE (p2))))	    continue;	  /* The following is wrong for contravariance,	     but many programs depend on it.  */	  if (TREE_TYPE (p1) == void_type_node)	    {	      warn_contravariance = 1;	      continue;	    }	  if (TREE_TYPE (p2) == void_type_node)	    continue;	  if (IS_AGGR_TYPE (TREE_TYPE (p1)))	    {	      if (comptypes (p2, p1, 0) == 0)		{		  if (comptypes (p1, p2, 0) != 0)		    warn_contravariance = 1;		  else		    return 0;		}	      continue;	    }	}      /* Note backwards order due to contravariance.  */      if (comp_target_types (p2, p1, 1) == 0)	{	  if (comp_target_types (p1, p2, 1))	    {	      warn_contravariance = 1;	      continue;	    }	  if (strict > 0)	    return 0;#if 0	  /* What good do these cases do?  */	  if (strict == 0)

⌨️ 快捷键说明

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