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

📄 cvt.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
    case RESULT_DECL:      if (staticp (targ))	literal_flag = 1;      TREE_ADDRESSABLE (targ) = 1;      put_var_into_stack (targ);      break;    case PARM_DECL:#if 0      if (targ == current_class_decl)	{	  error ("address of `this' not available");/* #if 0 */	  	  /* This code makes the following core dump the compiler on a sun4,	     if the code below is used.	     class e_decl;	     class a_decl;	     typedef a_decl* a_ref;	     class a_s {	     public:	       a_s();	       void* append(a_ref& item);	     };	     class a_decl {	     public:	       a_decl (e_decl *parent);	       a_s  generic_s;	       a_s  decls;	       e_decl* parent;	     };	     class e_decl {	     public:	       e_decl();	       a_s implementations;	     };	     void foobar(void *);	     a_decl::a_decl(e_decl *parent) {	       parent->implementations.append(this);	     }	   */	  TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */	  put_var_into_stack (targ);	  break;/* #else */	  return error_mark_node;/* #endif */	  	}#endif      /* Fall through.  */    case VAR_DECL:    case CONST_DECL:      if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ)	  && !DECL_ARTIFICIAL (targ))	cp_warning ("address needed to build reference for `%D', which is declared `register'",		    targ);      else if (staticp (targ))	literal_flag = 1;      TREE_ADDRESSABLE (targ) = 1;      put_var_into_stack (targ);      break;    case COMPOUND_EXPR:      {	tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 1),						  LOOKUP_PROTECT, checkconst);	rval = build (COMPOUND_EXPR, type, TREE_OPERAND (targ, 0), real_reference);	TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 1));	return rval;      }    case PREINCREMENT_EXPR:    case PREDECREMENT_EXPR:    case MODIFY_EXPR:    case INIT_EXPR:      {	tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 0),						  LOOKUP_PROTECT, checkconst);	rval = build (COMPOUND_EXPR, type, arg, real_reference);	TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 0));	return rval;      }    case COND_EXPR:      return build (COND_EXPR, type,		    TREE_OPERAND (targ, 0),		    build_up_reference (type, TREE_OPERAND (targ, 1),					LOOKUP_PROTECT, checkconst),		    build_up_reference (type, TREE_OPERAND (targ, 2),					LOOKUP_PROTECT, checkconst));      /* Undo the folding... */    case MIN_EXPR:    case MAX_EXPR:      return build (COND_EXPR, type,		    build (TREE_CODE (targ) == MIN_EXPR ? LT_EXPR : GT_EXPR,			   boolean_type_node, TREE_OPERAND (targ, 0),			   TREE_OPERAND (targ, 1)),		    build_up_reference (type, TREE_OPERAND (targ, 0),					LOOKUP_PROTECT, checkconst),		    build_up_reference (type, TREE_OPERAND (targ, 1),					LOOKUP_PROTECT, checkconst));    case WITH_CLEANUP_EXPR:      return build (WITH_CLEANUP_EXPR, type,		    build_up_reference (type, TREE_OPERAND (targ, 0),					LOOKUP_PROTECT, checkconst),		    0, TREE_OPERAND (targ, 2));    case BIND_EXPR:      arg = TREE_OPERAND (targ, 1);      if (arg == NULL_TREE)	{	  compiler_error ("({ ... }) expression not expanded when needed for reference");	  return error_mark_node;	}      rval = build1 (ADDR_EXPR, type, arg);      TREE_REFERENCE_EXPR (rval) = 1;      return rval;    default:      break;    }  if (TREE_ADDRESSABLE (targ) == 0)    {      tree temp;      if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))	{	  temp = build_cplus_new (argtype, targ, 1);	  if (TREE_CODE (temp) == WITH_CLEANUP_EXPR)	    rval = build (WITH_CLEANUP_EXPR, type,			  build1 (ADDR_EXPR, type, TREE_OPERAND (temp, 0)),			  0, TREE_OPERAND (temp, 2));	  else	    rval = build1 (ADDR_EXPR, type, temp);	  goto done;	}      else	{	  temp = get_temp_name (argtype, 0);	  if (toplevel_bindings_p ())	    {	      /* Give this new temp some rtl and initialize it.  */	      DECL_INITIAL (temp) = targ;	      TREE_STATIC (temp) = 1;	      cp_finish_decl (temp, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);	      /* Do this after declaring it static.  */	      rval = build_unary_op (ADDR_EXPR, temp, 0);	      TREE_TYPE (rval) = type;	      literal_flag = TREE_CONSTANT (rval);	      goto done;	    }	  else	    {	      rval = build_unary_op (ADDR_EXPR, temp, 0);	      if (binfo && !BINFO_OFFSET_ZEROP (binfo))		rval = convert_pointer_to (target_type, rval);	      else		TREE_TYPE (rval) = type;	      temp = build (MODIFY_EXPR, argtype, temp, arg);	      TREE_SIDE_EFFECTS (temp) = 1;	      return build (COMPOUND_EXPR, type, temp, rval);	    }	}    }  else    rval = build1 (ADDR_EXPR, type, arg); done:  if (TYPE_USES_COMPLEX_INHERITANCE (argtype)      || TYPE_USES_COMPLEX_INHERITANCE (target_type))    {      TREE_TYPE (rval) = build_pointer_type (argtype);      if (flags & LOOKUP_PROTECT)	rval = convert_pointer_to (target_type, rval);      else	rval	  = convert_to_pointer_force (build_pointer_type (target_type), rval);      TREE_TYPE (rval) = type;      if (TREE_CODE (rval) == PLUS_EXPR || TREE_CODE (rval) == MINUS_EXPR)	TREE_TYPE (TREE_OPERAND (rval, 0))	  = TREE_TYPE (TREE_OPERAND (rval, 1)) = type;    }  TREE_CONSTANT (rval) = literal_flag;  return rval;}/* For C++: Only need to do one-level references, but cannot   get tripped up on signed/unsigned differences.   DECL is either NULL_TREE or the _DECL node for a reference that is being   initialized.  It can be error_mark_node if we don't know the _DECL but   we know it's an initialization.  */treeconvert_to_reference (reftype, expr, convtype, flags, decl)     tree reftype, expr;     int convtype, flags;     tree decl;{  register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));  register tree intype = TREE_TYPE (expr);  tree rval = NULL_TREE;  tree rval_as_conversion = NULL_TREE;  int i;  if (TREE_CODE (intype) == REFERENCE_TYPE)    my_friendly_abort (364);  intype = TYPE_MAIN_VARIANT (intype);  i = comp_target_types (type, intype, 0);  if (i <= 0 && (convtype & CONV_IMPLICIT) && IS_AGGR_TYPE (intype)      && ! (flags & LOOKUP_NO_CONVERSION))    {      /* Look for a user-defined conversion to lvalue that we can use.  */      rval_as_conversion = build_type_conversion (CONVERT_EXPR, type, expr, 1);      if (rval_as_conversion && rval_as_conversion != error_mark_node	  && real_lvalue_p (rval_as_conversion))	{	  expr = rval_as_conversion;	  rval_as_conversion = NULL_TREE;	  intype = type;	  i = 1;	}    }  if (((convtype & CONV_STATIC) && i == -1)      || ((convtype & CONV_IMPLICIT) && i == 1))    {      if (flags & LOOKUP_COMPLAIN)	{	  tree ttl = TREE_TYPE (reftype);	  tree ttr;	  	  {	    int r = TREE_READONLY (expr);	    int v = TREE_THIS_VOLATILE (expr);	    ttr = cp_build_type_variant (TREE_TYPE (expr), r, v);	  }	  if (! real_lvalue_p (expr) &&	      (decl == NULL_TREE || ! TYPE_READONLY (ttl)))	    {	      if (decl)		/* Ensure semantics of [dcl.init.ref] */		cp_pedwarn ("initialization of non-const `%T' from rvalue `%T'",			    reftype, intype);	      else		cp_pedwarn ("conversion to `%T' from rvalue `%T'",			    reftype, intype);	    }	  else if (! (convtype & CONV_CONST))	    {	      if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))		cp_pedwarn ("conversion from `%T' to `%T' discards const",			    ttr, reftype);	      else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))		cp_pedwarn ("conversion from `%T' to `%T' discards volatile",			    ttr, reftype);	    }	}      return build_up_reference (reftype, expr, flags,				 ! (convtype & CONV_CONST));    }  else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))    {      /* When casting an lvalue to a reference type, just convert into	 a pointer to the new type and deference it.  This is allowed	 by San Diego WP section 5.2.9 paragraph 12, though perhaps it	 should be done directly (jason).  (int &)ri ---> *(int*)&ri */      /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they         meant.  */      if (TREE_CODE (intype) == POINTER_TYPE	  && (comptypes (TREE_TYPE (intype), type, -1)))	cp_warning ("casting `%T' to `%T' does not dereference pointer",		    intype, reftype);	        rval = build_unary_op (ADDR_EXPR, expr, 0);      if (rval != error_mark_node)	rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval, 0);      if (rval != error_mark_node)	rval = build1 (NOP_EXPR, reftype, rval);    }  else if (decl)    {      tree rval_as_ctor = NULL_TREE;            if (rval_as_conversion)	{	  if (rval_as_conversion == error_mark_node)	    {	      cp_error ("conversion from `%T' to `%T' is ambiguous",			intype, reftype);	      return error_mark_node;	    }	  rval_as_conversion = build_up_reference (reftype, rval_as_conversion,						   flags, 1);	}            /* Definitely need to go through a constructor here.  */      if (TYPE_HAS_CONSTRUCTOR (type)	  && ! CLASSTYPE_ABSTRACT_VIRTUALS (type)	  && (rval = build_method_call	      (NULL_TREE, constructor_name_full (type),	       build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),	       LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY	       | LOOKUP_ONLYCONVERTING)))	{	  tree init;	  if (toplevel_bindings_p ())	    {	      extern tree static_aggregates;	      tree t = get_temp_name (type, toplevel_bindings_p ());	      init = build_method_call (t, constructor_name_full (type),					build_tree_list (NULL_TREE, expr),					TYPE_BINFO (type),					LOOKUP_NORMAL|LOOKUP_NO_CONVERSION					| LOOKUP_ONLYCONVERTING);	      if (init == error_mark_node)		return error_mark_node;	      make_decl_rtl (t, NULL_PTR, 1);	      static_aggregates = perm_tree_cons (expr, t, static_aggregates);	      rval = build_unary_op (ADDR_EXPR, t, 0);	    }	  else	    {	      init = build_method_call (NULL_TREE, constructor_name_full (type),					build_tree_list (NULL_TREE, expr),					TYPE_BINFO (type),					LOOKUP_NORMAL|LOOKUP_NO_CONVERSION					|LOOKUP_ONLYCONVERTING);	      if (init == error_mark_node)		return error_mark_node;	      rval = build_cplus_new (type, init, 1);	      rval = build_up_reference (reftype, rval, flags, 1);	    }	  rval_as_ctor = rval;	}      if (rval_as_ctor && rval_as_conversion)	{	  cp_error ("ambiguous conversion from `%T' to `%T'; both user-defined conversion and constructor apply",		    intype, reftype);	  return error_mark_node;	}      else if (rval_as_ctor)	rval = rval_as_ctor;      else if (rval_as_conversion)	rval = rval_as_conversion;      else if (! IS_AGGR_TYPE (type) && ! IS_AGGR_TYPE (intype))	{	  rval = convert (type, expr);	  if (rval == error_mark_node)	    return error_mark_node;	  	  rval = build_up_reference (reftype, rval, flags, 1);	}      if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))	cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",		    reftype, intype);    }  if (rval)    {      /* If we found a way to convert earlier, then use it. */      return rval;    }  my_friendly_assert (TREE_CODE (intype) != OFFSET_TYPE, 189);  if (flags & LOOKUP_COMPLAIN)    cp_error ("cannot convert type `%T' to type `%T'", intype, reftype);  if (flags & LOOKUP_SPECULATIVELY)    return NULL_TREE;  return error_mark_node;}/* We are using a reference VAL for its value. Bash that reference all the   way down to its lowest form. */treeconvert_from_reference (val)     tree val;{  tree type = TREE_TYPE (val);  if (TREE_CODE (type) == OFFSET_TYPE)    type = TREE_TYPE (type);  if (TREE_CODE (type) == REFERENCE_TYPE)    return build_indirect_ref (val, NULL_PTR);  return val;}/* See if there is a constructor of type TYPE which will convert   EXPR.  The reference manual seems to suggest (8.5.6) that we need   not worry about finding constructors for base classes, then converting   to the derived class.   MSGP is a pointer to a message that would be an appropriate error   string.  If MSGP is NULL, then we are not interested in reporting   errors.  */treeconvert_to_aggr (type, expr, msgp, protect)     tree type, expr;     char **msgp;     int protect;{  tree basetype = type;  tree name = TYPE_IDENTIFIER (basetype);  tree function, fndecl, fntype, parmtypes, parmlist, result;  tree method_name;  enum access_type access;  int can_be_private, can_be_protected;  if (! TYPE_HAS_CONSTRUCTOR (basetype))    {      if (msgp)	*msgp = "type `%s' does not have a constructor";      return error_mark_node;    }  access = access_public;  can_be_private = 0;  can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;  parmlist = build_tree_list (NULL_TREE, expr);  parmtypes = tree_cons (NULL_TREE, TREE_TYPE (expr), void_list_node);  if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))    {      parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes);      parmlist = tree_cons (NULL_TREE, integer_one_node, parmlist);    }

⌨️ 快捷键说明

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