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

📄 cvt.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
	  rval = build_type_conversion (type, e, 1);	  if (rval)	    return rval;	  else	    if (flags & LOOKUP_COMPLAIN)	      cp_error ("`%#T' used where a floating point value was expected",			TREE_TYPE (e));	}      if (code == REAL_TYPE)	return fold (convert_to_real (type, e));      else if (code == COMPLEX_TYPE)	return fold (convert_to_complex (type, e));    }  /* New C++ semantics:  since assignment is now based on     memberwise copying,  if the rhs type is derived from the     lhs type, then we may still do a conversion.  */  if (IS_AGGR_TYPE_CODE (code))    {      tree dtype = TREE_TYPE (e);      tree ctor = NULL_TREE;      dtype = TYPE_MAIN_VARIANT (dtype);      /* Conversion of object pointers or signature pointers/references	 to signature pointers/references.  */      if (TYPE_LANG_SPECIFIC (type)	  && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type)))	{	  tree constructor = build_signature_pointer_constructor (type, expr);	  tree sig_ty = SIGNATURE_TYPE (type);	  tree sig_ptr;	  if (constructor == error_mark_node)	    return error_mark_node;	  sig_ptr = get_temp_name (type, 1);	  DECL_INITIAL (sig_ptr) = constructor;	  CLEAR_SIGNATURE (sig_ty);	  cp_finish_decl (sig_ptr, constructor, NULL_TREE, 0, 0);	  SET_SIGNATURE (sig_ty);	  TREE_READONLY (sig_ptr) = 1;	  return sig_ptr;	}      /* Conversion between aggregate types.  New C++ semantics allow	 objects of derived type to be cast to objects of base type.	 Old semantics only allowed this between pointers.	 There may be some ambiguity between using a constructor	 vs. using a type conversion operator when both apply.  */      ctor = e;      if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type))	{	  abstract_virtuals_error (NULL_TREE, type);	  return error_mark_node;	}      if ((flags & LOOKUP_ONLYCONVERTING)	  && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype)))	/* For copy-initialization, first we create a temp of the proper type	   with a user-defined conversion sequence, then we direct-initialize	   the target with the temp (see [dcl.init]).  */	ctor = build_user_type_conversion (type, ctor, flags);      if (ctor)	ctor = build_method_call (NULL_TREE, ctor_identifier,				  build_expr_list (NULL_TREE, ctor),				  TYPE_BINFO (type), flags);      if (ctor)	return build_cplus_new (type, ctor);    }  /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack,     then it won't be hashed and hence compare as not equal,     even when it is.  */  if (code == ARRAY_TYPE      && 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.   Most of this routine is from build_reinterpret_cast.   The backend cannot call cp_convert (what was convert) because   conversions to/from basetypes may involve memory references   (vbases) and adding or subtracting small values (multiple   inheritance), but it calls convert from the constant folding code   on subtrees of already build trees after it has ripped them apart.   Also, if we ever support range variables, we'll probably also have to   do a little bit more work.  */treeconvert (type, expr)     tree type, expr;{  tree intype;  if (type == error_mark_node || expr == error_mark_node)    return error_mark_node;  intype = TREE_TYPE (expr);  if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))    {      if (TREE_READONLY_DECL_P (expr))	expr = decl_constant_value (expr);      return fold (build1 (NOP_EXPR, type, expr));    }  return ocp_convert (type, expr, CONV_OLD_CONVERT,		      LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);}/* Like cp_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 ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);}/* 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 (xtype, expr, for_sure)     tree xtype, expr;     int for_sure;{  /* C++: check to see if we can convert this aggregate type     into the required type.  */  return build_user_type_conversion    (xtype, expr, for_sure ? LOOKUP_NORMAL : 0);}/* 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 = NULL_TREE;  tree winner = NULL_TREE;  if (expr == null_node       && (desires & WANT_INT)       && !(desires & WANT_NULL))    cp_warning ("converting NULL to non-pointer type");      if (TREE_CODE (expr) == OFFSET_REF)    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) && null_ptr_cst_p (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;      }  /* The code for conversions from class type is currently only used for     delete expressions.  Other expressions are handled by build_new_op.  */  if (! TYPE_HAS_CONVERSION (basetype))    return NULL_TREE;  for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))    {      int win = 0;      tree candidate;      tree cand = TREE_VALUE (conv);      if (winner && winner == cand)	continue;      candidate = TREE_TYPE (TREE_TYPE (cand));      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;	default:	  break;	}      if (win)	{	  if (winner)	    {	      if (complain)		{		  cp_error ("ambiguous default type conversion from `%T'",			    basetype);		  cp_error ("  candidate conversions include `%D' and `%D'",			    winner, cand);		}	      return error_mark_node;	    }	  else	    winner = cand;	}    }  if (winner)    {      tree type = TREE_TYPE (TREE_TYPE (winner));      if (TREE_CODE (type) == REFERENCE_TYPE)	type = TREE_TYPE (type);      return build_user_type_conversion (type, expr, LOOKUP_NORMAL);    }  return NULL_TREE;}/* Implements integral promotion (4.1) and float->double promotion.  */treetype_promotes_to (type)     tree type;{  int type_quals;  if (type == error_mark_node)    return error_mark_node;  type_quals = CP_TYPE_QUALS (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))    {      /* Retain unsignedness if really not getting bigger.  */      if (TREE_UNSIGNED (type)	  && 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_qualified_type (type, type_quals);}/* The routines below this point are carefully written to conform to   the standard.  They use the same terminology, and follow the rules   closely.  Although they are used only in pt.c at the moment, they   should presumably be used everywhere in the future.  *//* Attempt to perform qualification conversions on EXPR to convert it   to TYPE.  Return the resulting expression, or error_mark_node if   the conversion was impossible.  */tree perform_qualification_conversions (type, expr)     tree type;     tree expr;{  if (TREE_CODE (type) == POINTER_TYPE      && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE      && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (expr))))    return build1 (NOP_EXPR, type, expr);  else    return error_mark_node;}

⌨️ 快捷键说明

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