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

📄 call.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
   purposes of reference binding.  For lvalue binding, either pass a   reference type to FROM or an lvalue expression to EXPR.   Currently does not distinguish in the generated trees between binding to   an lvalue and a temporary.  Should it?  */static treereference_binding (rto, rfrom, expr, flags)     tree rto, rfrom, expr;     int flags;{  tree conv;  int lvalue = 1;  tree to = TREE_TYPE (rto);  tree from = rfrom;  int related;  if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))    {      expr = instantiate_type (to, expr, 0);      if (expr == error_mark_node)	return NULL_TREE;      from = TREE_TYPE (expr);    }  if (TREE_CODE (from) == REFERENCE_TYPE)    from = TREE_TYPE (from);  else if (! expr || ! real_lvalue_p (expr))    lvalue = 0;  related = (same_type_p (TYPE_MAIN_VARIANT (to),			  TYPE_MAIN_VARIANT (from))	     || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)		 && DERIVED_FROM_P (to, from)));  if (lvalue && related && at_least_as_qualified_p (to, from))    {      conv = build1 (IDENTITY_CONV, from, expr);      if (same_type_p (TYPE_MAIN_VARIANT (to),		       TYPE_MAIN_VARIANT (from)))	conv = build_conv (REF_BIND, rto, conv);      else	{	  conv = build_conv (REF_BIND, rto, conv);	  ICS_STD_RANK (conv) = STD_RANK;	}    }  else    conv = NULL_TREE;  if (! conv)    {      conv = standard_conversion (to, rfrom, expr);      if (conv)	{	  conv = build_conv (REF_BIND, rto, conv);	  /* Bind directly to a base subobject of a class rvalue.  Do it             after building the conversion for proper handling of ICS_RANK.  */	  if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV)	    TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0);	}      if (conv	  && ((! (CP_TYPE_CONST_NON_VOLATILE_P (to)		  && (flags & LOOKUP_NO_TEMP_BIND) == 0))	      /* If T1 is reference-related to T2, cv1 must be the same		 cv-qualification as, or greater cv-qualification than,		 cv2; otherwise, the program is ill-formed.  */	      || (related && !at_least_as_qualified_p (to, from))))	ICS_BAD_FLAG (conv) = 1;    }  return conv;}/* Returns the implicit conversion sequence (see [over.ics]) from type FROM   to type TO.  The optional expression EXPR may affect the conversion.   FLAGS are the usual overloading flags.  Only LOOKUP_NO_CONVERSION is   significant.  */static treeimplicit_conversion (to, from, expr, flags)     tree to, from, expr;     int flags;{  tree conv;  struct z_candidate *cand;  if (TREE_CODE (to) == REFERENCE_TYPE)    conv = reference_binding (to, from, expr, flags);  else    conv = standard_conversion (to, from, expr);  if (conv)    ;  else if (expr != NULL_TREE	   && (IS_AGGR_TYPE (non_reference (from))	       || IS_AGGR_TYPE (non_reference (to)))	   && (flags & LOOKUP_NO_CONVERSION) == 0)    {      cand = build_user_type_conversion_1	(to, expr, LOOKUP_ONLYCONVERTING);      if (cand)	conv = cand->second_conv;      if ((! conv || ICS_BAD_FLAG (conv))	  && TREE_CODE (to) == REFERENCE_TYPE	  && (flags & LOOKUP_NO_TEMP_BIND) == 0)	{	  cand = build_user_type_conversion_1	    (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);	  if (cand)	    {	      if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to)))		ICS_BAD_FLAG (cand->second_conv) = 1;	      if (!conv || (ICS_BAD_FLAG (conv)			    > ICS_BAD_FLAG (cand->second_conv)))		conv = build_conv (REF_BIND, to, cand->second_conv);	    }	}    }  return conv;}/* Add a new entry to the list of candidates.  Used by the add_*_candidate   functions.  */static struct z_candidate *add_candidate (candidates, fn, convs, viable)     struct z_candidate *candidates;     tree fn, convs;     int viable;{  struct z_candidate *cand    = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate));  cand->fn = fn;  cand->convs = convs;  cand->second_conv = NULL_TREE;  cand->viable = viable;  cand->basetype_path = NULL_TREE;  cand->template = NULL_TREE;  cand->warnings = NULL_TREE;  cand->next = candidates;  return cand;}/* Create an overload candidate for the function or method FN called with   the argument list ARGLIST and add it to CANDIDATES.  FLAGS is passed on   to implicit_conversion.  */static struct z_candidate *add_function_candidate (candidates, fn, arglist, flags)     struct z_candidate *candidates;     tree fn, arglist;     int flags;{  tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));  int i, len;  tree convs;  tree parmnode, argnode;  int viable = 1;  /* The `this', `in_chrg', and `vlist' arguments to constructors are     not considered in overload resolution.  */  if (DECL_CONSTRUCTOR_P (fn))    {      parmlist = TREE_CHAIN (parmlist);      arglist = TREE_CHAIN (arglist);      if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))	{	  parmlist = TREE_CHAIN (parmlist);	  arglist = TREE_CHAIN (arglist);	}      if ((flags & LOOKUP_HAS_VLIST)	  && DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))	{	  parmlist = TREE_CHAIN (parmlist);	  arglist = TREE_CHAIN (arglist);	}      else if (!(flags & LOOKUP_HAS_VLIST)	       && !DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))	/* Ok */;      else	{	  /* The ctor expects a vlist and the arguments don't have	     one, or vice versa, so fn is not even a candidate, since	     the corresponding ctor would be the candidate.  */	  return candidates;	}    }  len = list_length (arglist);  convs = make_scratch_vec (len);  /* 13.3.2 - Viable functions [over.match.viable]     First, to be a viable function, a candidate function shall have enough     parameters to agree in number with the arguments in the list.     We need to check this first; otherwise, checking the ICSes might cause     us to produce an ill-formed template instantiation.  */  parmnode = parmlist;  for (i = 0; i < len; ++i)    {      if (parmnode == NULL_TREE || parmnode == void_list_node)	break;      parmnode = TREE_CHAIN (parmnode);    }  if (i < len && parmnode)    viable = 0;  /* Make sure there are default args for the rest of the parms.  */  else for (; parmnode && parmnode != void_list_node;	    parmnode = TREE_CHAIN (parmnode))    if (! TREE_PURPOSE (parmnode))      {	viable = 0;	break;      }  if (! viable)    goto out;  /* Second, for F to be a viable function, there shall exist for each     argument an implicit conversion sequence that converts that argument     to the corresponding parameter of F.  */  parmnode = parmlist;  argnode = arglist;  for (i = 0; i < len; ++i)    {      tree arg = TREE_VALUE (argnode);      tree argtype = lvalue_type (arg);      tree t;      if (parmnode == void_list_node)	break;      if (parmnode)	{	  tree parmtype = TREE_VALUE (parmnode);	  /* [over.match.funcs] For conversion functions, the function is	     considered to be a member of the class of the implicit object	     argument for the purpose of defining the type of the implicit	     object parameter.	     Since build_over_call ignores the ICS for the `this' parameter,	     we can just change the parm type.  */	  if (DECL_CONV_FN_P (fn) && i == 0)	    {	      parmtype		= build_qualified_type (TREE_TYPE (argtype),					TYPE_QUALS (TREE_TYPE (parmtype)));	      parmtype = build_pointer_type (parmtype);	    }	  t = implicit_conversion (parmtype, argtype, arg, flags);	}      else	{	  t = build1 (IDENTITY_CONV, argtype, arg);	  ICS_ELLIPSIS_FLAG (t) = 1;	}      if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE	  && ! DECL_CONSTRUCTOR_P (fn))	ICS_THIS_FLAG (t) = 1;      TREE_VEC_ELT (convs, i) = t;      if (! t)	{	  viable = 0;	  break;	}      if (ICS_BAD_FLAG (t))	viable = -1;      if (parmnode)	parmnode = TREE_CHAIN (parmnode);      argnode = TREE_CHAIN (argnode);    } out:  return add_candidate (candidates, fn, convs, viable);}/* Create an overload candidate for the conversion function FN which will   be invoked for expression OBJ, producing a pointer-to-function which   will in turn be called with the argument list ARGLIST, and add it to   CANDIDATES.  FLAGS is passed on to implicit_conversion.   Actually, we don't really care about FN; we care about the type it   converts to.  There may be multiple conversion functions that will   convert to that type, and we rely on build_user_type_conversion_1 to   choose the best one; so when we create our candidate, we record the type   instead of the function.  */static struct z_candidate *add_conv_candidate (candidates, fn, obj, arglist)     struct z_candidate *candidates;     tree fn, obj, arglist;{  tree totype = TREE_TYPE (TREE_TYPE (fn));  tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (totype));  int i, len = list_length (arglist) + 1;  tree convs = make_scratch_vec (len);  tree parmnode = parmlist;  tree argnode = arglist;  int viable = 1;  int flags = LOOKUP_NORMAL;  /* Don't bother looking up the same type twice.  */  if (candidates && candidates->fn == totype)    return candidates;  for (i = 0; i < len; ++i)    {      tree arg = i == 0 ? obj : TREE_VALUE (argnode);      tree argtype = lvalue_type (arg);      tree t;      if (i == 0)	t = implicit_conversion (totype, argtype, arg, flags);      else if (parmnode == void_list_node)	break;      else if (parmnode)	t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags);      else	{	  t = build1 (IDENTITY_CONV, argtype, arg);	  ICS_ELLIPSIS_FLAG (t) = 1;	}      TREE_VEC_ELT (convs, i) = t;      if (! t)	break;      if (ICS_BAD_FLAG (t))	viable = -1;      if (i == 0)	continue;      if (parmnode)	parmnode = TREE_CHAIN (parmnode);      argnode = TREE_CHAIN (argnode);    }  if (i < len)    viable = 0;  for (; parmnode && parmnode != void_list_node;       parmnode = TREE_CHAIN (parmnode))    if (! TREE_PURPOSE (parmnode))      {	viable = 0;	break;      }  return add_candidate (candidates, totype, convs, viable);}static struct z_candidate *build_builtin_candidate (candidates, fnname, type1, type2,			 args, argtypes, flags)     struct z_candidate *candidates;     tree fnname, type1, type2, *args, *argtypes;     int flags;{  tree t, convs;  int viable = 1, i;  tree types[2];  types[0] = type1;  types[1] = type2;  convs = make_scratch_vec (args[2] ? 3 : (args[1] ? 2 : 1));  for (i = 0; i < 2; ++i)    {      if (! args[i])	break;      t = implicit_conversion (types[i], argtypes[i], args[i], flags);      if (! t)	{	  viable = 0;	  /* We need something for printing the candidate.  */	  t = build1 (IDENTITY_CONV, types[i], NULL_TREE);	}      else if (ICS_BAD_FLAG (t))	viable = 0;      TREE_VEC_ELT (convs, i) = t;    }  /* For COND_EXPR we rearranged the arguments; undo that now.  */  if (args[2])    {      TREE_VEC_ELT (convs, 2) = TREE_VEC_ELT (convs, 1);      TREE_VEC_ELT (convs, 1) = TREE_VEC_ELT (convs, 0);      t = implicit_conversion (boolean_type_node, argtypes[2], args[2], flags);      if (t)	TREE_VEC_ELT (convs, 0) = t;      else	viable = 0;    }        return add_candidate (candidates, fnname, convs, viable);}static intis_complete (t)     tree t;{  return TYPE_SIZE (complete_type (t)) != NULL_TREE;}/* Create any builtin operator overload candidates for the operator in   question given the converted operand types TYPE1 and TYPE2.  The other   args are passed through from add_builtin_candidates to   build_builtin_candidate.  */static struct z_candidate *add_builtin_candidate (candidates, code, code2, fnname, type1, type2,		       args, argtypes, flags)     struct z_candidate *candidates;     enum tree_code code, code2;     tree fnname, type1, type2, *args, *argtypes;     int flags;{  switch (code)    {    case POSTINCREMENT_EXPR:    case POSTDECREMENT_EXPR:      args[1] = integer_zero_node;      type2 = integer_type_node;      break;    default:      break;    }  switch (code)    {

⌨️ 快捷键说明

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