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

📄 call.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
     functions.  */  if (TREE_CODE (type) == METHOD_TYPE)    {      tree addr;      type = build_pointer_type (type);      if (mark_addressable (function) == 0)	return error_mark_node;      addr = build1 (ADDR_EXPR, type, function);      /* Address of a static or external variable or function counts	 as a constant */      if (staticp (function))	TREE_CONSTANT (addr) = 1;      function = addr;    }  else    function = default_conversion (function);  return function;}/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or   POINTER_TYPE to those.  Note, pointer to member function types   (TYPE_PTRMEMFUNC_P) must be handled by our callers.  */treebuild_call (function, result_type, parms)     tree function, result_type, parms;{  int is_constructor = 0;  tree tmp;  tree decl;  function = build_addr_func (function);  if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))    {      sorry ("unable to call pointer to member function here");      return error_mark_node;    }  if (TREE_CODE (function) == ADDR_EXPR      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)    decl = TREE_OPERAND (function, 0);  else    decl = NULL_TREE;  if (decl && DECL_CONSTRUCTOR_P (decl))    is_constructor = 1;  if (decl)    my_friendly_assert (TREE_USED (decl), 990125);  /* Don't pass empty class objects by value.  This is useful     for tags in STL, which are used to control overload resolution.     We don't need to handle other cases of copying empty classes.  */  if (! decl || ! DECL_BUILT_IN (decl))    for (tmp = parms; tmp; tmp = TREE_CHAIN (tmp))      if (is_empty_class (TREE_TYPE (TREE_VALUE (tmp)))	  && ! TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (tmp))))	{	  tree t = make_node (RTL_EXPR);	  TREE_TYPE (t) = TREE_TYPE (TREE_VALUE (tmp));	  RTL_EXPR_RTL (t) = const0_rtx;	  RTL_EXPR_SEQUENCE (t) = NULL_RTX;	  TREE_VALUE (tmp) = build (COMPOUND_EXPR, TREE_TYPE (t),				    TREE_VALUE (tmp), t);	}  function = build_nt (CALL_EXPR, function, parms, NULL_TREE);  TREE_HAS_CONSTRUCTOR (function) = is_constructor;  TREE_TYPE (function) = result_type;  TREE_SIDE_EFFECTS (function) = 1;    return function;}/* Build something of the form ptr->method (args)   or object.method (args).  This can also build   calls to constructors, and find friends.   Member functions always take their class variable   as a pointer.   INSTANCE is a class instance.   NAME is the name of the method desired, usually an IDENTIFIER_NODE.   PARMS help to figure out what that NAME really refers to.   BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE   down to the real instance type to use for access checking.  We need this   information to get protected accesses correct.  This parameter is used   by build_member_call.   FLAGS is the logical disjunction of zero or more LOOKUP_   flags.  See cp-tree.h for more info.   If this is all OK, calls build_function_call with the resolved   member function.   This function must also handle being called to perform   initialization, promotion/coercion of arguments, and   instantiation of default parameters.   Note that NAME may refer to an instance variable name.  If   `operator()()' is defined for the type of that field, then we return   that result.  */treebuild_method_call (instance, name, parms, basetype_path, flags)     tree instance, name, parms, basetype_path;     int flags;{  tree basetype, instance_ptr;#ifdef GATHER_STATISTICS  n_build_method_call++;#endif  if (instance == error_mark_node      || name == error_mark_node      || parms == error_mark_node      || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))    return error_mark_node;  if (processing_template_decl)    {      /* We need to process template parm names here so that tsubst catches	 them properly.  Other type names can wait.  */      if (TREE_CODE (name) == BIT_NOT_EXPR)	{	  tree type = NULL_TREE;	  if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)	    type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);	  else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL)	    type = TREE_TYPE (TREE_OPERAND (name, 0));	  if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)	    name = build_min_nt (BIT_NOT_EXPR, type);	}      return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);    }  if (TREE_CODE (name) == BIT_NOT_EXPR)    {      if (parms)	error ("destructors take no parameters");      basetype = TREE_TYPE (instance);      if (TREE_CODE (basetype) == REFERENCE_TYPE)	basetype = TREE_TYPE (basetype);      if (! check_dtor_name (basetype, name))	cp_error	  ("destructor name `~%T' does not match type `%T' of expression",	   TREE_OPERAND (name, 0), basetype);      if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype)))	return cp_convert (void_type_node, instance);      instance = default_conversion (instance);      instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);      return build_delete (build_pointer_type (basetype),			   instance_ptr, integer_two_node,			   LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);    }  return build_new_method_call (instance, name, parms, basetype_path, flags);}/* New overloading code.  */struct z_candidate {  tree fn;  tree convs;  tree second_conv;  int viable;  tree basetype_path;  tree template;  tree warnings;  struct z_candidate *next;};#define IDENTITY_RANK 0#define EXACT_RANK 1#define PROMO_RANK 2#define STD_RANK 3#define PBOOL_RANK 4#define USER_RANK 5#define ELLIPSIS_RANK 6#define BAD_RANK 7#define ICS_RANK(NODE)				\  (ICS_BAD_FLAG (NODE) ? BAD_RANK   \   : ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK	\   : ICS_USER_FLAG (NODE) ? USER_RANK		\   : ICS_STD_RANK (NODE))#define ICS_STD_RANK(NODE) TREE_COMPLEXITY (NODE)#define ICS_USER_FLAG(NODE) TREE_LANG_FLAG_0 (NODE)#define ICS_ELLIPSIS_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)#define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE)#define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (NODE)#define USER_CONV_CAND(NODE) \  ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1)))#define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)intnull_ptr_cst_p (t)     tree t;{  if (t == null_node      || (integer_zerop (t) && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE))    return 1;  return 0;}static treebuild_conv (code, type, from)     enum tree_code code;     tree type, from;{  tree t = build1 (code, type, from);  int rank = ICS_STD_RANK (from);  switch (code)    {    case PTR_CONV:    case PMEM_CONV:    case BASE_CONV:    case STD_CONV:      if (rank < STD_RANK)	rank = STD_RANK;      break;    case QUAL_CONV:      if (rank < EXACT_RANK)	rank = EXACT_RANK;    default:      break;    }  ICS_STD_RANK (t) = rank;  ICS_USER_FLAG (t) = ICS_USER_FLAG (from);  ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);  return t;}static treenon_reference (t)     tree t;{  if (TREE_CODE (t) == REFERENCE_TYPE)    t = TREE_TYPE (t);  return t;}static treestrip_top_quals (t)     tree t;{  if (TREE_CODE (t) == ARRAY_TYPE)    return t;  return TYPE_MAIN_VARIANT (t);}/* Returns the standard conversion path (see [conv]) from type FROM to type   TO, if any.  For proper handling of null pointer constants, you must   also pass the expression EXPR to convert from.  */static treestandard_conversion (to, from, expr)     tree to, from, expr;{  enum tree_code fcode, tcode;  tree conv;  int fromref = 0;  if (TREE_CODE (to) == REFERENCE_TYPE)    to = TREE_TYPE (to);  if (TREE_CODE (from) == REFERENCE_TYPE)    {      fromref = 1;      from = TREE_TYPE (from);    }  to = strip_top_quals (to);  from = strip_top_quals (from);  if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))      && expr && type_unknown_p (expr))    {      expr = instantiate_type (to, expr, 0);      if (expr == error_mark_node)	return NULL_TREE;      from = TREE_TYPE (expr);    }  fcode = TREE_CODE (from);  tcode = TREE_CODE (to);  conv = build1 (IDENTITY_CONV, from, expr);  if (fcode == FUNCTION_TYPE)    {      from = build_pointer_type (from);      fcode = TREE_CODE (from);      conv = build_conv (LVALUE_CONV, from, conv);    }  else if (fcode == ARRAY_TYPE)    {      from = build_pointer_type (TREE_TYPE (from));      fcode = TREE_CODE (from);      conv = build_conv (LVALUE_CONV, from, conv);    }  else if (fromref || (expr && real_lvalue_p (expr)))    conv = build_conv (RVALUE_CONV, from, conv);  if (from == to)    return conv;  if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))      && expr && null_ptr_cst_p (expr))    {      conv = build_conv (STD_CONV, to, conv);    }  else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)    {      enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));      enum tree_code utcode = TREE_CODE (TREE_TYPE (to));      if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)),		       TYPE_MAIN_VARIANT (TREE_TYPE (to))))	;      else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE	       && ufcode != FUNCTION_TYPE)	{	  from = build_pointer_type	    (cp_build_qualified_type (void_type_node, 				      CP_TYPE_QUALS (TREE_TYPE (from))));	  conv = build_conv (PTR_CONV, from, conv);	}      else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)	{	  tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));	  tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));	  if (DERIVED_FROM_P (fbase, tbase)	      && (same_type_p 		  (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))),		   TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))))))	    {	      from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));	      from = build_pointer_type (from);	      conv = build_conv (PMEM_CONV, from, conv);	    }	}      else if (IS_AGGR_TYPE (TREE_TYPE (from))	       && IS_AGGR_TYPE (TREE_TYPE (to)))	{	  if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))	    {	      from = 		cp_build_qualified_type (TREE_TYPE (to),					 CP_TYPE_QUALS (TREE_TYPE (from)));	      from = build_pointer_type (from);	      conv = build_conv (PTR_CONV, from, conv);	    }	}      if (same_type_p (from, to))	/* OK */;      else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))	conv = build_conv (QUAL_CONV, to, conv);      else if (expr && string_conv_p (to, expr, 0))	/* converting from string constant to char *.  */	conv = build_conv (QUAL_CONV, to, conv);      else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from)))	{	  conv = build_conv (PTR_CONV, to, conv);	  ICS_BAD_FLAG (conv) = 1;	}      else	return 0;      from = to;    }  else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))    {      tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));      tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));      tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));      tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));      if (! DERIVED_FROM_P (fbase, tbase)	  || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))	  || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),			  TREE_CHAIN (TYPE_ARG_TYPES (tofn)))	  || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))	return 0;      from = cp_build_qualified_type (tbase, CP_TYPE_QUALS (fbase));      from = build_cplus_method_type (from, TREE_TYPE (fromfn),				      TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));      from = build_ptrmemfunc_type (build_pointer_type (from));      conv = build_conv (PMEM_CONV, from, conv);    }  else if (tcode == BOOLEAN_TYPE)    {      if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE	     || fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from)))	return 0;      conv = build_conv (STD_CONV, to, conv);      if (fcode == POINTER_TYPE	  || (TYPE_PTRMEMFUNC_P (from) && ICS_STD_RANK (conv) < PBOOL_RANK))	ICS_STD_RANK (conv) = PBOOL_RANK;    }  /* We don't check for ENUMERAL_TYPE here because there are no standard     conversions to enum type.  */  else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE	   || tcode == REAL_TYPE)    {      if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))	return 0;      conv = build_conv (STD_CONV, to, conv);      /* Give this a better rank if it's a promotion.  */      if (to == type_promotes_to (from)	  && ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK)	ICS_STD_RANK (conv) = PROMO_RANK;    }  else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)	   && DERIVED_FROM_P (to, from))    {      if (TREE_CODE (conv) == RVALUE_CONV)	conv = TREE_OPERAND (conv, 0);      conv = build_conv (BASE_CONV, to, conv);    }  else    return 0;  return conv;}/* Returns the conversion path from type FROM to reference type TO for

⌨️ 快捷键说明

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