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

📄 cp-cvt.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      type = TYPE_MAIN_VARIANT (TREE_TYPE (xtype));      for (n_variants = 0; type; type = TYPE_NEXT_VARIANT (type))	n_variants++;      typenames = (tree *)alloca (n_variants * sizeof (tree));      for (n_variants = 0, type = TYPE_MAIN_VARIANT (TREE_TYPE (xtype));	   type; n_variants++, type = TYPE_NEXT_VARIANT (type))	{	  if (type == TREE_TYPE (xtype))	    typenames[n_variants] = typename;	  else if (TREE_CODE (xtype) == POINTER_TYPE)	    typenames[n_variants] = build_typename_overload (build_pointer_type (type));	  else	    typenames[n_variants] = build_typename_overload (build_reference_type (type));	}    }  save_basetype = basetype;  type = xtype;  while (TYPE_HAS_CONVERSION (basetype))    {      int i;      if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))	return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);      for (i = 0; i < n_variants; i++)	if (typenames[i] != typename	    && lookup_fnfields (TYPE_BINFO (basetype), typenames[i], 0))	  return build_type_conversion_1 (xtype, basetype, expr, typenames[i], for_sure);      if (TYPE_BINFO_BASETYPES (basetype))	basetype = TYPE_BINFO_BASETYPE (basetype, 0);      else break;    }  if (TREE_CODE (type) == REFERENCE_TYPE)    {      tree first_arg = expr;      type = TYPE_MAIN_VARIANT (TREE_TYPE (type));      basetype = save_basetype;      /* May need to build a temporary for this.  */      while (TYPE_HAS_CONVERSION (basetype))	{	  if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))	    {	      int flags;	      if (for_sure == 0)		{		  if (! lvalue_p (expr))		    first_arg = build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node);		  flags = LOOKUP_PROTECT;		}	      else		flags = LOOKUP_NORMAL;	      rval = build_method_call (first_arg, constructor_name (typename),					NULL_TREE, NULL_TREE, flags);	      if (rval == error_mark_node)		{		  if (for_sure == 0)		    return NULL_TREE;		  return error_mark_node;		}	      TREE_VALUE (TREE_OPERAND (rval, 1)) = expr;	      if (IS_AGGR_TYPE (type))		{		  tree init = build_method_call (NULL_TREE,						 constructor_name (type),						 build_tree_list (NULL_TREE, rval), NULL_TREE, LOOKUP_NORMAL);		  tree temp = build_cplus_new (type, init, 1);		  return build_up_reference (TYPE_REFERENCE_TO (type), temp,					     LOOKUP_COMPLAIN, 1);		}	      return convert (xtype, rval);	    }	  if (TYPE_BINFO_BASETYPES (basetype))	    basetype = TYPE_BINFO_BASETYPE (basetype, 0);	  else break;	}      /* No free conversions for reference types, right?.  */      return NULL_TREE;    }  if (exact_conversion)    return NULL_TREE;  /* No perfect match found, try default.  */  if (code == CONVERT_EXPR && TREE_CODE (type) == POINTER_TYPE)    type_default = ptr_type_node;  else if (type == void_type_node)    return NULL_TREE;  else    {      extern tree default_conversion ();      tree tmp = default_conversion (build1 (NOP_EXPR, type, integer_zero_node));      if (tmp == error_mark_node)	return NULL_TREE;      type_default = TREE_TYPE (tmp);    }  basetype = save_basetype;  if (type_default != type)    {      type = type_default;      typename = build_typename_overload (type);      while (TYPE_HAS_CONVERSION (basetype))	{	  if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))	    return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);	  if (TYPE_BINFO_BASETYPES (basetype))	    basetype = TYPE_BINFO_BASETYPE (basetype, 0);	  else break;	}    } try_pointer:  if (type == ptr_type_node)    {      /* Try converting to some other pointer type	 with which void* is compatible, or in situations	 in which void* is appropriate (such as &&,||, and !).  */      while (TYPE_HAS_CONVERSION (basetype))	{	  if (CLASSTYPE_CONVERSION (basetype, ptr_conv) != 0)	    {	      if (CLASSTYPE_CONVERSION (basetype, ptr_conv) == error_mark_node)		return error_mark_node;	      typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, ptr_conv));	      return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);	    }	  if (TYPE_BINFO_BASETYPES (basetype))	    basetype = TYPE_BINFO_BASETYPE (basetype, 0);	  else break;	}    }  if (TREE_CODE (type) == POINTER_TYPE      && TYPE_READONLY (TREE_TYPE (type))      && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)    {      /* Try converting to some other pointer type	 with which const void* is compatible.  */      while (TYPE_HAS_CONVERSION (basetype))	{	  if (CLASSTYPE_CONVERSION (basetype, constptr_conv) != 0)	    {	      if (CLASSTYPE_CONVERSION (basetype, constptr_conv) == error_mark_node)		return error_mark_node;	      typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, constptr_conv));	      return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);	    }	  if (TYPE_BINFO_BASETYPES (basetype))	    basetype = TYPE_BINFO_BASETYPE (basetype, 0);	  else break;	}    }  /* Use the longer or shorter conversion that is appropriate.  Have     to check against 0 because the conversion may come from a baseclass.  */  if (TREE_CODE (type) == INTEGER_TYPE      && TYPE_HAS_INT_CONVERSION (basetype)      && CLASSTYPE_CONVERSION (basetype, int_conv) != 0      && CLASSTYPE_CONVERSION (basetype, int_conv) != error_mark_node)    {      typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, int_conv));      return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);    }  if (TREE_CODE (type) == REAL_TYPE      && TYPE_HAS_REAL_CONVERSION (basetype)      && CLASSTYPE_CONVERSION (basetype, real_conv) != 0      && CLASSTYPE_CONVERSION (basetype, real_conv) != error_mark_node)    {      typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, real_conv));      return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);    }  /* THIS IS A KLUDGE.  */  if (TREE_CODE (type) != POINTER_TYPE      && (code == TRUTH_ANDIF_EXPR	  || code == TRUTH_ORIF_EXPR	  || code == TRUTH_NOT_EXPR))    {      /* Here's when we can convert to a pointer.  */      type = ptr_type_node;      goto try_pointer;    }  /* THESE ARE TOTAL KLUDGES.  */  /* Default promotion yields no new alternatives, try     conversions which are anti-default, such as     double -> float or int -> unsigned or unsigned -> long     */  if (type_default == type      && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE))    {      int not_again = 0;      if (type == double_type_node)	typename = build_typename_overload (float_type_node);      else if (type == integer_type_node)	typename = build_typename_overload (unsigned_type_node);      else if (type == unsigned_type_node)	typename = build_typename_overload (long_integer_type_node);    again:      basetype = save_basetype;      while (TYPE_HAS_CONVERSION (basetype))	{	  if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))	    return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);	  if (TYPE_BINFO_BASETYPES (basetype))	    basetype = TYPE_BINFO_BASETYPE (basetype, 0);	  else break;	}      if (! not_again)	{	  if (type == integer_type_node)	    {	      typename = build_typename_overload (long_integer_type_node);	      not_again = 1;	      goto again;	    }	  else	    {	      typename = build_typename_overload (integer_type_node);	      not_again = 1;	      goto again;	    }	}    }  /* Now, try C promotions...     float -> int     int -> float, void *     void * -> int     Truthvalue conversions let us try to convert     to pointer if we were going for int, and to int     if we were looking for pointer.  */    basetype = save_basetype;    if (TREE_CODE (type) == REAL_TYPE	|| (TREE_CODE (type) == POINTER_TYPE	    && (code == TRUTH_ANDIF_EXPR		|| code == TRUTH_ORIF_EXPR		|| code == TRUTH_NOT_EXPR)))      type = integer_type_node;    else if (TREE_CODE (type) == INTEGER_TYPE)      if (TYPE_HAS_REAL_CONVERSION (basetype))	type = double_type_node;      else	return NULL_TREE;    else      return NULL_TREE;    typename = build_typename_overload (type);    while (TYPE_HAS_CONVERSION (basetype))      {	if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))	  {	    rval = build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);	    return rval;	  }	if (TYPE_BINFO_BASETYPES (basetype))	  basetype = TYPE_BINFO_BASETYPE (basetype, 0);	else	  break;      }  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;{  tree type1 = TREE_TYPE (*arg1);  tree type2 = TREE_TYPE (*arg2);  char *name1, *name2;  if (TREE_CODE (type1) == REFERENCE_TYPE)    type1 = TREE_TYPE (type1);  if (TREE_CODE (type2) == REFERENCE_TYPE)    type2 = TREE_TYPE (type2);  if (TREE_CODE (TYPE_NAME (type1)) != TYPE_DECL)    {      tree decl = typedecl_for_tag (type1);      if (decl)	error ("type conversion nonexistent for type `%s'",	       IDENTIFIER_POINTER (DECL_NAME (decl)));      else	error ("type conversion nonexistent for non-C++ type");      return 0;    }  if (TREE_CODE (TYPE_NAME (type2)) != TYPE_DECL)    {      tree decl = typedecl_for_tag (type2);      if (decl)	error ("type conversion nonexistent for type `%s'",	       IDENTIFIER_POINTER (decl));      else	error ("type conversion nonexistent for non-C++ type");      return 0;    }  name1 = TYPE_NAME_STRING (type1);  name2 = TYPE_NAME_STRING (type2);  if (!IS_AGGR_TYPE (type1) || !TYPE_HAS_CONVERSION (type1))    {      if (!IS_AGGR_TYPE (type2) || !TYPE_HAS_CONVERSION (type2))	error ("type conversion required for binary operation on types `%s' and `%s'",	       name1, name2);      else	error ("type conversion required for type `%s'", name1);      return 0;    }  else if (!IS_AGGR_TYPE (type2) || !TYPE_HAS_CONVERSION (type2))    {      error ("type conversion required for type `%s'", name2);      return 0;    }  if (TYPE_HAS_INT_CONVERSION (type1) && TYPE_HAS_REAL_CONVERSION (type1))    warning ("ambiguous type conversion for type `%s', defaulting to int", name1);  if (TYPE_HAS_INT_CONVERSION (type1))    {      *arg1 = build_type_conversion (code, integer_type_node, *arg1, 1);      *arg2 = build_type_conversion (code, integer_type_node, *arg2, 1);    }  else if (TYPE_HAS_REAL_CONVERSION (type1))    {      *arg1 = build_type_conversion (code, double_type_node, *arg1, 1);      *arg2 = build_type_conversion (code, double_type_node, *arg2, 1);    }  else    {      *arg1 = build_type_conversion (code, ptr_type_node, *arg1, 1);      if (*arg1 == error_mark_node)	error ("ambiguous pointer conversion");      *arg2 = build_type_conversion (code, ptr_type_node, *arg2, 1);      if (*arg1 != error_mark_node && *arg2 == error_mark_node)	error ("ambiguous pointer conversion");    }  if (*arg1 == 0)    {      if (*arg2 == 0 && type1 != type2)	error ("default type conversion for types `%s' and `%s' failed",	       name1, name2);      else	error ("default type conversion for type `%s' failed", name1);      return 0;    }  else if (*arg2 == 0)    {      error ("default type conversion for type `%s' failed", name2);      return 0;    }  return 1;}/* 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.   The type of the argument is expected to be of aggregate type here.   @@ What are the real semantics of this supposed to be??? */intbuild_default_unary_type_conversion (code, arg)     enum tree_code code;     tree *arg;{  tree type = TREE_TYPE (*arg);  tree id = TREE_CODE (TYPE_NAME (type)) == TYPE_DECL    ? TYPE_IDENTIFIER (type) : TYPE_NAME (type);  char *name = IDENTIFIER_POINTER (id);  if (! TYPE_HAS_CONVERSION (type))    {      error ("type conversion required for type `%s'", name);      return 0;    }  if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type))    warning ("ambiguous type conversion for type `%s', defaulting to int", name);  if (TYPE_HAS_INT_CONVERSION (type))    *arg = build_type_conversion (code, integer_type_node, *arg, 1);  else if (TYPE_HAS_REAL_CONVERSION (type))    *arg = build_type_conversion (code, double_type_node, *arg, 1);  else    {      *arg = build_type_conversion (code, ptr_type_node, *arg, 1);      if (*arg == error_mark_node)	error ("ambiguous pointer conversion");    }  if (*arg == 0)    {      error ("default type conversion for type `%s' failed", name);      return 0;    }  return 1;}

⌨️ 快捷键说明

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