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

📄 cvt.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
      && TREE_TYPE (TREE_TYPE (e)) == TREE_TYPE (type)      && index_type_equal (TYPE_DOMAIN (TREE_TYPE (e)), TYPE_DOMAIN (type)))    return e;  if (flags & LOOKUP_COMPLAIN)    cp_error ("conversion from `%T' to non-scalar type `%T' requested",	      TREE_TYPE (expr), type);  if (flags & LOOKUP_SPECULATIVELY)    return NULL_TREE;  return error_mark_node;}/* Create an expression whose value is that of EXPR,   converted to type TYPE.  The TREE_TYPE of the value   is always TYPE.  This function implements all reasonable   conversions; callers should filter out those that are   not permitted by the language being compiled.  */treeconvert (type, expr)     tree type, expr;{  return cp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);}/* Like convert, except permit conversions to take place which   are not normally allowed due to access restrictions   (such as conversion from sub-type to private super-type).  */treeconvert_force (type, expr, convtype)     tree type;     tree expr;     int convtype;{  register tree e = expr;  register enum tree_code code = TREE_CODE (type);  if (code == REFERENCE_TYPE)    return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,				       NULL_TREE));  else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)    e = convert_from_reference (e);  if (code == POINTER_TYPE)    return fold (convert_to_pointer_force (type, e));  /* From typeck.c convert_for_assignment */  if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR	&& TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE	&& TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE)       || integer_zerop (e)       || TYPE_PTRMEMFUNC_P (TREE_TYPE (e)))      && TYPE_PTRMEMFUNC_P (type))    {      /* compatible pointer to member functions. */      return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1);    }  return cp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);}/* Subroutine of build_type_conversion.  */static treebuild_type_conversion_1 (xtype, basetype, expr, typename, for_sure)     tree xtype, basetype;     tree expr;     tree typename;     int for_sure;{  tree rval;  int flags;  if (for_sure == 0)    flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;  else    flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;  rval = build_method_call (expr, typename, NULL_TREE, NULL_TREE, flags);  if (rval == error_mark_node)    {      if (for_sure == 0)	return NULL_TREE;      return error_mark_node;    }  if (IS_AGGR_TYPE (TREE_TYPE (rval)))    return rval;  if (warn_cast_qual      && TREE_TYPE (xtype)      && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))	  > TREE_READONLY (TREE_TYPE (xtype))))    warning ("user-defined conversion casting away `const'");  return convert (xtype, rval);}/* Convert an aggregate EXPR to type XTYPE.  If a conversion   exists, return the attempted conversion.  This may   return ERROR_MARK_NODE if the conversion is not   allowed (references private members, etc).   If no conversion exists, NULL_TREE is returned.   If (FOR_SURE & 1) is non-zero, then we allow this type conversion   to take place immediately.  Otherwise, we build a SAVE_EXPR   which can be evaluated if the results are ever needed.   Changes to this functions should be mirrored in user_harshness.   FIXME: Ambiguity checking is wrong.  Should choose one by the implicit   object parameter, or by the second standard conversion sequence if   that doesn't do it.  This will probably wait for an overloading rewrite.   (jason 8/9/95)  */treebuild_type_conversion (code, xtype, expr, for_sure)     enum tree_code code;     tree xtype, expr;     int for_sure;{  /* C++: check to see if we can convert this aggregate type     into the required type.  */  tree basetype;  tree conv;  tree winner = NULL_TREE;  if (expr == error_mark_node)    return error_mark_node;  basetype = TREE_TYPE (expr);  if (TREE_CODE (basetype) == REFERENCE_TYPE)    basetype = TREE_TYPE (basetype);  basetype = TYPE_MAIN_VARIANT (basetype);  if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype))    return NULL_TREE;  /* Do we have an exact match?  */  {    tree typename = build_typename_overload (xtype);    if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))      return build_type_conversion_1 (xtype, basetype, expr, typename,				      for_sure);  }  /* Nope; try looking for others.  */  for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))    {      if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))	continue;      if (can_convert (xtype, TREE_VALUE (conv)))	{	  if (winner)	    {	      if (for_sure)		{		  cp_error ("ambiguous conversion from `%T' to `%T'", basetype,			    xtype);		  cp_error ("  candidate conversions include `%T' and `%T'",			    TREE_VALUE (winner), TREE_VALUE (conv));		}	      return NULL_TREE;	    }	  else	    winner = conv;	}    }  if (winner)    return build_type_conversion_1 (xtype, basetype, expr,				    TREE_PURPOSE (winner), for_sure);  return NULL_TREE;}/* Convert the given EXPR to one of a group of types suitable for use in an   expression.  DESIRES is a combination of various WANT_* flags (q.v.)   which indicates which types are suitable.  If COMPLAIN is 1, complain   about ambiguity; otherwise, the caller will deal with it.  */treebuild_expr_type_conversion (desires, expr, complain)     int desires;     tree expr;     int complain;{  tree basetype = TREE_TYPE (expr);  tree conv;  tree winner = NULL_TREE;  if (TREE_CODE (basetype) == OFFSET_TYPE)    expr = resolve_offset_ref (expr);  expr = convert_from_reference (expr);  basetype = TREE_TYPE (expr);  if (! IS_AGGR_TYPE (basetype))    switch (TREE_CODE (basetype))      {      case INTEGER_TYPE:	if ((desires & WANT_NULL) && TREE_CODE (expr) == INTEGER_CST	    && integer_zerop (expr))	  return expr;	/* else fall through... */      case BOOLEAN_TYPE:	return (desires & WANT_INT) ? expr : NULL_TREE;      case ENUMERAL_TYPE:	return (desires & WANT_ENUM) ? expr : NULL_TREE;      case REAL_TYPE:	return (desires & WANT_FLOAT) ? expr : NULL_TREE;      case POINTER_TYPE:	return (desires & WANT_POINTER) ? expr : NULL_TREE;	      case FUNCTION_TYPE:      case ARRAY_TYPE:	return (desires & WANT_POINTER) ? default_conversion (expr)     	                                : NULL_TREE;      default:	return NULL_TREE;      }  if (! TYPE_HAS_CONVERSION (basetype))    return NULL_TREE;  for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))    {      int win = 0;      tree candidate;      if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))	continue;      candidate = TREE_VALUE (conv);      if (TREE_CODE (candidate) == REFERENCE_TYPE)	candidate = TREE_TYPE (candidate);      switch (TREE_CODE (candidate))	{	case BOOLEAN_TYPE:	case INTEGER_TYPE:	  win = (desires & WANT_INT); break;	case ENUMERAL_TYPE:	  win = (desires & WANT_ENUM); break;	case REAL_TYPE:	  win = (desires & WANT_FLOAT); break;	case POINTER_TYPE:	  win = (desires & WANT_POINTER); break;	}      if (win)	{	  if (winner)	    {	      if (complain)		{		  cp_error ("ambiguous default type conversion from `%T'",			    basetype);		  cp_error ("  candidate conversions include `%T' and `%T'",			    TREE_VALUE (winner), TREE_VALUE (conv));		}	      return error_mark_node;	    }	  else	    winner = conv;	}    }  if (winner)    return build_type_conversion_1 (TREE_VALUE (winner), basetype, expr,				    TREE_PURPOSE (winner), 1);  return NULL_TREE;}/* Must convert two aggregate types to non-aggregate type.   Attempts to find a non-ambiguous, "best" type conversion.   Return 1 on success, 0 on failure.   @@ What are the real semantics of this supposed to be??? */intbuild_default_binary_type_conversion (code, arg1, arg2)     enum tree_code code;     tree *arg1, *arg2;{  switch (code)    {    case MULT_EXPR:    case TRUNC_DIV_EXPR:    case CEIL_DIV_EXPR:    case FLOOR_DIV_EXPR:    case ROUND_DIV_EXPR:    case EXACT_DIV_EXPR:      *arg1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);      *arg2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);      break;    case TRUNC_MOD_EXPR:    case FLOOR_MOD_EXPR:    case LSHIFT_EXPR:    case RSHIFT_EXPR:    case BIT_AND_EXPR:    case BIT_XOR_EXPR:    case BIT_IOR_EXPR:      *arg1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, *arg1, 0);      *arg2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, *arg2, 0);      break;    case PLUS_EXPR:      {	tree a1, a2, p1, p2;	int wins;	a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);	a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);	p1 = build_expr_type_conversion (WANT_POINTER, *arg1, 0);	p2 = build_expr_type_conversion (WANT_POINTER, *arg2, 0);	wins = (a1 && a2) + (a1 && p2) + (p1 && a2);	if (wins > 1)	  error ("ambiguous default type conversion for `operator +'");	if (a1 && a2)	  *arg1 = a1, *arg2 = a2;	else if (a1 && p2)	  *arg1 = a1, *arg2 = p2;	else	  *arg1 = p1, *arg2 = a2;	break;      }    case MINUS_EXPR:      {	tree a1, a2, p1, p2;	int wins;	a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);	a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);	p1 = build_expr_type_conversion (WANT_POINTER, *arg1, 0);	p2 = build_expr_type_conversion (WANT_POINTER, *arg2, 0);	wins = (a1 && a2) + (p1 && p2) + (p1 && a2);	if (wins > 1)	  error ("ambiguous default type conversion for `operator -'");	if (a1 && a2)	  *arg1 = a1, *arg2 = a2;	else if (p1 && p2)	  *arg1 = p1, *arg2 = p2;	else	  *arg1 = p1, *arg2 = a2;	break;      }    case GT_EXPR:    case LT_EXPR:    case GE_EXPR:    case LE_EXPR:    case EQ_EXPR:    case NE_EXPR:      {	tree a1, a2, p1, p2;	int wins;	a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);	a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);	p1 = build_expr_type_conversion (WANT_POINTER | WANT_NULL, *arg1, 0);	p2 = build_expr_type_conversion (WANT_POINTER | WANT_NULL, *arg2, 0);	wins = (a1 && a2) + (p1 && p2);	if (wins > 1)	  cp_error ("ambiguous default type conversion for `%O'", code);	if (a1 && a2)	  *arg1 = a1, *arg2 = a2;	else	  *arg1 = p1, *arg2 = p2;	break;      }    case TRUTH_ANDIF_EXPR:    case TRUTH_ORIF_EXPR:      *arg1 = convert (boolean_type_node, *arg1);      *arg2 = convert (boolean_type_node, *arg2);      break;    default:      *arg1 = NULL_TREE;      *arg2 = NULL_TREE;    }  if (*arg1 == error_mark_node || *arg2 == error_mark_node)    cp_error ("ambiguous default type conversion for `%O'", code);  if (*arg1 && *arg2)    return 1;  return 0;}/* Implements integral promotion (4.1) and float->double promotion. */treetype_promotes_to (type)     tree type;{  int constp, volatilep;  if (type == error_mark_node)    return error_mark_node;  constp = TYPE_READONLY (type);  volatilep = TYPE_VOLATILE (type);  type = TYPE_MAIN_VARIANT (type);  /* bool always promotes to int (not unsigned), even if it's the same     size.  */  if (type == boolean_type_node)    type = integer_type_node;  /* Normally convert enums to int, but convert wide enums to something     wider.  */  else if (TREE_CODE (type) == ENUMERAL_TYPE	   || type == wchar_type_node)    {      int precision = MAX (TYPE_PRECISION (type),			   TYPE_PRECISION (integer_type_node));      tree totype = type_for_size (precision, 0);      if (TREE_UNSIGNED (type)	  && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype))	type = type_for_size (precision, 1);      else	type = totype;    }  else if (C_PROMOTING_INTEGER_TYPE_P (type))    {      /* Traditionally, unsignedness is preserved in default promotions.         Otherwise, retain unsignedness if really not getting bigger.  */      if (TREE_UNSIGNED (type)	  && (flag_traditional	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))	type = unsigned_type_node;      else	type = integer_type_node;    }  else if (type == float_type_node)    type = double_type_node;  return cp_build_type_variant (type, constp, volatilep);}

⌨️ 快捷键说明

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