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

📄 cvt.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* The type of the first argument will be filled in inside the loop.  */  parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist);  parmtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes);#if 0  method_name = build_decl_overload (name, parmtypes, 1);  /* constructors are up front.  */  fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);  if (TYPE_HAS_DESTRUCTOR (basetype))    fndecl = DECL_CHAIN (fndecl);  while (fndecl)    {      if (DECL_ASSEMBLER_NAME (fndecl) == method_name)	{	  function = fndecl;	  if (protect)	    {	      if (TREE_PRIVATE (fndecl))		{		  can_be_private =		    (basetype == current_class_type		     || is_friend (basetype, current_function_decl)		     || purpose_member (basetype, DECL_ACCESS (fndecl)));		  if (! can_be_private)		    goto found;		}	      else if (TREE_PROTECTED (fndecl))		{		  if (! can_be_protected)		    goto found;		}	    }	  goto found_and_ok;	}      fndecl = DECL_CHAIN (fndecl);    }#endif  /* No exact conversion was found.  See if an approximate     one will do.  */  fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);  if (TYPE_HAS_DESTRUCTOR (basetype))    fndecl = DECL_CHAIN (fndecl);  {    int saw_private = 0;    int saw_protected = 0;    struct candidate *candidates =      (struct candidate *) alloca ((decl_list_length (fndecl)+1) * sizeof (struct candidate));    struct candidate *cp = candidates;    while (fndecl)      {	function = fndecl;	cp->h_len = 2;	cp->harshness = (struct harshness_code *)	  alloca (3 * sizeof (struct harshness_code));	compute_conversion_costs (fndecl, parmlist, cp, 2);	if ((cp->h.code & EVIL_CODE) == 0)	  {	    cp->u.field = fndecl;	    if (protect)	      {		if (TREE_PRIVATE (fndecl))		  access = access_private;		else if (TREE_PROTECTED (fndecl))		  access = access_protected;		else		  access = access_public;	      }	    else	      access = access_public;	    if (access == access_private		? (basetype == current_class_type		   || is_friend (basetype, cp->function)		   || purpose_member (basetype, DECL_ACCESS (fndecl)))		: access == access_protected		? (can_be_protected		   || purpose_member (basetype, DECL_ACCESS (fndecl)))		: 1)	      {		if (cp->h.code <= TRIVIAL_CODE)		  goto found_and_ok;		cp++;	      }	    else	      {		if (access == access_private)		  saw_private = 1;		else		  saw_protected = 1;	      }	  }	fndecl = DECL_CHAIN (fndecl);      }    if (cp - candidates)      {	/* Rank from worst to best.  Then cp will point to best one.	   Private fields have their bits flipped.  For unsigned	   numbers, this should make them look very large.	   If the best alternate has a (signed) negative value,	   then all we ever saw were private members.  */	if (cp - candidates > 1)	  qsort (candidates,	/* char *base */		 cp - candidates, /* int nel */		 sizeof (struct candidate), /* int width */		 rank_for_overload); /* int (*compar)() */	--cp;	if (cp->h.code & EVIL_CODE)	  {	    if (msgp)	      *msgp = "ambiguous type conversion possible for `%s'";	    return error_mark_node;	  }	function = cp->function;	fndecl = cp->u.field;	goto found_and_ok;      }    else if (msgp)      {	if (saw_private)	  if (saw_protected)	    *msgp = "only private and protected conversions apply";	  else	    *msgp = "only private conversions apply";	else if (saw_protected)	  *msgp = "only protected conversions apply";	else	  *msgp = "no appropriate conversion to type `%s'";      }    return error_mark_node;  }  /* NOTREACHED */ found:  if (access == access_private)    if (! can_be_private)      {	if (msgp)	  *msgp = TREE_PRIVATE (fndecl)	    ? "conversion to type `%s' is private"	    : "conversion to type `%s' is from private base class";	return error_mark_node;      }  if (access == access_protected)    if (! can_be_protected)      {	if (msgp)	  *msgp = TREE_PRIVATE (fndecl)	    ? "conversion to type `%s' is protected"	    : "conversion to type `%s' is from protected base class";	return error_mark_node;      }  function = fndecl; found_and_ok:  /* It will convert, but we don't do anything about it yet.  */  if (msgp == 0)    return NULL_TREE;  fntype = TREE_TYPE (function);  function = default_conversion (function);  result = build_nt (CALL_EXPR, function,		     convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),					parmlist, NULL_TREE, LOOKUP_NORMAL),		     NULL_TREE);  TREE_TYPE (result) = TREE_TYPE (fntype);  TREE_SIDE_EFFECTS (result) = 1;  return result;}/* Call this when we know (for any reason) that expr is not, in fact,   zero.  This routine is like convert_pointer_to, but it pays   attention to which specific instance of what type we want to   convert to.  This routine should eventually become   convert_to_pointer after all references to convert_to_pointer   are removed.  */treeconvert_pointer_to_real (binfo, expr)     tree binfo, expr;{  register tree intype = TREE_TYPE (expr);  tree ptr_type;  tree type, rval;  if (TREE_CODE (binfo) == TREE_VEC)    type = BINFO_TYPE (binfo);  else if (IS_AGGR_TYPE (binfo))    {      type = binfo;    }  else    {      type = binfo;      binfo = NULL_TREE;    }  ptr_type = build_pointer_type (type);  if (ptr_type == TYPE_MAIN_VARIANT (intype))    return expr;  if (intype == error_mark_node)    return error_mark_node;  my_friendly_assert (!integer_zerop (expr), 191);  if (TREE_CODE (type) == RECORD_TYPE      && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE      && type != TYPE_MAIN_VARIANT (TREE_TYPE (intype)))    {      tree path;      int distance	= get_base_distance (binfo, TYPE_MAIN_VARIANT (TREE_TYPE (intype)),			     0, &path);      /* This function shouldn't be called with unqualified arguments	 but if it is, give them an error message that they can read.  */      if (distance < 0)	{	  cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'",		    TREE_TYPE (intype), type);	  if (distance == -2)	    cp_error ("because `%T' is an ambiguous base class", type);	  return error_mark_node;	}      return build_vbase_path (PLUS_EXPR, ptr_type, expr, path, 1);    }  rval = build1 (NOP_EXPR, ptr_type,		 TREE_CODE (expr) == NOP_EXPR ? TREE_OPERAND (expr, 0) : expr);  TREE_CONSTANT (rval) = TREE_CONSTANT (expr);  return rval;}/* Call this when we know (for any reason) that expr is   not, in fact, zero.  This routine gets a type out of the first   argument and uses it to search for the type to convert to.  If there   is more than one instance of that type in the expr, the conversion is   ambiguous.  This routine should eventually go away, and all   callers should use convert_to_pointer_real.  */treeconvert_pointer_to (binfo, expr)     tree binfo, expr;{  tree type;  if (TREE_CODE (binfo) == TREE_VEC)    type = BINFO_TYPE (binfo);  else if (IS_AGGR_TYPE (binfo))      type = binfo;  else      type = binfo;  return convert_pointer_to_real (type, expr);}/* Conversion...   FLAGS indicates how we should behave.  */treecp_convert (type, expr, convtype, flags)     tree type, expr;     int convtype, flags;{  register tree e = expr;  register enum tree_code code = TREE_CODE (type);  if (TREE_CODE (e) == ERROR_MARK      || TREE_CODE (TREE_TYPE (e)) == ERROR_MARK)    return error_mark_node;  if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP))    /* We need a new temporary; don't take this shortcut.  */;  else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))    /* Trivial conversion: cv-qualifiers do not matter on rvalues.  */    return fold (build1 (NOP_EXPR, type, e));    if (code == VOID_TYPE && (convtype & CONV_STATIC))    return build1 (CONVERT_EXPR, type, e);#if 0  /* This is incorrect.  A truncation can't be stripped this way.     Extensions will be stripped by the use of get_unwidened.  */  if (TREE_CODE (e) == NOP_EXPR)    return convert (type, TREE_OPERAND (e, 0));#endif  /* Just convert to the type of the member.  */  if (code == OFFSET_TYPE)    {      type = TREE_TYPE (type);      code = TREE_CODE (type);    }#if 0  if (code == REFERENCE_TYPE)    return fold (convert_to_reference (type, e, convtype, flags, NULL_TREE));  else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)    e = convert_from_reference (e);#endif  if (TREE_CODE (e) == OFFSET_REF)    e = resolve_offset_ref (e);  if (TREE_READONLY_DECL_P (e))    e = decl_constant_value (e);  if (INTEGRAL_CODE_P (code))    {      tree intype = TREE_TYPE (e);      enum tree_code form = TREE_CODE (intype);      /* enum = enum, enum = int, enum = float are all errors. */      if (flag_int_enum_equivalence == 0	  && TREE_CODE (type) == ENUMERAL_TYPE	  && ARITHMETIC_TYPE_P (intype)	  && ! (convtype & CONV_STATIC))	{	  cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type);	  if (flag_pedantic_errors)	    return error_mark_node;	}      if (IS_AGGR_TYPE (intype))	{	  tree rval;	  rval = build_type_conversion (CONVERT_EXPR, type, e, 1);	  if (rval)	    return rval;	  if (flags & LOOKUP_COMPLAIN)	    cp_error ("`%#T' used where a `%T' was expected", intype, type);	  if (flags & LOOKUP_SPECULATIVELY)	    return NULL_TREE;	  return error_mark_node;	}      if (code == BOOLEAN_TYPE)	return truthvalue_conversion (e);      return fold (convert_to_integer (type, e));    }  if (code == POINTER_TYPE || code == REFERENCE_TYPE      || TYPE_PTRMEMFUNC_P (type))    return fold (cp_convert_to_pointer (type, e));  if (code == REAL_TYPE)    {      if (IS_AGGR_TYPE (TREE_TYPE (e)))	{	  tree rval;	  rval = build_type_conversion (CONVERT_EXPR, 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));	}      return fold (convert_to_real (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;      tree conversion = 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.  */      if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype)	  && TYPE_HAS_CONVERSION (dtype))	conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);      if (conversion == error_mark_node)	{	  if (flags & LOOKUP_COMPLAIN)	    error ("ambiguous pointer conversion");	  return conversion;	}      if (TYPE_HAS_CONSTRUCTOR (type))	ctor = build_method_call (NULL_TREE, constructor_name_full (type),				  build_tree_list (NULL_TREE, e),				  TYPE_BINFO (type),				  (flags & LOOKUP_NORMAL) | LOOKUP_SPECULATIVELY				  | (convtype&CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING)				  | (conversion ? LOOKUP_NO_CONVERSION : 0));      if (ctor == error_mark_node)	{	  if (flags & LOOKUP_COMPLAIN)	    cp_error ("in conversion to type `%T'", type);	  if (flags & LOOKUP_SPECULATIVELY)	    return NULL_TREE;	  return error_mark_node;	}            if (conversion && ctor)	{	  if (flags & LOOKUP_COMPLAIN)	    error ("both constructor and type conversion operator apply");	  if (flags & LOOKUP_SPECULATIVELY)	    return NULL_TREE;	  return error_mark_node;	}      else if (conversion)	return conversion;      else if (ctor)	{	  ctor = build_cplus_new (type, ctor, 0);	  return ctor;	}    }  /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack,     then the it won't be hashed and hence compare as not equal,     even when it is.  */  if (code == ARRAY_TYPE

⌨️ 快捷键说明

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