FreeBSD/contrib/gcc/cp/call.c
/* Build a call to a global operator new.  FNNAME is the name of the
   operator (either "operator new" or "operator new[]") and ARGS are
   the arguments provided.  *SIZE points to the total number of bytes
   required by the allocation, and is updated if that is changed here.
   *COOKIE_SIZE is non-NULL if a cookie should be used.  If this
   function determines that no cookie should be used, after all,
   *COOKIE_SIZE is set to NULL_TREE.  If FN is non-NULL, it will be
   set, upon return, to the allocation function called.  */
Build a call to a global operator new.  FNNAME is the name of the
operator (either "operator new" or "operator new[]") and ARGS are
the arguments provided.  *SIZE points to the total number of bytes
required by the allocation, and is updated if that is changed here.
COOKIE_SIZE is non-NULL if a cookie should be used.  If this
function determines that no cookie should be used, after all,
COOKIE_SIZE is set to NULL_TREE.  If FN is non-NULL, it will be
set, upon return, to the allocation function called.
Build a call to a global operator new . FNNAME is the name of the operator ( either " operator new " or " operator new [] " ) and ARGS are the arguments provided . * SIZE points to the total number of bytes required by the allocation and is updated if that is changed here . COOKIE_SIZE is non - NULL if a cookie should be used . If this function determines that no cookie should be used after all COOKIE_SIZE is set to NULL_TREE . If FN is non - NULL it will be set upon return to the allocation function called .
tree
build_operator_new_call (tree fnname, tree args,
			 tree *size, tree *cookie_size,
			 tree *fn)
{
  tree fns;
  struct z_candidate *candidates;
  struct z_candidate *cand;
  bool any_viable_p;
  if (fn)
    *fn = NULL_TREE;
  args = tree_cons (NULL_TREE, *size, args);
  args = resolve_args (args);
  if (args == error_mark_node)
    return args;
  fns = lookup_function_nonclass (fnname, args, false);
  cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
  if (!cand)
    {
      if (!any_viable_p)
	error ("no matching function for call to %<%D(%A)%>",
	       DECL_NAME (OVL_CURRENT (fns)), args);
      else
	error ("call of overloaded %<%D(%A)%> is ambiguous",
	       DECL_NAME (OVL_CURRENT (fns)), args);
      if (candidates)
	print_z_candidates (candidates);
      return error_mark_node;
    }
   if (*cookie_size)
     {
       bool use_cookie = true;
       if (!abi_version_at_least (2))
	 {
	   tree placement = TREE_CHAIN (args);
	   if (placement && !TREE_CHAIN (placement)
	       && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
			       ptr_type_node))
	     use_cookie = false;
	 }
       else
	 {
	   tree arg_types;
	   arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
	   arg_types = TREE_CHAIN (arg_types);
	   if (arg_types
	       && TREE_CHAIN (arg_types) == void_list_node
	       && same_type_p (TREE_VALUE (arg_types),
			       ptr_type_node))
	     use_cookie = false;
	 }
       if (use_cookie)
	 {
	   *size = size_binop (PLUS_EXPR, *size, *cookie_size);
	   TREE_VALUE (args) = *size;
	 }
       else
	 *cookie_size = NULL_TREE;
     }
   if (fn)
     *fn = cand->fn;
   return build_over_call (cand, LOOKUP_NORMAL);
}
tree build_operator_new_call ( tree fnname , tree args , tree * size , tree * cookie_size , tree * fn ) { tree fns ; struct z_candidate * candidates ; struct z_candidate * cand ; bool any_viable_p ; if ( fn ) * fn = NULL_TREE ; args = tree_cons ( NULL_TREE , * size , args ) ; args = resolve_args ( args ) ; if ( args == error_mark_node ) return args ; fns = lookup_function_nonclass ( fnname , args , false ) ; cand = perform_overload_resolution ( fns , args , & candidates , & any_viable_p ) ; if ( ! cand ) { if ( ! any_viable_p ) error ( " " , DECL_NAME ( OVL_CURRENT ( fns ) ) , args ) ; else error ( " " , DECL_NAME ( OVL_CURRENT ( fns ) ) , args ) ; if ( candidates ) print_z_candidates ( candidates ) ; return error_mark_node ; } if ( * cookie_size ) { bool use_cookie = true ; if ( ! abi_version_at_least ( 2 ) ) { tree placement = TREE_CHAIN ( args ) ; if ( placement && ! TREE_CHAIN ( placement ) && same_type_p ( TREE_TYPE ( TREE_VALUE ( placement ) ) , ptr_type_node ) ) use_cookie = false ; } else { tree arg_types ; arg_types = TYPE_ARG_TYPES ( TREE_TYPE ( cand -> fn ) ) ; arg_types = TREE_CHAIN ( arg_types ) ; if ( arg_types && TREE_CHAIN ( arg_types ) == void_list_node && same_type_p ( TREE_VALUE ( arg_types ) , ptr_type_node ) ) use_cookie = false ; } if ( use_cookie ) { * size = size_binop ( PLUS_EXPR , * size , * cookie_size ) ; TREE_VALUE ( args ) = * size ; } else * cookie_size = NULL_TREE ; } if ( fn ) * fn = cand -> fn ; return build_over_call ( cand , LOOKUP_NORMAL ) ; }
Build a call to a global operator new.
Build a call to a global operator new .
/* Based on:

       [expr.new]

       If this lookup fails to find the name, or if the allocated type
       is not a class type, the allocation function's name is looked
       up in the global scope.

     we disregard block-scope declarations of "operator new".  */ /*block_p=*/ /* Figure out what function is being called.  */ /* If no suitable function could be found, issue an error message
     and give up.  */ /* If a cookie is required, add some extra space.  Whether
      or not a cookie is required cannot be determined until
      after we know which function was called.  */ /* In G++ 3.2, the check was implemented incorrectly; it
	      looked at the placement expression, rather than the
	      type of the function.  */ /* Skip the size_t parameter.  */ /* Check the remaining parameters (if any).  */ /* If we need a cookie, adjust the number of bytes allocated.  */ /* Update the total size.  */ /* Update the argument list to reflect the adjusted size.  */ /* Tell our caller which function we decided to call.  */ /* Build the CALL_EXPR.  */