/* Breadth-first and depth-first routines for
   searching multiple-inheritance lattice for GNU C++.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.
   Contributed by Michael Tiemann (tiemann@cygnus.com)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* High-level class interface.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
#include "intl.h"
#include "toplev.h"
#include "spellcheck-tree.h"
#include "stringpool.h"
#include "attribs.h"

static int is_subobject_of_p (tree, tree);
static tree dfs_lookup_base (tree, void *);
static tree dfs_dcast_hint_pre (tree, void *);
static tree dfs_dcast_hint_post (tree, void *);
static tree dfs_debug_mark (tree, void *);
static int check_hidden_convs (tree, int, int, tree, tree, tree);
static tree split_conversions (tree, tree, tree, tree);
static int lookup_conversions_r (tree, int, int, tree, tree, tree *);
static int look_for_overrides_r (tree, tree);
static tree lookup_field_r (tree, void *);
static tree dfs_accessible_post (tree, void *);
static tree dfs_walk_once_accessible (tree, bool,
				      tree (*pre_fn) (tree, void *),
				      tree (*post_fn) (tree, void *),
				      void *data);
static tree dfs_access_in_type (tree, void *);
static access_kind access_in_type (tree, tree);
static tree dfs_get_pure_virtuals (tree, void *);


/* Data for lookup_base and its workers.  */

struct lookup_base_data_s
{
  tree t;		/* type being searched.  */
  tree base;		/* The base type we're looking for.  */
  tree binfo;		/* Found binfo.  */
  bool via_virtual;	/* Found via a virtual path.  */
  bool ambiguous;	/* Found multiply ambiguous */
  bool repeated_base;	/* Whether there are repeated bases in the
			    hierarchy.  */
  bool want_any;	/* Whether we want any matching binfo.  */
};

/* Worker function for lookup_base.  See if we've found the desired
   base and update DATA_ (a pointer to LOOKUP_BASE_DATA_S).  */

static tree
dfs_lookup_base (tree binfo, void *data_)
{
  struct lookup_base_data_s *data = (struct lookup_base_data_s *) data_;

  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base))
    {
      if (!data->binfo)
	{
	  data->binfo = binfo;
	  data->via_virtual
	    = binfo_via_virtual (data->binfo, data->t) != NULL_TREE;

	  if (!data->repeated_base)
	    /* If there are no repeated bases, we can stop now.  */
	    return binfo;

	  if (data->want_any && !data->via_virtual)
	    /* If this is a non-virtual base, then we can't do
	       better.  */
	    return binfo;

	  return dfs_skip_bases;
	}
      else
	{
	  gcc_assert (binfo != data->binfo);

	  /* We've found more than one matching binfo.  */
	  if (!data->want_any)
	    {
	      /* This is immediately ambiguous.  */
	      data->binfo = NULL_TREE;
	      data->ambiguous = true;
	      return error_mark_node;
	    }

	  /* Prefer one via a non-virtual path.  */
	  if (!binfo_via_virtual (binfo, data->t))
	    {
	      data->binfo = binfo;
	      data->via_virtual = false;
	      return binfo;
	    }

	  /* There must be repeated bases, otherwise we'd have stopped
	     on the first base we found.  */
	  return dfs_skip_bases;
	}
    }

  return NULL_TREE;
}

/* This deals with bug PR17314.

   DECL is a declaration and BINFO represents a class that has attempted (but
   failed) to access DECL.

   Examine the parent binfos of BINFO and determine whether any of them had
   private access to DECL.  If they did, return the parent binfo.  This helps
   in figuring out the correct error message to show (if the parents had
   access, it's their fault for not giving sufficient access to BINFO).

   If no parents had access, return NULL_TREE.  */

tree
get_parent_with_private_access (tree decl, tree binfo)
{
  /* Only BINFOs should come through here.  */
  gcc_assert (TREE_CODE (binfo) == TREE_BINFO);

  tree base_binfo = NULL_TREE;

  /* Iterate through immediate parent classes.  */
  for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    {
      /* This parent had private access.  Therefore that's why BINFO can't
	  access DECL.  */
      if (access_in_type (BINFO_TYPE (base_binfo), decl) == ak_private)
	return base_binfo;
    }

  /* None of the parents had access.  Note: it's impossible for one of the
     parents to have had public or protected access to DECL, since then
     BINFO would have been able to access DECL too.  */
  return NULL_TREE;
}

/* Returns true if type BASE is accessible in T.  (BASE is known to be
   a (possibly non-proper) base class of T.)  If CONSIDER_LOCAL_P is
   true, consider any special access of the current scope, or access
   bestowed by friendship.  */

bool
accessible_base_p (tree t, tree base, bool consider_local_p)
{
  tree decl;

  /* [class.access.base]

     A base class is said to be accessible if an invented public
     member of the base class is accessible.

     If BASE is a non-proper base, this condition is trivially
     true.  */
  if (same_type_p (t, base))
    return true;
  /* Rather than inventing a public member, we use the implicit
     public typedef created in the scope of every class.  */
  decl = TYPE_FIELDS (base);
  while (!DECL_SELF_REFERENCE_P (decl))
    decl = DECL_CHAIN (decl);
  while (ANON_AGGR_TYPE_P (t))
    t = TYPE_CONTEXT (t);
  return accessible_p (t, decl, consider_local_p);
}

/* Lookup BASE in the hierarchy dominated by T.  Do access checking as
   ACCESS specifies.  Return the binfo we discover.  If KIND_PTR is
   non-NULL, fill with information about what kind of base we
   discovered.

   If the base is inaccessible, or ambiguous, then error_mark_node is
   returned.  If the tf_error bit of COMPLAIN is not set, no error
   is issued.  */

tree
lookup_base (tree t, tree base, base_access access,
	     base_kind *kind_ptr, tsubst_flags_t complain)
{
  tree binfo;
  tree t_binfo;
  base_kind bk;

  /* "Nothing" is definitely not derived from Base.  */
  if (t == NULL_TREE)
    {
      if (kind_ptr)
	*kind_ptr = bk_not_base;
      return NULL_TREE;
    }

  if (t == error_mark_node || base == error_mark_node)
    {
      if (kind_ptr)
	*kind_ptr = bk_not_base;
      return error_mark_node;
    }
  gcc_assert (TYPE_P (base));

  if (!TYPE_P (t))
    {
      t_binfo = t;
      t = BINFO_TYPE (t);
    }
  else
    {
      t = complete_type (TYPE_MAIN_VARIANT (t));
      if (dependent_type_p (t))
	if (tree open = currently_open_class (t))
	  t = open;
      t_binfo = TYPE_BINFO (t);
    }

  base = TYPE_MAIN_VARIANT (base);

  /* If BASE is incomplete, it can't be a base of T--and instantiating it
     might cause an error.  */
  if (t_binfo && CLASS_TYPE_P (base) && COMPLETE_OR_OPEN_TYPE_P (base))
    {
      struct lookup_base_data_s data;

      data.t = t;
      data.base = base;
      data.binfo = NULL_TREE;
      data.ambiguous = data.via_virtual = false;
      data.repeated_base = CLASSTYPE_REPEATED_BASE_P (t);
      data.want_any = access == ba_any;

      dfs_walk_once (t_binfo, dfs_lookup_base, NULL, &data);
      binfo = data.binfo;

      if (!binfo)
	bk = data.ambiguous ? bk_ambig : bk_not_base;
      else if (binfo == t_binfo)
	bk = bk_same_type;
      else if (data.via_virtual)
	bk = bk_via_virtual;
      else
	bk = bk_proper_base;
    }
  else
    {
      binfo = NULL_TREE;
      bk = bk_not_base;
    }

  /* Check that the base is unambiguous and accessible.  */
  if (access != ba_any)
    switch (bk)
      {
      case bk_not_base:
	break;

      case bk_ambig:
	if (complain & tf_error)
	  error ("%qT is an ambiguous base of %qT", base, t);
	binfo = error_mark_node;
	break;

      default:
	if ((access & ba_check_bit)
	    /* If BASE is incomplete, then BASE and TYPE are probably
	       the same, in which case BASE is accessible.  If they
	       are not the same, then TYPE is invalid.  In that case,
	       there's no need to issue another error here, and
	       there's no implicit typedef to use in the code that
	       follows, so we skip the check.  */
	    && COMPLETE_TYPE_P (base)
	    && !accessible_base_p (t, base, !(access & ba_ignore_scope)))
	  {
	    if (complain & tf_error)
	      error ("%qT is an inaccessible base of %qT", base, t);
	    binfo = error_mark_node;
	    bk = bk_inaccessible;
	  }
	break;
      }

  if (kind_ptr)
    *kind_ptr = bk;

  return binfo;
}

/* Data for dcast_base_hint walker.  */

struct dcast_data_s
{
  tree subtype;   /* The base type we're looking for.  */
  int virt_depth; /* Number of virtual bases encountered from most
		     derived.  */
  tree offset;    /* Best hint offset discovered so far.  */
  bool repeated_base;  /* Whether there are repeated bases in the
			  hierarchy.  */
};

/* Worker for dcast_base_hint.  Search for the base type being cast
   from.  */

static tree
dfs_dcast_hint_pre (tree binfo, void *data_)
{
  struct dcast_data_s *data = (struct dcast_data_s *) data_;

  if (BINFO_VIRTUAL_P (binfo))
    data->virt_depth++;

  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->subtype))
    {
      if (data->virt_depth)
	{
	  data->offset = ssize_int (-1);
	  return data->offset;
	}
      if (data->offset)
	data->offset = ssize_int (-3);
      else
	data->offset = BINFO_OFFSET (binfo);

      return data->repeated_base ? dfs_skip_bases : data->offset;
    }

  return NULL_TREE;
}

/* Worker for dcast_base_hint.  Track the virtual depth.  */

static tree
dfs_dcast_hint_post (tree binfo, void *data_)
{
  struct dcast_data_s *data = (struct dcast_data_s *) data_;

  if (BINFO_VIRTUAL_P (binfo))
    data->virt_depth--;

  return NULL_TREE;
}

/* The dynamic cast runtime needs a hint about how the static SUBTYPE type
   started from is related to the required TARGET type, in order to optimize
   the inheritance graph search. This information is independent of the
   current context, and ignores private paths, hence get_base_distance is
   inappropriate. Return a TREE specifying the base offset, BOFF.
   BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset BOFF,
      and there are no public virtual SUBTYPE bases.
   BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
   BOFF == -2, SUBTYPE is not a public base.
   BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.  */

tree
dcast_base_hint (tree subtype, tree target)
{
  struct dcast_data_s data;

  data.subtype = subtype;
  data.virt_depth = 0;
  data.offset = NULL_TREE;
  data.repeated_base = CLASSTYPE_REPEATED_BASE_P (target);

  dfs_walk_once_accessible (TYPE_BINFO (target), /*friends=*/false,
			    dfs_dcast_hint_pre, dfs_dcast_hint_post, &data);
  return data.offset ? data.offset : ssize_int (-2);
}

/* Search for a member with name NAME in a multiple inheritance
   lattice specified by TYPE.  If it does not exist, return NULL_TREE.
   If the member is ambiguously referenced, return `error_mark_node'.
   Otherwise, return a DECL with the indicated name.  If WANT_TYPE is
   true, type declarations are preferred.  */

/* Return the FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, or
   NAMESPACE_DECL corresponding to the innermost non-block scope.  */

tree
current_scope (void)
{
  /* There are a number of cases we need to be aware of here:
			 current_class_type	current_function_decl
     global			NULL			NULL
     fn-local			NULL			SET
     class-local		SET			NULL
     class->fn			SET			SET
     fn->class			SET			SET

     Those last two make life interesting.  If we're in a function which is
     itself inside a class, we need decls to go into the fn's decls (our
     second case below).  But if we're in a class and the class itself is
     inside a function, we need decls to go into the decls for the class.  To
     achieve this last goal, we must see if, when both current_class_ptr and
     current_function_decl are set, the class was declared inside that
     function.  If so, we know to put the decls into the class's scope.  */
  if (current_function_decl && current_class_type
      && ((DECL_FUNCTION_MEMBER_P (current_function_decl)
	   && same_type_p (DECL_CONTEXT (current_function_decl),
			   current_class_type))
	  || (DECL_FRIEND_CONTEXT (current_function_decl)
	      && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
			      current_class_type))))
    return current_function_decl;

  if (current_class_type)
    return current_class_type;

  if (current_function_decl)
    return current_function_decl;

  return current_namespace;
}

/* Returns nonzero if we are currently in a function scope.  Note
   that this function returns zero if we are within a local class, but
   not within a member function body of the local class.  */

int
at_function_scope_p (void)
{
  tree cs = current_scope ();
  /* Also check cfun to make sure that we're really compiling
     this function (as opposed to having set current_function_decl
     for access checking or some such).  */
  return (cs && TREE_CODE (cs) == FUNCTION_DECL
	  && cfun && cfun->decl == current_function_decl);
}

/* Returns true if the innermost active scope is a class scope.  */

bool
at_class_scope_p (void)
{
  tree cs = current_scope ();
  return cs && TYPE_P (cs);
}

/* Returns true if the innermost active scope is a namespace scope.  */

bool
at_namespace_scope_p (void)
{
  tree cs = current_scope ();
  return cs && TREE_CODE (cs) == NAMESPACE_DECL;
}

/* Return the scope of DECL, as appropriate when doing name-lookup.  */

tree
context_for_name_lookup (tree decl)
{
  /* [class.union]

     For the purposes of name lookup, after the anonymous union
     definition, the members of the anonymous union are considered to
     have been defined in the scope in which the anonymous union is
     declared.  */
  tree context = DECL_CONTEXT (decl);

  while (context && TYPE_P (context)
	 && (ANON_AGGR_TYPE_P (context) || UNSCOPED_ENUM_P (context)))
    context = TYPE_CONTEXT (context);
  if (!context)
    context = global_namespace;

  return context;
}

/* Returns true iff DECL is declared in TYPE.  */

static bool
member_declared_in_type (tree decl, tree type)
{
  /* A normal declaration obviously counts.  */
  if (context_for_name_lookup (decl) == type)
    return true;
  /* So does a using or access declaration.  */
  if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl)
      && purpose_member (type, DECL_ACCESS (decl)))
    return true;
  return false;
}

/* The accessibility routines use BINFO_ACCESS for scratch space
   during the computation of the accessibility of some declaration.  */

/* Avoid walking up past a declaration of the member.  */

static tree
dfs_access_in_type_pre (tree binfo, void *data)
{
  tree decl = (tree) data;
  tree type = BINFO_TYPE (binfo);
  if (member_declared_in_type (decl, type))
    return dfs_skip_bases;
  return NULL_TREE;
}

#define BINFO_ACCESS(NODE) \
  ((access_kind) ((TREE_PUBLIC (NODE) << 1) | TREE_PRIVATE (NODE)))

/* Set the access associated with NODE to ACCESS.  */

#define SET_BINFO_ACCESS(NODE, ACCESS)			\
  ((TREE_PUBLIC (NODE) = ((ACCESS) & 2) != 0),	\
   (TREE_PRIVATE (NODE) = ((ACCESS) & 1) != 0))

/* Called from access_in_type via dfs_walk.  Calculate the access to
   DATA (which is really a DECL) in BINFO.  */

static tree
dfs_access_in_type (tree binfo, void *data)
{
  tree decl = (tree) data;
  tree type = BINFO_TYPE (binfo);
  access_kind access = ak_none;

  if (context_for_name_lookup (decl) == type)
    {
      /* If we have descended to the scope of DECL, just note the
	 appropriate access.  */
      if (TREE_PRIVATE (decl))
	access = ak_private;
      else if (TREE_PROTECTED (decl))
	access = ak_protected;
      else
	access = ak_public;
    }
  else
    {
      /* First, check for an access-declaration that gives us more
	 access to the DECL.  */
      if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl))
	{
	  tree decl_access = purpose_member (type, DECL_ACCESS (decl));

	  if (decl_access)
	    {
	      decl_access = TREE_VALUE (decl_access);

	      if (decl_access == access_public_node)
		access = ak_public;
	      else if (decl_access == access_protected_node)
		access = ak_protected;
	      else if (decl_access == access_private_node)
		access = ak_private;
	      else
		gcc_unreachable ();
	    }
	}

      if (!access)
	{
	  int i;
	  tree base_binfo;
	  vec<tree, va_gc> *accesses;

	  /* Otherwise, scan our baseclasses, and pick the most favorable
	     access.  */
	  accesses = BINFO_BASE_ACCESSES (binfo);
	  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	    {
	      tree base_access = (*accesses)[i];
	      access_kind base_access_now = BINFO_ACCESS (base_binfo);

	      if (base_access_now == ak_none || base_access_now == ak_private)
		/* If it was not accessible in the base, or only
		   accessible as a private member, we can't access it
		   all.  */
		base_access_now = ak_none;
	      else if (base_access == access_protected_node)
		/* Public and protected members in the base become
		   protected here.  */
		base_access_now = ak_protected;
	      else if (base_access == access_private_node)
		/* Public and protected members in the base become
		   private here.  */
		base_access_now = ak_private;

	      /* See if the new access, via this base, gives more
		 access than our previous best access.  */
	      if (base_access_now != ak_none
		  && (access == ak_none || base_access_now < access))
		{
		  access = base_access_now;

		  /* If the new access is public, we can't do better.  */
		  if (access == ak_public)
		    break;
		}
	    }
	}
    }

  /* Note the access to DECL in TYPE.  */
  SET_BINFO_ACCESS (binfo, access);

  return NULL_TREE;
}

/* Return the access to DECL in TYPE.  */

static access_kind
access_in_type (tree type, tree decl)
{
  tree binfo = TYPE_BINFO (type);

  /* We must take into account

       [class.paths]

       If a name can be reached by several paths through a multiple
       inheritance graph, the access is that of the path that gives
       most access.

    The algorithm we use is to make a post-order depth-first traversal
    of the base-class hierarchy.  As we come up the tree, we annotate
    each node with the most lenient access.  */
  dfs_walk_once (binfo, dfs_access_in_type_pre, dfs_access_in_type, decl);

  return BINFO_ACCESS (binfo);
}

/* Returns nonzero if it is OK to access DECL named in TYPE through an object
   of OTYPE in the context of DERIVED.  */

static int
protected_accessible_p (tree decl, tree derived, tree type, tree otype)
{
  /* We're checking this clause from [class.access.base]

       m as a member of N is protected, and the reference occurs in a
       member or friend of class N, or in a member or friend of a
       class P derived from N, where m as a member of P is public, private
       or protected.

    Here DERIVED is a possible P, DECL is m and TYPE is N.  */

  /* If DERIVED isn't derived from N, then it can't be a P.  */
  if (!DERIVED_FROM_P (type, derived))
    return 0;

  /* DECL_NONSTATIC_MEMBER_P won't work for USING_DECLs.  */
  decl = strip_using_decl (decl);
  /* We don't expect or support dependent decls.  */
  gcc_assert (TREE_CODE (decl) != USING_DECL);

  /* [class.protected]

     When a friend or a member function of a derived class references
     a protected non-static member of a base class, an access check
     applies in addition to those described earlier in clause
     _class.access_) Except when forming a pointer to member
     (_expr.unary.op_), the access must be through a pointer to,
     reference to, or object of the derived class itself (or any class
     derived from that class) (_expr.ref_).  If the access is to form
     a pointer to member, the nested-name-specifier shall name the
     derived class (or any class derived from that class).  */
  if (DECL_NONSTATIC_MEMBER_P (decl)
      && !DERIVED_FROM_P (derived, otype))
    return 0;

  return 1;
}

/* Returns nonzero if SCOPE is a type or a friend of a type which would be able
   to access DECL through TYPE.  OTYPE is the type of the object.  */

static int
friend_accessible_p (tree scope, tree decl, tree type, tree otype)
{
  /* We're checking this clause from [class.access.base]

       m as a member of N is protected, and the reference occurs in a
       member or friend of class N, or in a member or friend of a
       class P derived from N, where m as a member of P is public, private
       or protected.

    Here DECL is m and TYPE is N.  SCOPE is the current context,
    and we check all its possible Ps.  */
  tree befriending_classes;
  tree t;

  if (!scope)
    return 0;

  if (is_global_friend (scope))
    return 1;

  /* Is SCOPE itself a suitable P?  */
  if (TYPE_P (scope) && protected_accessible_p (decl, scope, type, otype))
    return 1;

  if (DECL_DECLARES_FUNCTION_P (scope))
    befriending_classes = DECL_BEFRIENDING_CLASSES (scope);
  else if (TYPE_P (scope))
    befriending_classes = CLASSTYPE_BEFRIENDING_CLASSES (scope);
  else
    return 0;

  for (t = befriending_classes; t; t = TREE_CHAIN (t))
    if (protected_accessible_p (decl, TREE_VALUE (t), type, otype))
      return 1;

  /* Nested classes have the same access as their enclosing types, as
     per DR 45 (this is a change from C++98).  */
  if (TYPE_P (scope))
    if (friend_accessible_p (TYPE_CONTEXT (scope), decl, type, otype))
      return 1;

  if (DECL_DECLARES_FUNCTION_P (scope))
    {
      /* Perhaps this SCOPE is a member of a class which is a
	 friend.  */
      if (DECL_CLASS_SCOPE_P (scope)
	  && friend_accessible_p (DECL_CONTEXT (scope), decl, type, otype))
	return 1;
      /* Perhaps SCOPE is a friend function defined inside a class from which
	 DECL is accessible.  */
      if (tree fctx = DECL_FRIEND_CONTEXT (scope))
	if (friend_accessible_p (fctx, decl, type, otype))
	  return 1;
    }

  /* Maybe scope's template is a friend.  */
  if (tree tinfo = get_template_info (scope))
    {
      tree tmpl = TI_TEMPLATE (tinfo);
      if (DECL_CLASS_TEMPLATE_P (tmpl))
	tmpl = TREE_TYPE (tmpl);
      else
	tmpl = DECL_TEMPLATE_RESULT (tmpl);
      if (tmpl != scope)
	{
	  /* Increment processing_template_decl to make sure that
	     dependent_type_p works correctly.  */
	  ++processing_template_decl;
	  int ret = friend_accessible_p (tmpl, decl, type, otype);
	  --processing_template_decl;
	  if (ret)
	    return 1;
	}
    }

  /* If is_friend is true, we should have found a befriending class.  */
  gcc_checking_assert (!is_friend (type, scope));

  return 0;
}

struct dfs_accessible_data
{
  tree decl;
  tree object_type;
};

/* Avoid walking up past a declaration of the member.  */

static tree
dfs_accessible_pre (tree binfo, void *data)
{
  dfs_accessible_data *d = (dfs_accessible_data *)data;
  tree type = BINFO_TYPE (binfo);
  if (member_declared_in_type (d->decl, type))
    return dfs_skip_bases;
  return NULL_TREE;
}

/* Called via dfs_walk_once_accessible from accessible_p */

static tree
dfs_accessible_post (tree binfo, void *data)
{
  /* access_in_type already set BINFO_ACCESS for us.  */
  access_kind access = BINFO_ACCESS (binfo);
  tree N = BINFO_TYPE (binfo);
  dfs_accessible_data *d = (dfs_accessible_data *)data;
  tree decl = d->decl;
  tree scope = current_nonlambda_scope ();

  /* A member m is accessible at the point R when named in class N if */
  switch (access)
    {
    case ak_none:
      return NULL_TREE;

    case ak_public:
      /* m as a member of N is public, or */
      return binfo;

    case ak_private:
      {
	/* m as a member of N is private, and R occurs in a member or friend of
	   class N, or */
	if (scope && TREE_CODE (scope) != NAMESPACE_DECL
	    && is_friend (N, scope))
	  return binfo;
	return NULL_TREE;
      }

    case ak_protected:
      {
	/* m as a member of N is protected, and R occurs in a member or friend
	   of class N, or in a member or friend of a class P derived from N,
	   where m as a member of P is public, private, or protected  */
	if (friend_accessible_p (scope, decl, N, d->object_type))
	  return binfo;
	return NULL_TREE;
      }

    default:
      gcc_unreachable ();
    }
}

/* Like accessible_p below, but within a template returns true iff DECL is
   accessible in TYPE to all possible instantiations of the template.  */

int
accessible_in_template_p (tree type, tree decl)
{
  int save_ptd = processing_template_decl;
  processing_template_decl = 0;
  int val = accessible_p (type, decl, false);
  processing_template_decl = save_ptd;
  return val;
}

/* DECL is a declaration from a base class of TYPE, which was the
   class used to name DECL.  Return nonzero if, in the current
   context, DECL is accessible.  If TYPE is actually a BINFO node,
   then we can tell in what context the access is occurring by looking
   at the most derived class along the path indicated by BINFO.  If
   CONSIDER_LOCAL is true, do consider special access the current
   scope or friendship thereof we might have.  */

int
accessible_p (tree type, tree decl, bool consider_local_p)
{
  tree binfo;
  access_kind access;

  /* If this declaration is in a block or namespace scope, there's no
     access control.  */
  if (!TYPE_P (context_for_name_lookup (decl)))
    return 1;

  /* There is no need to perform access checks inside a thunk.  */
  if (current_function_decl && DECL_THUNK_P (current_function_decl))
    return 1;

  tree otype = NULL_TREE;
  if (!TYPE_P (type))
    {
      /* When accessing a non-static member, the most derived type in the
	 binfo chain is the type of the object; remember that type for
	 protected_accessible_p.  */
      for (tree b = type; b; b = BINFO_INHERITANCE_CHAIN (b))
	otype = BINFO_TYPE (b);
      type = BINFO_TYPE (type);
    }
  else
    otype = type;

  /* [class.access.base]

     A member m is accessible when named in class N if

     --m as a member of N is public, or

     --m as a member of N is private, and the reference occurs in a
       member or friend of class N, or

     --m as a member of N is protected, and the reference occurs in a
       member or friend of class N, or in a member or friend of a
       class P derived from N, where m as a member of P is public, private or
       protected, or

     --there exists a base class B of N that is accessible at the point
       of reference, and m is accessible when named in class B.

    We walk the base class hierarchy, checking these conditions.  */

  /* We walk using TYPE_BINFO (type) because access_in_type will set
     BINFO_ACCESS on it and its bases.  */
  binfo = TYPE_BINFO (type);

  /* Compute the accessibility of DECL in the class hierarchy
     dominated by type.  */
  access = access_in_type (type, decl);
  if (access == ak_public)
    return 1;

  /* If we aren't considering the point of reference, only the first bullet
     applies.  */
  if (!consider_local_p)
    return 0;

  dfs_accessible_data d = { decl, otype };

  /* Walk the hierarchy again, looking for a base class that allows
     access.  */
  return dfs_walk_once_accessible (binfo, /*friends=*/true,
				   dfs_accessible_pre,
				   dfs_accessible_post, &d)
    != NULL_TREE;
}

struct lookup_field_info {
  /* The type in which we're looking.  */
  tree type;
  /* The name of the field for which we're looking.  */
  tree name;
  /* If non-NULL, the current result of the lookup.  */
  tree rval;
  /* The path to RVAL.  */
  tree rval_binfo;
  /* If non-NULL, the lookup was ambiguous, and this is a list of the
     candidates.  */
  tree ambiguous;
  /* If nonzero, we are looking for types, not data members.  */
  int want_type;
};

/* True for a class member means that it is shared between all objects
   of that class.

   [class.member.lookup]:If the resulting set of declarations are not all
   from sub-objects of the same type, or the set has a non-static member
   and  includes members from distinct sub-objects, there is an ambiguity
   and the program is ill-formed.

   This function checks that T contains no non-static members.  */

bool
shared_member_p (tree t)
{
  if (VAR_P (t) || TREE_CODE (t) == TYPE_DECL
      || TREE_CODE (t) == CONST_DECL)
    return true;
  if (is_overloaded_fn (t))
    {
      for (ovl_iterator iter (get_fns (t)); iter; ++iter)
	{
	  tree decl = strip_using_decl (*iter);
	  if (TREE_CODE (decl) == USING_DECL)
	    /* Conservatively assume a dependent using-declaration
	       might resolve to a non-static member.  */
	    return false;
	  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
	    return false;
	}
      return true;
    }
  return false;
}

/* Routine to see if the sub-object denoted by the binfo PARENT can be
   found as a base class and sub-object of the object denoted by
   BINFO.  */

static int
is_subobject_of_p (tree parent, tree binfo)
{
  tree probe;

  for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
    {
      if (probe == binfo)
	return 1;
      if (BINFO_VIRTUAL_P (probe))
	return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (binfo))
		!= NULL_TREE);
    }
  return 0;
}

/* DATA is really a struct lookup_field_info.  Look for a field with
   the name indicated there in BINFO.  If this function returns a
   non-NULL value it is the result of the lookup.  Called from
   lookup_field via breadth_first_search.  */

static tree
lookup_field_r (tree binfo, void *data)
{
  struct lookup_field_info *lfi = (struct lookup_field_info *) data;
  tree type = BINFO_TYPE (binfo);
  tree nval = NULL_TREE;

  /* If this is a dependent base, don't look in it.  */
  if (BINFO_DEPENDENT_BASE_P (binfo))
    return NULL_TREE;

  /* If this base class is hidden by the best-known value so far, we
     don't need to look.  */
  if (lfi->rval_binfo && BINFO_INHERITANCE_CHAIN (binfo) == lfi->rval_binfo
      && !BINFO_VIRTUAL_P (binfo))
    return dfs_skip_bases;

  nval = get_class_binding (type, lfi->name, lfi->want_type);

  /* If there is no declaration with the indicated name in this type,
     then there's nothing to do.  */
  if (!nval)
    goto done;

  /* If the lookup already found a match, and the new value doesn't
     hide the old one, we might have an ambiguity.  */
  if (lfi->rval_binfo
      && !is_subobject_of_p (lfi->rval_binfo, binfo))

    {
      if (nval == lfi->rval && shared_member_p (nval))
	/* The two things are really the same.  */
	;
      else if (is_subobject_of_p (binfo, lfi->rval_binfo))
	/* The previous value hides the new one.  */
	;
      else
	{
	  /* We have a real ambiguity.  We keep a chain of all the
	     candidates.  */
	  if (!lfi->ambiguous && lfi->rval)
	    {
	      /* This is the first time we noticed an ambiguity.  Add
		 what we previously thought was a reasonable candidate
		 to the list.  */
	      lfi->ambiguous = tree_cons (NULL_TREE, lfi->rval, NULL_TREE);
	      TREE_TYPE (lfi->ambiguous) = error_mark_node;
	    }

	  /* Add the new value.  */
	  lfi->ambiguous = tree_cons (NULL_TREE, nval, lfi->ambiguous);
	  TREE_TYPE (lfi->ambiguous) = error_mark_node;
	}
    }
  else
    {
      lfi->rval = nval;
      lfi->rval_binfo = binfo;
    }

 done:
  /* Don't look for constructors or destructors in base classes.  */
  if (IDENTIFIER_CDTOR_P (lfi->name))
    return dfs_skip_bases;
  return NULL_TREE;
}

/* Return a "baselink" with BASELINK_BINFO, BASELINK_ACCESS_BINFO,
   BASELINK_FUNCTIONS, and BASELINK_OPTYPE set to BINFO, ACCESS_BINFO,
   FUNCTIONS, and OPTYPE respectively.  */

tree
build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
{
  tree baselink;

  gcc_assert (OVL_P (functions) || TREE_CODE (functions) == TEMPLATE_ID_EXPR);
  gcc_assert (!optype || TYPE_P (optype));
  gcc_assert (TREE_TYPE (functions));

  baselink = make_node (BASELINK);
  TREE_TYPE (baselink) = TREE_TYPE (functions);
  BASELINK_BINFO (baselink) = binfo;
  BASELINK_ACCESS_BINFO (baselink) = access_binfo;
  BASELINK_FUNCTIONS (baselink) = functions;
  BASELINK_OPTYPE (baselink) = optype;

  if (binfo == access_binfo
      && TYPE_BEING_DEFINED (BINFO_TYPE (access_binfo)))
    BASELINK_FUNCTIONS_MAYBE_INCOMPLETE_P (baselink) = true;

  return baselink;
}

/* Look for a member named NAME in an inheritance lattice dominated by
   XBASETYPE.  If PROTECT is 0 or two, we do not check access.  If it
   is 1, we enforce accessibility.  If PROTECT is zero, then, for an
   ambiguous lookup, we return NULL.  If PROTECT is 1, we issue error
   messages about inaccessible or ambiguous lookup.  If PROTECT is 2,
   we return a TREE_LIST whose TREE_TYPE is error_mark_node and whose
   TREE_VALUEs are the list of ambiguous candidates.

   WANT_TYPE is 1 when we should only return TYPE_DECLs.

   If nothing can be found return NULL_TREE and do not issue an error.

   If non-NULL, failure information is written back to AFI.  */

tree
lookup_member (tree xbasetype, tree name, int protect, bool want_type,
	       tsubst_flags_t complain, access_failure_info *afi)
{
  tree rval, rval_binfo = NULL_TREE;
  tree type = NULL_TREE, basetype_path = NULL_TREE;
  struct lookup_field_info lfi;

  /* rval_binfo is the binfo associated with the found member, note,
     this can be set with useful information, even when rval is not
     set, because it must deal with ALL members, not just non-function
     members.  It is used for ambiguity checking and the hidden
     checks.  Whereas rval is only set if a proper (not hidden)
     non-function member is found.  */

  if (name == error_mark_node
      || xbasetype == NULL_TREE
      || xbasetype == error_mark_node)
    return NULL_TREE;

  gcc_assert (identifier_p (name));

  if (TREE_CODE (xbasetype) == TREE_BINFO)
    {
      type = BINFO_TYPE (xbasetype);
      basetype_path = xbasetype;
    }
  else
    {
      if (!RECORD_OR_UNION_CODE_P (TREE_CODE (xbasetype)))
	return NULL_TREE;
      type = xbasetype;
      xbasetype = NULL_TREE;
    }

  type = complete_type (type);

  /* Make sure we're looking for a member of the current instantiation in the
     right partial specialization.  */
  if (dependent_type_p (type))
    if (tree t = currently_open_class (type))
      type = t;

  if (!basetype_path)
    basetype_path = TYPE_BINFO (type);

  if (!basetype_path)
    return NULL_TREE;

  memset (&lfi, 0, sizeof (lfi));
  lfi.type = type;
  lfi.name = name;
  lfi.want_type = want_type;
  dfs_walk_all (basetype_path, &lookup_field_r, NULL, &lfi);
  rval = lfi.rval;
  rval_binfo = lfi.rval_binfo;
  if (rval_binfo)
    type = BINFO_TYPE (rval_binfo);

  if (lfi.ambiguous)
    {
      if (protect == 0)
	return NULL_TREE;
      else if (protect == 1)
	{
	  if (complain & tf_error)
	    {
	      error ("request for member %qD is ambiguous", name);
	      print_candidates (lfi.ambiguous);
	    }
	  return error_mark_node;
	}
      else if (protect == 2)
	return lfi.ambiguous;
    }

  if (!rval)
    return NULL_TREE;

  /* [class.access]

     In the case of overloaded function names, access control is
     applied to the function selected by overloaded resolution.  

     We cannot check here, even if RVAL is only a single non-static
     member function, since we do not know what the "this" pointer
     will be.  For:

        class A { protected: void f(); };
        class B : public A { 
          void g(A *p) {
            f(); // OK
            p->f(); // Not OK.
          }
        };

    only the first call to "f" is valid.  However, if the function is
    static, we can check.  */
  if (protect == 1 && !really_overloaded_fn (rval))
    {
      tree decl = is_overloaded_fn (rval) ? get_first_fn (rval) : rval;
      decl = strip_using_decl (decl);
      /* A dependent USING_DECL will be checked after tsubsting.  */
      if (TREE_CODE (decl) != USING_DECL
	  && !DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
	  && !perform_or_defer_access_check (basetype_path, decl, decl,
					     complain, afi))
	return error_mark_node;
    }

  if (is_overloaded_fn (rval)
      /* Don't use a BASELINK for class-scope deduction guides since
	 they're not actually member functions.  */
      && !dguide_name_p (name))
    rval = build_baselink (rval_binfo, basetype_path, rval,
			   (IDENTIFIER_CONV_OP_P (name)
			   ? TREE_TYPE (name): NULL_TREE));
  return rval;
}

/* Helper class for lookup_member_fuzzy.  */

class lookup_field_fuzzy_info
{
 public:
  lookup_field_fuzzy_info (bool want_type_p) :
    m_want_type_p (want_type_p), m_candidates () {}

  void fuzzy_lookup_field (tree type);

  /* If true, we are looking for types, not data members.  */
  bool m_want_type_p;
  /* The result: a vec of identifiers.  */
  auto_vec<tree> m_candidates;
};

/* Locate all fields within TYPE, append them to m_candidates.  */

void
lookup_field_fuzzy_info::fuzzy_lookup_field (tree type)
{
  if (!CLASS_TYPE_P (type))
    return;

  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      if (m_want_type_p && !DECL_DECLARES_TYPE_P (field))
	continue;

      if (!DECL_NAME (field))
	continue;

      if (is_lambda_ignored_entity (field))
	continue;

      /* Ignore special identifiers with space at the end like cdtor or
	 conversion op identifiers.  */
      if (TREE_CODE (DECL_NAME (field)) == IDENTIFIER_NODE)
	if (unsigned int len = IDENTIFIER_LENGTH (DECL_NAME (field)))
	  if (IDENTIFIER_POINTER (DECL_NAME (field))[len - 1] == ' ')
	    continue;

      m_candidates.safe_push (DECL_NAME (field));
    }
}


/* Helper function for lookup_member_fuzzy, called via dfs_walk_all
   DATA is really a lookup_field_fuzzy_info.  Look for a field with
   the name indicated there in BINFO.  Gathers pertinent identifiers into
   m_candidates.  */

static tree
lookup_field_fuzzy_r (tree binfo, void *data)
{
  lookup_field_fuzzy_info *lffi = (lookup_field_fuzzy_info *) data;
  tree type = BINFO_TYPE (binfo);

  lffi->fuzzy_lookup_field (type);

  return NULL_TREE;
}

/* Like lookup_member, but try to find the closest match for NAME,
   rather than an exact match, and return an identifier (or NULL_TREE).
   Do not complain.  */

tree
lookup_member_fuzzy (tree xbasetype, tree name, bool want_type_p)
{
  tree type = NULL_TREE, basetype_path = NULL_TREE;
  class lookup_field_fuzzy_info lffi (want_type_p);

  /* rval_binfo is the binfo associated with the found member, note,
     this can be set with useful information, even when rval is not
     set, because it must deal with ALL members, not just non-function
     members.  It is used for ambiguity checking and the hidden
     checks.  Whereas rval is only set if a proper (not hidden)
     non-function member is found.  */

  if (name == error_mark_node
      || xbasetype == NULL_TREE
      || xbasetype == error_mark_node)
    return NULL_TREE;

  gcc_assert (identifier_p (name));

  if (TREE_CODE (xbasetype) == TREE_BINFO)
    {
      type = BINFO_TYPE (xbasetype);
      basetype_path = xbasetype;
    }
  else
    {
      if (!RECORD_OR_UNION_CODE_P (TREE_CODE (xbasetype)))
	return NULL_TREE;
      type = xbasetype;
      xbasetype = NULL_TREE;
    }

  type = complete_type (type);

  /* Make sure we're looking for a member of the current instantiation in the
     right partial specialization.  */
  if (flag_concepts && dependent_type_p (type))
    type = currently_open_class (type);

  if (!basetype_path)
    basetype_path = TYPE_BINFO (type);

  if (!basetype_path)
    return NULL_TREE;

  /* Populate lffi.m_candidates.  */
  dfs_walk_all (basetype_path, &lookup_field_fuzzy_r, NULL, &lffi);

  return find_closest_identifier (name, &lffi.m_candidates);
}

/* Like lookup_member, except that if we find a function member we
   return NULL_TREE.  */

tree
lookup_field (tree xbasetype, tree name, int protect, bool want_type)
{
  tree rval = lookup_member (xbasetype, name, protect, want_type,
			     tf_warning_or_error);

  /* Ignore functions, but propagate the ambiguity list.  */
  if (!error_operand_p (rval)
      && (rval && BASELINK_P (rval)))
    return NULL_TREE;

  return rval;
}

/* Like lookup_member, except that if we find a non-function member we
   return NULL_TREE.  */

tree
lookup_fnfields (tree xbasetype, tree name, int protect,
		 tsubst_flags_t complain)
{
  tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false,
			     complain);

  /* Ignore non-functions, but propagate the ambiguity list.  */
  if (!error_operand_p (rval)
      && (rval && !BASELINK_P (rval)))
    return NULL_TREE;

  return rval;
}

/* DECL is the result of a qualified name lookup.  QUALIFYING_SCOPE is
   the class or namespace used to qualify the name.  CONTEXT_CLASS is
   the class corresponding to the object in which DECL will be used.
   Return a possibly modified version of DECL that takes into account
   the CONTEXT_CLASS.

   In particular, consider an expression like `B::m' in the context of
   a derived class `D'.  If `B::m' has been resolved to a BASELINK,
   then the most derived class indicated by the BASELINK_BINFO will be
   `B', not `D'.  This function makes that adjustment.  */

tree
adjust_result_of_qualified_name_lookup (tree decl,
					tree qualifying_scope,
					tree context_class)
{
  if (context_class && context_class != error_mark_node
      && CLASS_TYPE_P (context_class)
      && CLASS_TYPE_P (qualifying_scope)
      && DERIVED_FROM_P (qualifying_scope, context_class)
      && BASELINK_P (decl))
    {
      tree base;

      /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
	 Because we do not yet know which function will be chosen by
	 overload resolution, we cannot yet check either accessibility
	 or ambiguity -- in either case, the choice of a static member
	 function might make the usage valid.  */
      base = lookup_base (context_class, qualifying_scope,
			  ba_unique, NULL, tf_none);
      if (base && base != error_mark_node)
	{
	  BASELINK_ACCESS_BINFO (decl) = base;
	  tree decl_binfo
	    = lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)),
			   ba_unique, NULL, tf_none);
	  if (decl_binfo && decl_binfo != error_mark_node)
	    BASELINK_BINFO (decl) = decl_binfo;
	}
    }

  if (BASELINK_P (decl))
    BASELINK_QUALIFIED_P (decl) = true;

  return decl;
}


/* Walk the class hierarchy within BINFO, in a depth-first traversal.
   PRE_FN is called in preorder, while POST_FN is called in postorder.
   If PRE_FN returns DFS_SKIP_BASES, child binfos will not be
   walked.  If PRE_FN or POST_FN returns a different non-NULL value,
   that value is immediately returned and the walk is terminated.  One
   of PRE_FN and POST_FN can be NULL.  At each node, PRE_FN and
   POST_FN are passed the binfo to examine and the caller's DATA
   value.  All paths are walked, thus virtual and morally virtual
   binfos can be multiply walked.  */

tree
dfs_walk_all (tree binfo, tree (*pre_fn) (tree, void *),
	      tree (*post_fn) (tree, void *), void *data)
{
  tree rval;
  unsigned ix;
  tree base_binfo;

  /* Call the pre-order walking function.  */
  if (pre_fn)
    {
      rval = pre_fn (binfo, data);
      if (rval)
	{
	  if (rval == dfs_skip_bases)
	    goto skip_bases;
	  return rval;
	}
    }

  /* Find the next child binfo to walk.  */
  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    {
      rval = dfs_walk_all (base_binfo, pre_fn, post_fn, data);
      if (rval)
	return rval;
    }

 skip_bases:
  /* Call the post-order walking function.  */
  if (post_fn)
    {
      rval = post_fn (binfo, data);
      gcc_assert (rval != dfs_skip_bases);
      return rval;
    }

  return NULL_TREE;
}

/* Worker for dfs_walk_once.  This behaves as dfs_walk_all, except
   that binfos are walked at most once.  */

static tree
dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
		 tree (*post_fn) (tree, void *), hash_set<tree> *pset,
		 void *data)
{
  tree rval;
  unsigned ix;
  tree base_binfo;

  /* Call the pre-order walking function.  */
  if (pre_fn)
    {
      rval = pre_fn (binfo, data);
      if (rval)
	{
	  if (rval == dfs_skip_bases)
	    goto skip_bases;

	  return rval;
	}
    }

  /* Find the next child binfo to walk.  */
  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    {
      if (BINFO_VIRTUAL_P (base_binfo))
	if (pset->add (base_binfo))
	  continue;

      rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, pset, data);
      if (rval)
	return rval;
    }

 skip_bases:
  /* Call the post-order walking function.  */
  if (post_fn)
    {
      rval = post_fn (binfo, data);
      gcc_assert (rval != dfs_skip_bases);
      return rval;
    }

  return NULL_TREE;
}

/* Like dfs_walk_all, except that binfos are not multiply walked.  For
   non-diamond shaped hierarchies this is the same as dfs_walk_all.
   For diamond shaped hierarchies we must mark the virtual bases, to
   avoid multiple walks.  */

tree
dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
	       tree (*post_fn) (tree, void *), void *data)
{
  static int active = 0;  /* We must not be called recursively. */
  tree rval;

  gcc_assert (pre_fn || post_fn);
  gcc_assert (!active);
  active++;

  if (!CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
    /* We are not diamond shaped, and therefore cannot encounter the
       same binfo twice.  */
    rval = dfs_walk_all (binfo, pre_fn, post_fn, data);
  else
    {
      hash_set<tree> pset;
      rval = dfs_walk_once_r (binfo, pre_fn, post_fn, &pset, data);
    }

  active--;

  return rval;
}

/* Worker function for dfs_walk_once_accessible.  Behaves like
   dfs_walk_once_r, except (a) FRIENDS_P is true if special
   access given by the current context should be considered, (b) ONCE
   indicates whether bases should be marked during traversal.  */

static tree
dfs_walk_once_accessible_r (tree binfo, bool friends_p, hash_set<tree> *pset,
			    tree (*pre_fn) (tree, void *),
			    tree (*post_fn) (tree, void *), void *data)
{
  tree rval = NULL_TREE;
  unsigned ix;
  tree base_binfo;

  /* Call the pre-order walking function.  */
  if (pre_fn)
    {
      rval = pre_fn (binfo, data);
      if (rval)
	{
	  if (rval == dfs_skip_bases)
	    goto skip_bases;

	  return rval;
	}
    }

  /* Find the next child binfo to walk.  */
  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    {
      bool mark = pset && BINFO_VIRTUAL_P (base_binfo);

      if (mark && pset->contains (base_binfo))
	continue;

      /* If the base is inherited via private or protected
	 inheritance, then we can't see it, unless we are a friend of
	 the current binfo.  */
      if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node)
	{
	  tree scope;
	  if (!friends_p)
	    continue;
	  scope = current_scope ();
	  if (!scope
	      || TREE_CODE (scope) == NAMESPACE_DECL
	      || !is_friend (BINFO_TYPE (binfo), scope))
	    continue;
	}

      if (mark)
	pset->add (base_binfo);

      rval = dfs_walk_once_accessible_r (base_binfo, friends_p, pset,
					 pre_fn, post_fn, data);
      if (rval)
	return rval;
    }

 skip_bases:
  /* Call the post-order walking function.  */
  if (post_fn)
    {
      rval = post_fn (binfo, data);
      gcc_assert (rval != dfs_skip_bases);
      return rval;
    }

  return NULL_TREE;
}

/* Like dfs_walk_once except that only accessible bases are walked.
   FRIENDS_P indicates whether friendship of the local context
   should be considered when determining accessibility.  */

static tree
dfs_walk_once_accessible (tree binfo, bool friends_p,
			    tree (*pre_fn) (tree, void *),
			    tree (*post_fn) (tree, void *), void *data)
{
  hash_set<tree> *pset = NULL;
  if (CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
    pset = new hash_set<tree>;
  tree rval = dfs_walk_once_accessible_r (binfo, friends_p, pset,
					  pre_fn, post_fn, data);

  if (pset)
    delete pset;
  return rval;
}

/* Return true iff the code of T is CODE, and it has compatible
   type with TYPE.  */

static bool
matches_code_and_type_p (tree t, enum tree_code code, tree type)
{
  if (TREE_CODE (t) != code)
    return false;
  if (!cxx_types_compatible_p (TREE_TYPE (t), type))
    return false;
  return true;
}

/* Subroutine of direct_accessor_p and reference_accessor_p.
   Determine if COMPONENT_REF is a simple field lookup of this->FIELD_DECL.
   We expect a tree of the form:
	     <component_ref:
	       <indirect_ref:S>
		 <nop_expr:P*
		   <parm_decl (this)>
		 <field_decl (FIELD_DECL)>>>.  */

static bool
field_access_p (tree component_ref, tree field_decl, tree field_type)
{
  if (!matches_code_and_type_p (component_ref, COMPONENT_REF, field_type))
    return false;

  tree indirect_ref = TREE_OPERAND (component_ref, 0);
  if (!INDIRECT_REF_P (indirect_ref))
    return false;

  tree ptr = STRIP_NOPS (TREE_OPERAND (indirect_ref, 0));
  if (!is_this_parameter (ptr))
    return false;

  /* Must access the correct field.  */
  if (TREE_OPERAND (component_ref, 1) != field_decl)
    return false;
  return true;
}

/* Subroutine of field_accessor_p.

   Assuming that INIT_EXPR has already had its code and type checked,
   determine if it is a simple accessor for FIELD_DECL
   (of type FIELD_TYPE).

   Specifically, a simple accessor within struct S of the form:
       T get_field () { return m_field; }
   should have a constexpr_fn_retval (saved_tree) of the form:
	 <init_expr:T
	   <result_decl:T
	   <nop_expr:T
	     <component_ref:
	       <indirect_ref:S>
		 <nop_expr:P*
		   <parm_decl (this)>
		 <field_decl (FIELD_DECL)>>>>>.  */

static bool
direct_accessor_p (tree init_expr, tree field_decl, tree field_type)
{
  tree result_decl = TREE_OPERAND (init_expr, 0);
  if (!matches_code_and_type_p (result_decl, RESULT_DECL, field_type))
    return false;

  tree component_ref = STRIP_NOPS (TREE_OPERAND (init_expr, 1));
  if (!field_access_p (component_ref, field_decl, field_type))
    return false;

  return true;
}

/* Subroutine of field_accessor_p.

   Assuming that INIT_EXPR has already had its code and type checked,
   determine if it is a "reference" accessor for FIELD_DECL
   (of type FIELD_REFERENCE_TYPE).

   Specifically, a simple accessor within struct S of the form:
       T& get_field () { return m_field; }
   should have a constexpr_fn_retval (saved_tree) of the form:
	 <init_expr:T&
	   <result_decl:T&
	   <nop_expr: T&
	     <addr_expr: T*
	       <component_ref:T
		 <indirect_ref:S
		   <nop_expr
		     <parm_decl (this)>>
		   <field (FIELD_DECL)>>>>>>.  */
static bool
reference_accessor_p (tree init_expr, tree field_decl, tree field_type,
		      tree field_reference_type)
{
  tree result_decl = TREE_OPERAND (init_expr, 0);
  if (!matches_code_and_type_p (result_decl, RESULT_DECL, field_reference_type))
    return false;

  tree field_pointer_type = build_pointer_type (field_type);
  tree addr_expr = STRIP_NOPS (TREE_OPERAND (init_expr, 1));
  if (!matches_code_and_type_p (addr_expr, ADDR_EXPR, field_pointer_type))
    return false;

  tree component_ref = STRIP_NOPS (TREE_OPERAND (addr_expr, 0));

  if (!field_access_p (component_ref, field_decl, field_type))
    return false;

  return true;
}

/* Return true if FN is an accessor method for FIELD_DECL.
   i.e. a method of the form { return FIELD; }, with no
   conversions.

   If CONST_P, then additionally require that FN be a const
   method.  */

static bool
field_accessor_p (tree fn, tree field_decl, bool const_p)
{
  if (TREE_CODE (fn) != FUNCTION_DECL)
    return false;

  /* We don't yet support looking up static data, just fields.  */
  if (TREE_CODE (field_decl) != FIELD_DECL)
    return false;

  tree fntype = TREE_TYPE (fn);
  if (TREE_CODE (fntype) != METHOD_TYPE)
    return false;

  /* If the field is accessed via a const "this" argument, verify
     that the "this" parameter is const.  */
  if (const_p)
    {
      tree this_class = class_of_this_parm (fntype);
      if (!TYPE_READONLY (this_class))
	return false;
    }

  tree saved_tree = DECL_SAVED_TREE (fn);

  if (saved_tree == NULL_TREE)
    return false;

  /* Attempt to extract a single return value from the function,
     if it has one.  */
  tree retval = constexpr_fn_retval (saved_tree);
  if (retval == NULL_TREE || retval == error_mark_node)
    return false;
  /* Require an INIT_EXPR.  */
  if (TREE_CODE (retval) != INIT_EXPR)
    return false;
  tree init_expr = retval;

  /* Determine if this is a simple accessor within struct S of the form:
       T get_field () { return m_field; }.  */
  tree field_type = TREE_TYPE (field_decl);
  if (cxx_types_compatible_p (TREE_TYPE (init_expr), field_type))
    return direct_accessor_p (init_expr, field_decl, field_type);

  /* Failing that, determine if it is an accessor of the form:
       T& get_field () { return m_field; }.  */
  tree field_reference_type = cp_build_reference_type (field_type, false);
  if (cxx_types_compatible_p (TREE_TYPE (init_expr), field_reference_type))
    return reference_accessor_p (init_expr, field_decl, field_type,
				 field_reference_type);

  return false;
}

/* Callback data for dfs_locate_field_accessor_pre.  */

class locate_field_data
{
public:
  locate_field_data (tree field_decl_, bool const_p_)
  : field_decl (field_decl_), const_p (const_p_) {}

  tree field_decl;
  bool const_p;
};

/* Return a FUNCTION_DECL that is an "accessor" method for DATA, a FIELD_DECL,
   callable via binfo, if one exists, otherwise return NULL_TREE.

   Callback for dfs_walk_once_accessible for use within
   locate_field_accessor.  */

static tree
dfs_locate_field_accessor_pre (tree binfo, void *data)
{
  locate_field_data *lfd = (locate_field_data *)data;
  tree type = BINFO_TYPE (binfo);

  vec<tree, va_gc> *member_vec;
  tree fn;
  size_t i;

  if (!CLASS_TYPE_P (type))
    return NULL_TREE;

  member_vec = CLASSTYPE_MEMBER_VEC (type);
  if (!member_vec)
    return NULL_TREE;

  for (i = 0; vec_safe_iterate (member_vec, i, &fn); ++i)
    if (fn)
      if (field_accessor_p (fn, lfd->field_decl, lfd->const_p))
	return fn;

  return NULL_TREE;
}

/* Return a FUNCTION_DECL that is an "accessor" method for FIELD_DECL,
   callable via BASETYPE_PATH, if one exists, otherwise return NULL_TREE.  */

tree
locate_field_accessor (tree basetype_path, tree field_decl, bool const_p)
{
  if (TREE_CODE (basetype_path) != TREE_BINFO)
    return NULL_TREE;

  /* Walk the hierarchy, looking for a method of some base class that allows
     access to the field.  */
  locate_field_data lfd (field_decl, const_p);
  return dfs_walk_once_accessible (basetype_path, /*friends=*/true,
				   dfs_locate_field_accessor_pre,
				   NULL, &lfd);
}

/* Check throw specifier of OVERRIDER is at least as strict as
   the one of BASEFN.  */

bool
maybe_check_overriding_exception_spec (tree overrider, tree basefn)
{
  maybe_instantiate_noexcept (basefn);
  maybe_instantiate_noexcept (overrider);
  tree base_throw = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (basefn));
  tree over_throw = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (overrider));

  if (DECL_INVALID_OVERRIDER_P (overrider))
    return true;

  /* Can't check this yet.  Pretend this is fine and let
     noexcept_override_late_checks check this later.  */
  if (UNPARSED_NOEXCEPT_SPEC_P (base_throw)
      || UNPARSED_NOEXCEPT_SPEC_P (over_throw))
    return true;

  if (!comp_except_specs (base_throw, over_throw, ce_derived))
    {
      auto_diagnostic_group d;
      error ("looser exception specification on overriding virtual function "
	     "%q+#F", overrider);
      inform (DECL_SOURCE_LOCATION (basefn),
	      "overridden function is %q#F", basefn);
      DECL_INVALID_OVERRIDER_P (overrider) = 1;
      return false;
    }
  return true;
}

/* Check that virtual overrider OVERRIDER is acceptable for base function
   BASEFN. Issue diagnostic, and return zero, if unacceptable.  */

static int
check_final_overrider (tree overrider, tree basefn)
{
  tree over_type = TREE_TYPE (overrider);
  tree base_type = TREE_TYPE (basefn);
  tree over_return = fndecl_declared_return_type (overrider);
  tree base_return = fndecl_declared_return_type (basefn);

  int fail = 0;

  if (DECL_INVALID_OVERRIDER_P (overrider))
    return 0;

  if (same_type_p (base_return, over_return))
    /* OK */;
  else if ((CLASS_TYPE_P (over_return) && CLASS_TYPE_P (base_return))
	   || (TREE_CODE (base_return) == TREE_CODE (over_return)
	       && INDIRECT_TYPE_P (base_return)))
    {
      /* Potentially covariant.  */
      unsigned base_quals, over_quals;

      fail = !INDIRECT_TYPE_P (base_return);
      if (!fail)
	{
	  if (cp_type_quals (base_return) != cp_type_quals (over_return))
	    fail = 1;

	  if (TYPE_REF_P (base_return)
	      && (TYPE_REF_IS_RVALUE (base_return)
		  != TYPE_REF_IS_RVALUE (over_return)))
	    fail = 1;

	  base_return = TREE_TYPE (base_return);
	  over_return = TREE_TYPE (over_return);
	}
      base_quals = cp_type_quals (base_return);
      over_quals = cp_type_quals (over_return);

      if ((base_quals & over_quals) != over_quals)
	fail = 1;

      if (CLASS_TYPE_P (base_return) && CLASS_TYPE_P (over_return))
	{
	  /* Strictly speaking, the standard requires the return type to be
	     complete even if it only differs in cv-quals, but that seems
	     like a bug in the wording.  */
	  if (!same_type_ignoring_top_level_qualifiers_p (base_return,
							  over_return))
	    {
	      tree binfo = lookup_base (over_return, base_return,
					ba_check, NULL, tf_none);

	      if (!binfo || binfo == error_mark_node)
		fail = 1;
	    }
	}
      else if (can_convert_standard (TREE_TYPE (base_type),
				     TREE_TYPE (over_type),
				     tf_warning_or_error))
	/* GNU extension, allow trivial pointer conversions such as
	   converting to void *, or qualification conversion.  */
	{
	  auto_diagnostic_group d;
	  if (pedwarn (DECL_SOURCE_LOCATION (overrider), 0,
		       "invalid covariant return type for %q#D", overrider))
	    inform (DECL_SOURCE_LOCATION (basefn),
		    "overridden function is %q#D", basefn);
	}
      else
	fail = 2;
    }
  else
    fail = 2;
  if (!fail)
    /* OK */;
  else
    {
      auto_diagnostic_group d;
      if (fail == 1)
	error ("invalid covariant return type for %q+#D", overrider);
      else
	error ("conflicting return type specified for %q+#D", overrider);
      inform (DECL_SOURCE_LOCATION (basefn),
	      "overridden function is %q#D", basefn);
      DECL_INVALID_OVERRIDER_P (overrider) = 1;
      return 0;
    }

  if (!maybe_check_overriding_exception_spec (overrider, basefn))
    return 0;

  /* Check for conflicting type attributes.  But leave transaction_safe for
     set_one_vmethod_tm_attributes.  */
  if (!comp_type_attributes (over_type, base_type)
      && !tx_safe_fn_type_p (base_type)
      && !tx_safe_fn_type_p (over_type))
    {
      auto_diagnostic_group d;
      error ("conflicting type attributes specified for %q+#D", overrider);
      inform (DECL_SOURCE_LOCATION (basefn),
	      "overridden function is %q#D", basefn);
      DECL_INVALID_OVERRIDER_P (overrider) = 1;
      return 0;
    }

  /* A consteval virtual function shall not override a virtual function that is
     not consteval. A consteval virtual function shall not be overridden by a
     virtual function that is not consteval.  */
  if (DECL_IMMEDIATE_FUNCTION_P (overrider)
      != DECL_IMMEDIATE_FUNCTION_P (basefn))
    {
      auto_diagnostic_group d;
      if (DECL_IMMEDIATE_FUNCTION_P (overrider))
	error ("%<consteval%> function %q+D overriding non-%<consteval%> "
	       "function", overrider);
      else
	error ("non-%<consteval%> function %q+D overriding %<consteval%> "
	       "function", overrider);
      inform (DECL_SOURCE_LOCATION (basefn),
	      "overridden function is %qD", basefn);
      DECL_INVALID_OVERRIDER_P (overrider) = 1;
      return 0;
    }

  /* A function declared transaction_safe_dynamic that overrides a function
     declared transaction_safe (but not transaction_safe_dynamic) is
     ill-formed.  */
  if (tx_safe_fn_type_p (base_type)
      && lookup_attribute ("transaction_safe_dynamic",
			   DECL_ATTRIBUTES (overrider))
      && !lookup_attribute ("transaction_safe_dynamic",
			    DECL_ATTRIBUTES (basefn)))
    {
      auto_diagnostic_group d;
      error_at (DECL_SOURCE_LOCATION (overrider),
		"%qD declared %<transaction_safe_dynamic%>", overrider);
      inform (DECL_SOURCE_LOCATION (basefn),
	      "overriding %qD declared %<transaction_safe%>", basefn);
    }

  if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider))
    {
      if (DECL_DELETED_FN (overrider))
	{
	  auto_diagnostic_group d;
	  error ("deleted function %q+D overriding non-deleted function",
		 overrider);
	  inform (DECL_SOURCE_LOCATION (basefn),
		  "overridden function is %qD", basefn);
	  maybe_explain_implicit_delete (overrider);
	}
      else
	{
	  auto_diagnostic_group d;
	  error ("non-deleted function %q+D overriding deleted function",
		 overrider);
	  inform (DECL_SOURCE_LOCATION (basefn),
		  "overridden function is %qD", basefn);
	}
      return 0;
    }
  if (DECL_FINAL_P (basefn))
    {
      auto_diagnostic_group d;
      error ("virtual function %q+D overriding final function", overrider);
      inform (DECL_SOURCE_LOCATION (basefn),
	      "overridden function is %qD", basefn);
      return 0;
    }
  return 1;
}

/* Given a class TYPE, and a function decl FNDECL, look for
   virtual functions in TYPE's hierarchy which FNDECL overrides.
   We do not look in TYPE itself, only its bases.

   Returns nonzero, if we find any. Set FNDECL's DECL_VIRTUAL_P, if we
   find that it overrides anything.

   We check that every function which is overridden, is correctly
   overridden.  */

int
look_for_overrides (tree type, tree fndecl)
{
  tree binfo = TYPE_BINFO (type);
  tree base_binfo;
  int ix;
  int found = 0;

  /* A constructor for a class T does not override a function T
     in a base class.  */
  if (DECL_CONSTRUCTOR_P (fndecl))
    return 0;

  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
    {
      tree basetype = BINFO_TYPE (base_binfo);

      if (TYPE_POLYMORPHIC_P (basetype))
	found += look_for_overrides_r (basetype, fndecl);
    }
  return found;
}

/* Look in TYPE for virtual functions with the same signature as
   FNDECL.  */

tree
look_for_overrides_here (tree type, tree fndecl)
{
  tree ovl = get_class_binding (type, DECL_NAME (fndecl));

  for (ovl_iterator iter (ovl); iter; ++iter)
    {
      tree fn = *iter;

      if (!DECL_VIRTUAL_P (fn))
	/* Not a virtual.  */;
      else if (DECL_CONTEXT (fn) != type)
	/* Introduced with a using declaration.  */;
      else if (DECL_STATIC_FUNCTION_P (fndecl))
	{
	  tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
	  tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
	  if (compparms (TREE_CHAIN (btypes), dtypes))
	    return fn;
	}
      else if (same_signature_p (fndecl, fn))
	return fn;
    }

  return NULL_TREE;
}

/* Look in TYPE for virtual functions overridden by FNDECL. Check both
   TYPE itself and its bases.  */

static int
look_for_overrides_r (tree type, tree fndecl)
{
  tree fn = look_for_overrides_here (type, fndecl);
  if (fn)
    {
      if (DECL_STATIC_FUNCTION_P (fndecl))
	{
	  /* A static member function cannot match an inherited
	     virtual member function.  */
	  auto_diagnostic_group d;
	  error ("%q+#D cannot be declared", fndecl);
	  error ("  since %q+#D declared in base class", fn);
	}
      else
	{
	  /* It's definitely virtual, even if not explicitly set.  */
	  DECL_VIRTUAL_P (fndecl) = 1;
	  check_final_overrider (fndecl, fn);
	}
      return 1;
    }

  /* We failed to find one declared in this class. Look in its bases.  */
  return look_for_overrides (type, fndecl);
}

/* Called via dfs_walk from dfs_get_pure_virtuals.  */

static tree
dfs_get_pure_virtuals (tree binfo, void *data)
{
  tree type = (tree) data;

  /* We're not interested in primary base classes; the derived class
     of which they are a primary base will contain the information we
     need.  */
  if (!BINFO_PRIMARY_P (binfo))
    {
      tree virtuals;

      for (virtuals = BINFO_VIRTUALS (binfo);
	   virtuals;
	   virtuals = TREE_CHAIN (virtuals))
	if (DECL_PURE_VIRTUAL_P (BV_FN (virtuals)))
	  vec_safe_push (CLASSTYPE_PURE_VIRTUALS (type), BV_FN (virtuals));
    }

  return NULL_TREE;
}

/* Set CLASSTYPE_PURE_VIRTUALS for TYPE.  */

void
get_pure_virtuals (tree type)
{
  /* Clear the CLASSTYPE_PURE_VIRTUALS list; whatever is already there
     is going to be overridden.  */
  CLASSTYPE_PURE_VIRTUALS (type) = NULL;
  /* Now, run through all the bases which are not primary bases, and
     collect the pure virtual functions.  We look at the vtable in
     each class to determine what pure virtual functions are present.
     (A primary base is not interesting because the derived class of
     which it is a primary base will contain vtable entries for the
     pure virtuals in the base class.  */
  dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type);
}

/* Debug info for C++ classes can get very large; try to avoid
   emitting it everywhere.

   Note that this optimization wins even when the target supports
   BINCL (if only slightly), and reduces the amount of work for the
   linker.  */

void
maybe_suppress_debug_info (tree t)
{
  if (write_symbols == NO_DEBUG)
    return;

  /* We might have set this earlier in cp_finish_decl.  */
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 0;

  /* Always emit the information for each class every time. */
  if (flag_emit_class_debug_always)
    return;

  /* If we already know how we're handling this class, handle debug info
     the same way.  */
  if (CLASSTYPE_INTERFACE_KNOWN (t))
    {
      if (CLASSTYPE_INTERFACE_ONLY (t))
	TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
      /* else don't set it.  */
    }
  /* If the class has a vtable, write out the debug info along with
     the vtable.  */
  else if (TYPE_CONTAINS_VPTR_P (t))
    TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;

  /* Otherwise, just emit the debug info normally.  */
}

/* Note that we want debugging information for a base class of a class
   whose vtable is being emitted.  Normally, this would happen because
   calling the constructor for a derived class implies calling the
   constructors for all bases, which involve initializing the
   appropriate vptr with the vtable for the base class; but in the
   presence of optimization, this initialization may be optimized
   away, so we tell finish_vtable_vardecl that we want the debugging
   information anyway.  */

static tree
dfs_debug_mark (tree binfo, void * /*data*/)
{
  tree t = BINFO_TYPE (binfo);

  if (CLASSTYPE_DEBUG_REQUESTED (t))
    return dfs_skip_bases;

  CLASSTYPE_DEBUG_REQUESTED (t) = 1;

  return NULL_TREE;
}

/* Write out the debugging information for TYPE, whose vtable is being
   emitted.  Also walk through our bases and note that we want to
   write out information for them.  This avoids the problem of not
   writing any debug info for intermediate basetypes whose
   constructors, and thus the references to their vtables, and thus
   the vtables themselves, were optimized away.  */

void
note_debug_info_needed (tree type)
{
  if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)))
    {
      TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)) = 0;
      rest_of_type_compilation (type, namespace_bindings_p ());
    }

  dfs_walk_all (TYPE_BINFO (type), dfs_debug_mark, NULL, 0);
}

/* Helper for lookup_conversions_r.  TO_TYPE is the type converted to
   by a conversion op in base BINFO.  VIRTUAL_DEPTH is nonzero if
   BINFO is morally virtual, and VIRTUALNESS is nonzero if virtual
   bases have been encountered already in the tree walk.  PARENT_CONVS
   is the list of lists of conversion functions that could hide CONV
   and OTHER_CONVS is the list of lists of conversion functions that
   could hide or be hidden by CONV, should virtualness be involved in
   the hierarchy.  Merely checking the conversion op's name is not
   enough because two conversion operators to the same type can have
   different names.  Return nonzero if we are visible.  */

static int
check_hidden_convs (tree binfo, int virtual_depth, int virtualness,
		    tree to_type, tree parent_convs, tree other_convs)
{
  tree level, probe;

  /* See if we are hidden by a parent conversion.  */
  for (level = parent_convs; level; level = TREE_CHAIN (level))
    for (probe = TREE_VALUE (level); probe; probe = TREE_CHAIN (probe))
      if (same_type_p (to_type, TREE_TYPE (probe)))
	return 0;

  if (virtual_depth || virtualness)
    {
     /* In a virtual hierarchy, we could be hidden, or could hide a
	conversion function on the other_convs list.  */
      for (level = other_convs; level; level = TREE_CHAIN (level))
	{
	  int we_hide_them;
	  int they_hide_us;
	  tree *prev, other;

	  if (!(virtual_depth || TREE_STATIC (level)))
	    /* Neither is morally virtual, so cannot hide each other.  */
	    continue;

	  if (!TREE_VALUE (level))
	    /* They evaporated away already.  */
	    continue;

	  they_hide_us = (virtual_depth
			  && original_binfo (binfo, TREE_PURPOSE (level)));
	  we_hide_them = (!they_hide_us && TREE_STATIC (level)
			  && original_binfo (TREE_PURPOSE (level), binfo));

	  if (!(we_hide_them || they_hide_us))
	    /* Neither is within the other, so no hiding can occur.  */
	    continue;

	  for (prev = &TREE_VALUE (level), other = *prev; other;)
	    {
	      if (same_type_p (to_type, TREE_TYPE (other)))
		{
		  if (they_hide_us)
		    /* We are hidden.  */
		    return 0;

		  if (we_hide_them)
		    {
		      /* We hide the other one.  */
		      other = TREE_CHAIN (other);
		      *prev = other;
		      continue;
		    }
		}
	      prev = &TREE_CHAIN (other);
	      other = *prev;
	    }
	}
    }
  return 1;
}

/* Helper for lookup_conversions_r.  PARENT_CONVS is a list of lists
   of conversion functions, the first slot will be for the current
   binfo, if MY_CONVS is non-NULL.  CHILD_CONVS is the list of lists
   of conversion functions from children of the current binfo,
   concatenated with conversions from elsewhere in the hierarchy --
   that list begins with OTHER_CONVS.  Return a single list of lists
   containing only conversions from the current binfo and its
   children.  */

static tree
split_conversions (tree my_convs, tree parent_convs,
		   tree child_convs, tree other_convs)
{
  tree t;
  tree prev;

  /* Remove the original other_convs portion from child_convs.  */
  for (prev = NULL, t = child_convs;
       t != other_convs; prev = t, t = TREE_CHAIN (t))
    continue;

  if (prev)
    TREE_CHAIN (prev) = NULL_TREE;
  else
    child_convs = NULL_TREE;

  /* Attach the child convs to any we had at this level.  */
  if (my_convs)
    {
      my_convs = parent_convs;
      TREE_CHAIN (my_convs) = child_convs;
    }
  else
    my_convs = child_convs;

  return my_convs;
}

/* Worker for lookup_conversions.  Lookup conversion functions in
   BINFO and its children.  VIRTUAL_DEPTH is nonzero, if BINFO is in a
   morally virtual base, and VIRTUALNESS is nonzero, if we've
   encountered virtual bases already in the tree walk.  PARENT_CONVS
   is a list of conversions within parent binfos.  OTHER_CONVS are
   conversions found elsewhere in the tree.  Return the conversions
   found within this portion of the graph in CONVS.  Return nonzero if
   we encountered virtualness.  We keep template and non-template
   conversions separate, to avoid unnecessary type comparisons.

   The located conversion functions are held in lists of lists.  The
   TREE_VALUE of the outer list is the list of conversion functions
   found in a particular binfo.  The TREE_PURPOSE of both the outer
   and inner lists is the binfo at which those conversions were
   found.  TREE_STATIC is set for those lists within of morally
   virtual binfos.  The TREE_VALUE of the inner list is the conversion
   function or overload itself.  The TREE_TYPE of each inner list node
   is the converted-to type.  */

static int
lookup_conversions_r (tree binfo, int virtual_depth, int virtualness,
		      tree parent_convs, tree other_convs, tree *convs)
{
  int my_virtualness = 0;
  tree my_convs = NULL_TREE;
  tree child_convs = NULL_TREE;

  /* If we have no conversion operators, then don't look.  */
  if (!TYPE_HAS_CONVERSION (BINFO_TYPE (binfo)))
    {
      *convs = NULL_TREE;

      return 0;
    }

  if (BINFO_VIRTUAL_P (binfo))
    virtual_depth++;

  /* First, locate the unhidden ones at this level.  */
  if (tree conv = get_class_binding (BINFO_TYPE (binfo), conv_op_identifier))
  for (ovl_iterator iter (conv); iter; ++iter)
    {
      tree fn = *iter;
      tree type = DECL_CONV_FN_TYPE (fn);

      if (TREE_CODE (fn) != TEMPLATE_DECL && type_uses_auto (type))
	{
	  mark_used (fn);
	  type = DECL_CONV_FN_TYPE (fn);
	}

      if (check_hidden_convs (binfo, virtual_depth, virtualness,
			      type, parent_convs, other_convs))
	{
	  my_convs = tree_cons (binfo, fn, my_convs);
	  TREE_TYPE (my_convs) = type;
	  if (virtual_depth)
	    {
	      TREE_STATIC (my_convs) = 1;
	      my_virtualness = 1;
	    }
	}
    }

  if (my_convs)
    {
      parent_convs = tree_cons (binfo, my_convs, parent_convs);
      if (virtual_depth)
	TREE_STATIC (parent_convs) = 1;
    }

  child_convs = other_convs;

  /* Now iterate over each base, looking for more conversions.  */
  unsigned i;
  tree base_binfo;
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    {
      tree base_convs;
      unsigned base_virtualness;

      base_virtualness = lookup_conversions_r (base_binfo,
					       virtual_depth, virtualness,
					       parent_convs, child_convs,
					       &base_convs);
      if (base_virtualness)
	my_virtualness = virtualness = 1;
      child_convs = chainon (base_convs, child_convs);
    }

  *convs = split_conversions (my_convs, parent_convs,
			      child_convs, other_convs);

  return my_virtualness;
}

/* Return a TREE_LIST containing all the non-hidden user-defined
   conversion functions for TYPE (and its base-classes).  The
   TREE_VALUE of each node is the FUNCTION_DECL of the conversion
   function.  The TREE_PURPOSE is the BINFO from which the conversion
   functions in this node were selected.  This function is effectively
   performing a set of member lookups as lookup_fnfield does, but
   using the type being converted to as the unique key, rather than the
   field name.  */

tree
lookup_conversions (tree type)
{
  tree convs;

  complete_type (type);
  if (!CLASS_TYPE_P (type) || !TYPE_BINFO (type))
    return NULL_TREE;

  lookup_conversions_r (TYPE_BINFO (type), 0, 0, NULL_TREE, NULL_TREE, &convs);

  tree list = NULL_TREE;
  
  /* Flatten the list-of-lists */
  for (; convs; convs = TREE_CHAIN (convs))
    {
      tree probe, next;

      for (probe = TREE_VALUE (convs); probe; probe = next)
	{
	  next = TREE_CHAIN (probe);

	  TREE_CHAIN (probe) = list;
	  list = probe;
	}
    }

  return list;
}

/* Returns the binfo of the first direct or indirect virtual base derived
   from BINFO, or NULL if binfo is not via virtual.  */

tree
binfo_from_vbase (tree binfo)
{
  for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
    {
      if (BINFO_VIRTUAL_P (binfo))
	return binfo;
    }
  return NULL_TREE;
}

/* Returns the binfo of the first direct or indirect virtual base derived
   from BINFO up to the TREE_TYPE, LIMIT, or NULL if binfo is not
   via virtual.  */

tree
binfo_via_virtual (tree binfo, tree limit)
{
  if (limit && !CLASSTYPE_VBASECLASSES (limit))
    /* LIMIT has no virtual bases, so BINFO cannot be via one.  */
    return NULL_TREE;

  for (; binfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), limit);
       binfo = BINFO_INHERITANCE_CHAIN (binfo))
    {
      if (BINFO_VIRTUAL_P (binfo))
	return binfo;
    }
  return NULL_TREE;
}

/* BINFO is for a base class in some hierarchy.  Return true iff it is a
   direct base.  */

bool
binfo_direct_p (tree binfo)
{
  tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
  if (BINFO_INHERITANCE_CHAIN (d_binfo))
    /* A second inheritance chain means indirect.  */
    return false;
  if (!BINFO_VIRTUAL_P (binfo))
    /* Non-virtual, so only one inheritance chain means direct.  */
    return true;
  /* A virtual base looks like a direct base, so we need to look through the
     direct bases to see if it's there.  */
  tree b_binfo;
  for (int i = 0; BINFO_BASE_ITERATE (d_binfo, i, b_binfo); ++i)
    if (b_binfo == binfo)
      return true;
  return false;
}

/* BINFO is a base binfo in the complete type BINFO_TYPE (HERE).
   Find the equivalent binfo within whatever graph HERE is located.
   This is the inverse of original_binfo.  */

tree
copied_binfo (tree binfo, tree here)
{
  tree result = NULL_TREE;

  if (BINFO_VIRTUAL_P (binfo))
    {
      tree t;

      for (t = here; BINFO_INHERITANCE_CHAIN (t);
	   t = BINFO_INHERITANCE_CHAIN (t))
	continue;

      result = binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (t));
    }
  else if (BINFO_INHERITANCE_CHAIN (binfo))
    {
      tree cbinfo;
      tree base_binfo;
      int ix;

      cbinfo = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
      for (ix = 0; BINFO_BASE_ITERATE (cbinfo, ix, base_binfo); ix++)
	if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)))
	  {
	    result = base_binfo;
	    break;
	  }
    }
  else
    {
      gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (here), BINFO_TYPE (binfo)));
      result = here;
    }

  gcc_assert (result);
  return result;
}

tree
binfo_for_vbase (tree base, tree t)
{
  unsigned ix;
  tree binfo;
  vec<tree, va_gc> *vbases;

  for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
       vec_safe_iterate (vbases, ix, &binfo); ix++)
    if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), base))
      return binfo;
  return NULL;
}

/* BINFO is some base binfo of HERE, within some other
   hierarchy. Return the equivalent binfo, but in the hierarchy
   dominated by HERE.  This is the inverse of copied_binfo.  If BINFO
   is not a base binfo of HERE, returns NULL_TREE.  */

tree
original_binfo (tree binfo, tree here)
{
  tree result = NULL;

  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (here)))
    result = here;
  else if (BINFO_VIRTUAL_P (binfo))
    result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))
	      ? binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (here))
	      : NULL_TREE);
  else if (BINFO_INHERITANCE_CHAIN (binfo))
    {
      tree base_binfos;

      base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
      if (base_binfos)
	{
	  int ix;
	  tree base_binfo;

	  for (ix = 0; (base_binfo = BINFO_BASE_BINFO (base_binfos, ix)); ix++)
	    if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
				   BINFO_TYPE (binfo)))
	      {
		result = base_binfo;
		break;
	      }
	}
    }

  return result;
}

/* True iff TYPE has any dependent bases (and therefore we can't say
   definitively that another class is not a base of an instantiation of
   TYPE).  */

bool
any_dependent_bases_p (tree type)
{
  if (!type || !CLASS_TYPE_P (type) || !uses_template_parms (type))
    return false;

  /* If we haven't set TYPE_BINFO yet, we don't know anything about the bases.
     Return false because in this situation we aren't actually looking up names
     in the scope of the class, so it doesn't matter whether it has dependent
     bases.  */
  if (!TYPE_BINFO (type))
    return false;

  unsigned i;
  tree base_binfo;
  FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo)
    if (BINFO_DEPENDENT_BASE_P (base_binfo))
      return true;

  return false;
}
