FreeBSD/contrib/gcc/cp/class.c
/* This function will instantiate the type of the expression given in
   RHS to match the type of LHSTYPE.  If errors exist, then return
   error_mark_node. FLAGS is a bit mask.  If TF_ERROR is set, then
   we complain on errors.  If we are not complaining, never modify rhs,
   as overload resolution wants to try many possible instantiations, in
   the hope that at least one will work.

   For non-recursive calls, LHSTYPE should be a function, pointer to
   function, or a pointer to member function.  */
This function will instantiate the type of the expression given in
RHS to match the type of LHSTYPE.  If errors exist, then return
error_mark_node. FLAGS is a bit mask.  If TF_ERROR is set, then
we complain on errors.  If we are not complaining, never modify rhs,
as overload resolution wants to try many possible instantiations, in
the hope that at least one will work.

For non-recursive calls, LHSTYPE should be a function, pointer to
function, or a pointer to member function.
This function will instantiate the type of the expression given in RHS to match the type of LHSTYPE . If errors exist then return error_mark_node . FLAGS is a bit mask . If TF_ERROR is set then we complain on errors . If we are not complaining never modify rhs as overload resolution wants to try many possible instantiations in the hope that at least one will work . For non - recursive calls LHSTYPE should be a function pointer to function or a pointer to member function .
tree
instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
{
  tsubst_flags_t flags_in = flags;
  tree access_path = NULL_TREE;
  flags &= ~tf_ptrmem_ok;
  if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
    {
      if (flags & tf_error)
	error ("not enough type information");
      return error_mark_node;
    }
  if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
    {
      if (same_type_p (lhstype, TREE_TYPE (rhs)))
	return rhs;
      if (flag_ms_extensions
	  && TYPE_PTRMEMFUNC_P (lhstype)
	  && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
	;
      else
	{
	  if (flags & tf_error)
	    error ("argument of type %qT does not match %qT",
		   TREE_TYPE (rhs), lhstype);
	  return error_mark_node;
	}
    }
  if (TREE_CODE (rhs) == BASELINK)
    {
      access_path = BASELINK_ACCESS_BINFO (rhs);
      rhs = BASELINK_FUNCTIONS (rhs);
    }
  if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
    {
      if (flags & tf_error)
	error ("not enough type information");
      return error_mark_node;
    }
  gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
	      || TREE_CODE (rhs) == COMPONENT_REF
	      || TREE_CODE (rhs) == COMPOUND_EXPR
	      || really_overloaded_fn (rhs));
  if (TREE_CODE (rhs) != OVERLOAD)
    rhs = copy_node (rhs);
  switch (TREE_CODE (rhs))
    {
    case COMPONENT_REF:
      {
	tree member = TREE_OPERAND (rhs, 1);
	member = instantiate_type (lhstype, member, flags);
	if (member != error_mark_node
	    && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
	  return build2 (COMPOUND_EXPR, TREE_TYPE (member),
			 TREE_OPERAND (rhs, 0), member);
	return member;
      }
    case OFFSET_REF:
      rhs = TREE_OPERAND (rhs, 1);
      if (BASELINK_P (rhs))
	return instantiate_type (lhstype, rhs, flags_in);
      gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);
    case TEMPLATE_ID_EXPR:
      {
	tree fns = TREE_OPERAND (rhs, 0);
	tree args = TREE_OPERAND (rhs, 1);
	return
	  resolve_address_of_overloaded_function (lhstype, fns, flags_in,
						  true,
						  args, access_path);
      }
    case OVERLOAD:
    case FUNCTION_DECL:
      return
	resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
						false,
						NULL_TREE,
						access_path);
    case COMPOUND_EXPR:
      TREE_OPERAND (rhs, 0)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
      if (TREE_OPERAND (rhs, 0) == error_mark_node)
	return error_mark_node;
      TREE_OPERAND (rhs, 1)
	= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
      if (TREE_OPERAND (rhs, 1) == error_mark_node)
	return error_mark_node;
      TREE_TYPE (rhs) = lhstype;
      return rhs;
    case ADDR_EXPR:
    {
      if (PTRMEM_OK_P (rhs))
	flags |= tf_ptrmem_ok;
      return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
    }
    case ERROR_MARK:
      return error_mark_node;
    default:
      gcc_unreachable ();
    }
  return error_mark_node;
}
tree instantiate_type ( tree lhstype , tree rhs , tsubst_flags_t flags ) { tsubst_flags_t flags_in = flags ; tree access_path = NULL_TREE ; flags &= ~ tf_ptrmem_ok ; if ( TREE_CODE ( lhstype ) == UNKNOWN_TYPE ) { if ( flags & tf_error ) error ( " " ) ; return error_mark_node ; } if ( TREE_TYPE ( rhs ) != NULL_TREE && ! ( type_unknown_p ( rhs ) ) ) { if ( same_type_p ( lhstype , TREE_TYPE ( rhs ) ) ) return rhs ; if ( flag_ms_extensions && TYPE_PTRMEMFUNC_P ( lhstype ) && ! TYPE_PTRMEMFUNC_P ( TREE_TYPE ( rhs ) ) ) ; else { if ( flags & tf_error ) error ( " " , TREE_TYPE ( rhs ) , lhstype ) ; return error_mark_node ; } } if ( TREE_CODE ( rhs ) == BASELINK ) { access_path = BASELINK_ACCESS_BINFO ( rhs ) ; rhs = BASELINK_FUNCTIONS ( rhs ) ; } if ( TREE_CODE ( rhs ) == NON_DEPENDENT_EXPR ) { if ( flags & tf_error ) error ( " " ) ; return error_mark_node ; } gcc_assert ( TREE_CODE ( rhs ) == ADDR_EXPR || TREE_CODE ( rhs ) == COMPONENT_REF || TREE_CODE ( rhs ) == COMPOUND_EXPR || really_overloaded_fn ( rhs ) ) ; if ( TREE_CODE ( rhs ) != OVERLOAD ) rhs = copy_node ( rhs ) ; switch ( TREE_CODE ( rhs ) ) { case COMPONENT_REF : { tree member = TREE_OPERAND ( rhs , 1 ) ; member = instantiate_type ( lhstype , member , flags ) ; if ( member != error_mark_node && TREE_SIDE_EFFECTS ( TREE_OPERAND ( rhs , 0 ) ) ) return build2 ( COMPOUND_EXPR , TREE_TYPE ( member ) , TREE_OPERAND ( rhs , 0 ) , member ) ; return member ; } case OFFSET_REF : rhs = TREE_OPERAND ( rhs , 1 ) ; if ( BASELINK_P ( rhs ) ) return instantiate_type ( lhstype , rhs , flags_in ) ; gcc_assert ( TREE_CODE ( rhs ) == TEMPLATE_ID_EXPR ) ; case TEMPLATE_ID_EXPR : { tree fns = TREE_OPERAND ( rhs , 0 ) ; tree args = TREE_OPERAND ( rhs , 1 ) ; return resolve_address_of_overloaded_function ( lhstype , fns , flags_in , true , args , access_path ) ; } case OVERLOAD : case FUNCTION_DECL : return resolve_address_of_overloaded_function ( lhstype , rhs , flags_in , false , NULL_TREE , access_path ) ; case COMPOUND_EXPR : TREE_OPERAND ( rhs , 0 ) = instantiate_type ( lhstype , TREE_OPERAND ( rhs , 0 ) , flags ) ; if ( TREE_OPERAND ( rhs , 0 ) == error_mark_node ) return error_mark_node ; TREE_OPERAND ( rhs , 1 ) = instantiate_type ( lhstype , TREE_OPERAND ( rhs , 1 ) , flags ) ; if ( TREE_OPERAND ( rhs , 1 ) == error_mark_node ) return error_mark_node ; TREE_TYPE ( rhs ) = lhstype ; return rhs ; case ADDR_EXPR : { if ( PTRMEM_OK_P ( rhs ) ) flags |= tf_ptrmem_ok ; return instantiate_type ( lhstype , TREE_OPERAND ( rhs , 0 ) , flags ) ; } case ERROR_MARK : return error_mark_node ; default : gcc_unreachable ( ) ; } return error_mark_node ; }
This function will instantiate the type of the expression given in
RHS to match the type of LHSTYPE.
This function will instantiate the type of the expression given in RHS to match the type of LHSTYPE .
/* Microsoft allows `A::f' to be resolved to a
	   pointer-to-member.  */ /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
     deduce any type information.  */ /* There only a few kinds of expressions that may have a type
     dependent on overload resolution.  */ /* We don't overwrite rhs if it is an overloaded function.
     Copying it would destroy the tree link.  */ /* This should really only be used when attempting to distinguish
     what sort of a pointer to function we have.  For now, any
     arithmetic operation which is not supported on pointers
     is rejected as an error.  */ /* Do not lose object's side effects.  */ /* This can happen if we are forming a pointer-to-member for a
	 member template.  */ /* Fall through.  */ /*template_only=*/ /*template_only=*/ /*explicit_targs=*/