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

📄 typeck.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    case OFFSET_TYPE:      val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)),			build_pointer_type (TYPE_OFFSET_BASETYPE (t2)), strict)	     && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));      break;    case METHOD_TYPE:      if (! compexcepttypes (t1, t2))	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!  */      val = (comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)	     && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));      break;    case POINTER_TYPE:    case REFERENCE_TYPE:      t1 = TREE_TYPE (t1);      t2 = TREE_TYPE (t2);      /* first, check whether the referred types match with the         required level of strictness */      val = comptypes (t1, t2, strict);      if (val)	break;      if (TREE_CODE (t1) == RECORD_TYPE 	  && TREE_CODE (t2) == RECORD_TYPE)	goto look_hard;      break;    case FUNCTION_TYPE:      if (! compexcepttypes (t1, t2))	return 0;      val = ((TREE_TYPE (t1) == TREE_TYPE (t2)	      || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))	     && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));      break;    case ARRAY_TYPE:      /* Target types must match incl. qualifiers.  We use ORIG_STRICT	 here since this is the one place where	 COMPARE_REDECLARATION should be used.  */      val = comp_array_types (comptypes, t1, t2, orig_strict);      break;    case TEMPLATE_TYPE_PARM:      return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)	&& TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2);    case TYPENAME_TYPE:      if (TYPE_IDENTIFIER (t1) != TYPE_IDENTIFIER (t2))	return 0;      return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));    default:      break;    }  return attrval == 2 && val == 1 ? 2 : val;}/* Subroutine of comp_target-types.  Make sure that the cv-quals change   only in the same direction as the target type.  */static intcomp_cv_target_types (ttl, ttr, nptrs)     tree ttl, ttr;     int nptrs;{  int t;  if (!at_least_as_qualified_p (ttl, ttr)      && !at_least_as_qualified_p (ttr, ttl))    /* The qualifications are incomparable.  */    return 0;  if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))    return more_qualified_p (ttr, ttl) ? -1 : 1;  t = comp_target_types (ttl, ttr, nptrs);  if ((t == 1 && at_least_as_qualified_p (ttl, ttr))       || (t == -1 && at_least_as_qualified_p (ttr, ttl)))    return t;  return 0;}/* Return 1 or -1 if TTL and TTR are pointers to types that are equivalent,   ignoring their qualifiers, 0 if not. Return 1 means that TTR can be   converted to TTL. Return -1 means that TTL can be converted to TTR but   not vice versa.   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**.   This should go away.  Callers should use can_convert or something   similar instead.  (jason 17 Apr 1997)  */intcomp_target_types (ttl, ttr, nptrs)     tree ttl, ttr;     int nptrs;{  ttl = TYPE_MAIN_VARIANT (ttl);  ttr = TYPE_MAIN_VARIANT (ttr);  if (same_type_p (ttl, ttr))    return 1;  if (TREE_CODE (ttr) != TREE_CODE (ttl))    return 0;  if ((TREE_CODE (ttr) == POINTER_TYPE       || TREE_CODE (ttr) == REFERENCE_TYPE)      /* If we get a pointer with nptrs == 0, we don't allow any tweaking	 of the type pointed to.  This is necessary for reference init	 semantics.  We won't get here from a previous call with nptrs == 1;	 for multi-level pointers we end up in comp_ptr_ttypes.  */      && nptrs > 0)    {      int is_ptr = TREE_CODE (ttr) == POINTER_TYPE;      ttl = TREE_TYPE (ttl);      ttr = TREE_TYPE (ttr);      if (is_ptr)	{	  if (TREE_CODE (ttl) == UNKNOWN_TYPE	      || TREE_CODE (ttr) == UNKNOWN_TYPE)	    return 1;	  else if (TREE_CODE (ttl) == VOID_TYPE		   && TREE_CODE (ttr) != FUNCTION_TYPE		   && TREE_CODE (ttr) != METHOD_TYPE		   && TREE_CODE (ttr) != OFFSET_TYPE)	    return 1;	  else if (TREE_CODE (ttr) == VOID_TYPE		   && TREE_CODE (ttl) != FUNCTION_TYPE		   && TREE_CODE (ttl) != METHOD_TYPE		   && TREE_CODE (ttl) != OFFSET_TYPE)	    return -1;	  else if (TREE_CODE (ttl) == POINTER_TYPE		   || TREE_CODE (ttl) == ARRAY_TYPE)	    {	      if (comp_ptr_ttypes (ttl, ttr))		return 1;	      else if (comp_ptr_ttypes (ttr, ttl))		return -1;	      return 0;	    }	}      /* Const and volatile mean something different for function types,	 so the usual checks are not appropriate.  */      if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE)	return comp_target_types (ttl, ttr, nptrs - 1);      return comp_cv_target_types (ttl, ttr, nptrs - 1);    }  if (TREE_CODE (ttr) == ARRAY_TYPE)    return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT);  else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)    {      tree argsl, argsr;      int saw_contra = 0;      if (pedantic)	{	  if (!same_type_p (TREE_TYPE (ttl), TREE_TYPE (ttr)))	    return 0;	}      else	{	  switch (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), -1))	    {	    case 0:	      return 0;	    case -1:	      saw_contra = 1;	    }	}      argsl = TYPE_ARG_TYPES (ttl);      argsr = TYPE_ARG_TYPES (ttr);      /* Compare 'this' here, not in comp_target_parms.  */      if (TREE_CODE (ttr) == METHOD_TYPE)	{	  tree tl = TYPE_METHOD_BASETYPE (ttl);	  tree tr = TYPE_METHOD_BASETYPE (ttr);	  if (!same_or_base_type_p (tr, tl))	    {	      if (same_or_base_type_p (tl, tr))		saw_contra = 1;	      else		return 0;	    }	  argsl = TREE_CHAIN (argsl);	  argsr = TREE_CHAIN (argsr);	}	switch (comp_target_parms (argsl, argsr, 1))	  {	  case 0:	    return 0;	  case -1:	    saw_contra = 1;	  }	return saw_contra ? -1 : 1;    }  /* for C++ */  else if (TREE_CODE (ttr) == OFFSET_TYPE)    {      int base;      /* 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 (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttr),			       TYPE_OFFSET_BASETYPE (ttl)))	base = 1;      else if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttl),				    TYPE_OFFSET_BASETYPE (ttr)))	{	  tree tmp = ttl;	  ttl = ttr;	  ttr = tmp;	  base = -1;	}      else	return 0;      ttl = TREE_TYPE (ttl);      ttr = TREE_TYPE (ttr);      if (TREE_CODE (ttl) == POINTER_TYPE	  || TREE_CODE (ttl) == ARRAY_TYPE)	{	  if (comp_ptr_ttypes (ttl, ttr))	    return base;	  return 0;	}      else	{	  if (comp_cv_target_types (ttl, ttr, nptrs) == 1)	    return base;	  return 0;	}    }  else if (IS_AGGR_TYPE (ttl))    {      if (nptrs < 0)	return 0;      if (same_or_base_type_p (build_pointer_type (ttl), 			       build_pointer_type (ttr)))	return 1;      if (same_or_base_type_p (build_pointer_type (ttr), 			       build_pointer_type (ttl)))	return -1;      return 0;    }  return 0;}/* Returns 1 if TYPE1 is at least as qualified as TYPE2.  */intat_least_as_qualified_p (type1, type2)     tree type1;     tree type2;{  /* All qualifiers for TYPE2 must also appear in TYPE1.  */  return ((CP_TYPE_QUALS (type1) & CP_TYPE_QUALS (type2))	  == CP_TYPE_QUALS (type2));}/* Returns 1 if TYPE1 is more qualified than TYPE2.  */intmore_qualified_p (type1, type2)     tree type1;     tree type2;{  return (CP_TYPE_QUALS (type1) != CP_TYPE_QUALS (type2)	  && at_least_as_qualified_p (type1, type2));}/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is   more cv-qualified that TYPE1, and 0 otherwise.  */intcomp_cv_qualification (type1, type2)     tree type1;     tree type2;{  if (CP_TYPE_QUALS (type1) == CP_TYPE_QUALS (type2))    return 0;  if (at_least_as_qualified_p (type1, type2))    return 1;  else if (at_least_as_qualified_p (type2, type1))    return -1;  return 0;}/* Returns 1 if the cv-qualification signature of TYPE1 is a proper   subset of the cv-qualification signature of TYPE2, and the types   are similar.  Returns -1 if the other way 'round, and 0 otherwise.  */intcomp_cv_qual_signature (type1, type2)     tree type1;     tree type2;{  if (comp_ptr_ttypes_real (type2, type1, -1))    return 1;  else if (comp_ptr_ttypes_real (type1, type2, -1))    return -1;  else    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.  */static treecommon_base_type (tt1, tt2)     tree tt1, tt2;{  tree best = NULL_TREE;  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;  /* 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.  The two lists must be equivalent,   element by element.   C++: See comment above about TYPE1, TYPE2.  */intcompparms (parms1, parms2)     tree parms1, parms2;{  register tree t1 = parms1, t2 = parms2;  /* An unspecified parmlist matches any specified parmlist     whose argument types don't need default promotions.  */  while (1)    {      if (t1 == 0 && t2 == 0)	return 1;      /* If one parmlist is shorter than the other,	 they fail to match.  */      if (t1 == 0 || t2 == 0)	return 0;      if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1)))	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.   The return value is like for comp_target_types.   This should go away, possibly with the exception of the empty parmlist   conversion; there are no conversions between function types in C++.   (jason 17 Apr 1997)  */static intcomp_target_parms (parms1, parms2, strict)     tree parms1, parms2;     int strict;{  register tree t1 = parms1, t2 = parms2;  int warn_contravariance = 0;  /* In C, an unspecified parmlist matches any specified parmlist     whose argument types don't need default promotions.  This is not     true for C++, but let's do it anyway for unfixed headers.  */  if (t1 == 0 && t2 != 0)    {      if (! flag_strict_prototype && t2 == void_list_node)	/* t1 might be the arglist of a function pointer in extern "C"	   declared to take (), which we fudged to (...).  Don't make the	   user pay for our mistake.  */;      else	cp_pedwarn ("ANSI C++ prohibits conversion from `%#T' to `(...)'",		    parms2);      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,

⌨️ 快捷键说明

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