/* 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.  Checking this is necessary only when the class
	 is dependent, for otherwise add_friend will already have added the
	 class to SCOPE's DECL_BEFRIENDING_CLASSES.  */
      if (tree fctx = DECL_FRIEND_CONTEXT (scope))
	if (dependent_type_p (fctx)
	    && protected_accessible_p (decl, fctx, 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;
}
