FreeBSD/contrib/gcc/cp/name-lookup.c
/* DECL is a FUNCTION_DECL for a non-member function, which may have
   other definitions already in place.  We get around this by making
   the value of the identifier point to a list of all the things that
   want to be referenced by that name.  It is then up to the users of
   that name to decide what to do with that list.

   DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
   DECL_TEMPLATE_RESULT.  It is dealt with the same way.

   FLAGS is a bitwise-or of the following values:
     PUSH_LOCAL: Bind DECL in the current scope, rather than at
		 namespace scope.
     PUSH_USING: DECL is being pushed as the result of a using
		 declaration.

   IS_FRIEND is true if this is a friend declaration.

   The value returned may be a previous declaration if we guessed wrong
   about what language DECL should belong to (C or C++).  Otherwise,
   it's always DECL (and never something that's not a _DECL).  */
DECL is a FUNCTION_DECL for a non-member function, which may have
other definitions already in place.  We get around this by making
the value of the identifier point to a list of all the things that
want to be referenced by that name.  It is then up to the users of
that name to decide what to do with that list.

DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
DECL_TEMPLATE_RESULT.  It is dealt with the same way.

FLAGS is a bitwise-or of the following values:
PUSH_LOCAL: Bind DECL in the current scope, rather than at
namespace scope.
PUSH_USING: DECL is being pushed as the result of a using
declaration.

IS_FRIEND is true if this is a friend declaration.

The value returned may be a previous declaration if we guessed wrong
about what language DECL should belong to (C or C++).  Otherwise,
it's always DECL (and never something that's not a _DECL).
DECL is a FUNCTION_DECL for a non - member function which may have other definitions already in place . We get around this by making the value of the identifier point to a list of all the things that want to be referenced by that name . It is then up to the users of that name to decide what to do with that list . DECL may also be a TEMPLATE_DECL with a FUNCTION_DECL in its DECL_TEMPLATE_RESULT . It is dealt with the same way . FLAGS is a bitwise - or of the following values : PUSH_LOCAL : Bind DECL in the current scope rather than at namespace scope . PUSH_USING : DECL is being pushed as the result of a using declaration . IS_FRIEND is true if this is a friend declaration . The value returned may be a previous declaration if we guessed wrong about what language DECL should belong to ( C or C ++ ) . Otherwise it ' s always DECL ( and never something that ' s not a _DECL ) .
static tree
push_overloaded_decl (tree decl, int flags, bool is_friend)
{
  tree name = DECL_NAME (decl);
  tree old;
  tree new_binding;
  int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
  timevar_push (TV_NAME_LOOKUP);
  if (doing_global)
    old = namespace_binding (name, DECL_CONTEXT (decl));
  else
    old = lookup_name_innermost_nonclass_level (name);
  if (old)
    {
      if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old))
	{
	  tree t = TREE_TYPE (old);
	  if (IS_AGGR_TYPE (t) && warn_shadow
	      && (! DECL_IN_SYSTEM_HEADER (decl)
		  || ! DECL_IN_SYSTEM_HEADER (old)))
	    warning (0, "%q#D hides constructor for %q#T", decl, t);
	  old = NULL_TREE;
	}
      else if (is_overloaded_fn (old))
	{
	  tree tmp;
	  for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
	    {
	      tree fn = OVL_CURRENT (tmp);
	      tree dup;
	      if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
		  && !(flags & PUSH_USING)
		  && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
				TYPE_ARG_TYPES (TREE_TYPE (decl)))
		  && ! decls_match (fn, decl))
		error ("%q#D conflicts with previous using declaration %q#D",
		       decl, fn);
	      dup = duplicate_decls (decl, fn, is_friend);
	      if (dup == fn || dup == error_mark_node)
		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup);
	    }
	  if (TREE_CODE (old) == FUNCTION_DECL
	      && DECL_ANTICIPATED (old)
	      && !DECL_HIDDEN_FRIEND_P (old))
	    old = NULL;
	}
      else if (old == error_mark_node)
	old = NULL_TREE;
      else
	{
	  error ("previous non-function declaration %q+#D", old);
	  error ("conflicts with function declaration %q#D", decl);
	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
	}
    }
  if (old || TREE_CODE (decl) == TEMPLATE_DECL
      || (flags & PUSH_USING))
    {
      if (old && TREE_CODE (old) != OVERLOAD)
	new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
      else
	new_binding = ovl_cons (decl, old);
      if (flags & PUSH_USING)
	OVL_USED (new_binding) = 1;
    }
  else
    new_binding = decl;
  if (doing_global)
    set_namespace_binding (name, current_namespace, new_binding);
  else
    {
      if (TREE_CODE (new_binding) == OVERLOAD && old)
	{
	  tree *d;
	  for (d = &IDENTIFIER_BINDING (name)->scope->names;
	       *d;
	       d = &TREE_CHAIN (*d))
	    if (*d == old
		|| (TREE_CODE (*d) == TREE_LIST
		    && TREE_VALUE (*d) == old))
	      {
		if (TREE_CODE (*d) == TREE_LIST)
		  TREE_VALUE (*d) = new_binding;
		else
		  *d = tree_cons (NULL_TREE, new_binding,
				  TREE_CHAIN (*d));
		IDENTIFIER_BINDING (name)->value = new_binding;
		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
	      }
	  gcc_unreachable ();
	}
      push_local_binding (name, new_binding, flags);
    }
  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
static tree push_overloaded_decl ( tree decl , int flags , bool is_friend ) { tree name = DECL_NAME ( decl ) ; tree old ; tree new_binding ; int doing_global = ( namespace_bindings_p ( ) || ! ( flags & PUSH_LOCAL ) ) ; timevar_push ( TV_NAME_LOOKUP ) ; if ( doing_global ) old = namespace_binding ( name , DECL_CONTEXT ( decl ) ) ; else old = lookup_name_innermost_nonclass_level ( name ) ; if ( old ) { if ( TREE_CODE ( old ) == TYPE_DECL && DECL_ARTIFICIAL ( old ) ) { tree t = TREE_TYPE ( old ) ; if ( IS_AGGR_TYPE ( t ) && warn_shadow && ( ! DECL_IN_SYSTEM_HEADER ( decl ) || ! DECL_IN_SYSTEM_HEADER ( old ) ) ) warning ( 0 , " " , decl , t ) ; old = NULL_TREE ; } else if ( is_overloaded_fn ( old ) ) { tree tmp ; for ( tmp = old ; tmp ; tmp = OVL_NEXT ( tmp ) ) { tree fn = OVL_CURRENT ( tmp ) ; tree dup ; if ( TREE_CODE ( tmp ) == OVERLOAD && OVL_USED ( tmp ) && ! ( flags & PUSH_USING ) && compparms ( TYPE_ARG_TYPES ( TREE_TYPE ( fn ) ) , TYPE_ARG_TYPES ( TREE_TYPE ( decl ) ) ) && ! decls_match ( fn , decl ) ) error ( " " , decl , fn ) ; dup = duplicate_decls ( decl , fn , is_friend ) ; if ( dup == fn || dup == error_mark_node ) POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , dup ) ; } if ( TREE_CODE ( old ) == FUNCTION_DECL && DECL_ANTICIPATED ( old ) && ! DECL_HIDDEN_FRIEND_P ( old ) ) old = NULL ; } else if ( old == error_mark_node ) old = NULL_TREE ; else { error ( " " , old ) ; error ( " " , decl ) ; POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , decl ) ; } } if ( old || TREE_CODE ( decl ) == TEMPLATE_DECL || ( flags & PUSH_USING ) ) { if ( old && TREE_CODE ( old ) != OVERLOAD ) new_binding = ovl_cons ( decl , ovl_cons ( old , NULL_TREE ) ) ; else new_binding = ovl_cons ( decl , old ) ; if ( flags & PUSH_USING ) OVL_USED ( new_binding ) = 1 ; } else new_binding = decl ; if ( doing_global ) set_namespace_binding ( name , current_namespace , new_binding ) ; else { if ( TREE_CODE ( new_binding ) == OVERLOAD && old ) { tree * d ; for ( d = & IDENTIFIER_BINDING ( name ) -> scope -> names ; * d ; d = & TREE_CHAIN ( * d ) ) if ( * d == old || ( TREE_CODE ( * d ) == TREE_LIST && TREE_VALUE ( * d ) == old ) ) { if ( TREE_CODE ( * d ) == TREE_LIST ) TREE_VALUE ( * d ) = new_binding ; else * d = tree_cons ( NULL_TREE , new_binding , TREE_CHAIN ( * d ) ) ; IDENTIFIER_BINDING ( name ) -> value = new_binding ; POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , decl ) ; } gcc_unreachable ( ) ; } push_local_binding ( name , new_binding , flags ) ; } POP_TIMEVAR_AND_RETURN ( TV_NAME_LOOKUP , decl ) ; }
DECL is a FUNCTION_DECL for a non-member function, which may have
other definitions already in place.
DECL is a FUNCTION_DECL for a non - member function which may have other definitions already in place .
/* If DECL was a redeclaration of FN -- even an invalid
		 one -- pass that information along to our caller.  */ /* We don't overload implicit built-ins.  duplicate_decls()
	     may fail to merge the decls if the new decl is e.g. a
	     template function.  */ /* Ignore the undefined symbol marker.  */ /* If it's a using declaration, we always need to build an OVERLOAD,
	 because it's the only way to remember that the declaration comes
	 from 'using', and have the lookup behave correctly.  */ /* NAME is not ambiguous.  */ /* We only create an OVERLOAD if there was a previous binding at
	 this level, or if decl is a template. In the former case, we
	 need to remove the old binding and replace it with the new
	 binding.  We must also run through the NAMES on the binding
	 level where the name was bound to update the chain.  */ /* Just replace the old binding with the new.  */ /* Build a TREE_LIST to wrap the OVERLOAD.  */ /* And update the cxx_binding node.  */ /* We should always find a previous binding in this case.  */ /* Install the new binding.  */