contrib/gcc-4.7/gcc/cp/class.c
/* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
   FN and whose TREE_VALUE is the binfo for the base where the
   overriding occurs.  BINFO (in the hierarchy dominated by the binfo
   DERIVED) is the base object in which FN is declared.  */
Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
FN and whose TREE_VALUE is the binfo for the base where the
overriding occurs.  BINFO (in the hierarchy dominated by the binfo
DERIVED) is the base object in which FN is declared.
Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for FN and whose TREE_VALUE is the binfo for the base where the overriding occurs . BINFO ( in the hierarchy dominated by the binfo DERIVED ) is the base object in which FN is declared .
static tree
find_final_overrider (tree derived, tree binfo, tree fn)
{
  find_final_overrider_data ffod;
  if (DECL_THUNK_P (fn))
    fn = THUNK_TARGET (fn);
  ffod.fn = fn;
  ffod.declaring_base = binfo;
  ffod.candidates = NULL_TREE;
  ffod.path = VEC_alloc (tree, heap, 30);
  dfs_walk_all (derived, dfs_find_final_overrider_pre,
		dfs_find_final_overrider_post, &ffod);
  VEC_free (tree, heap, ffod.path);
  if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
    return error_mark_node;
  return ffod.candidates;
}
static tree find_final_overrider ( tree derived , tree binfo , tree fn ) { find_final_overrider_data ffod ; if ( DECL_THUNK_P ( fn ) ) fn = THUNK_TARGET ( fn ) ; ffod . fn = fn ; ffod . declaring_base = binfo ; ffod . candidates = NULL_TREE ; ffod . path = VEC_alloc ( tree , heap , 30 ) ; dfs_walk_all ( derived , dfs_find_final_overrider_pre , dfs_find_final_overrider_post , & ffod ) ; VEC_free ( tree , heap , ffod . path ) ; if ( ! ffod . candidates || TREE_CHAIN ( ffod . candidates ) ) return error_mark_node ; return ffod . candidates ; }
Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
FN and whose TREE_VALUE is the binfo for the base where the
overriding occurs.
Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for FN and whose TREE_VALUE is the binfo for the base where the overriding occurs .
/* Getting this right is a little tricky.  This is valid:

       struct S { virtual void f (); };
       struct T { virtual void f (); };
       struct U : public S, public T { };

     even though calling `f' in `U' is ambiguous.  But,

       struct R { virtual void f(); };
       struct S : virtual public R { virtual void f (); };
       struct T : virtual public R { virtual void f (); };
       struct U : public S, public T { };

     is not -- there's no way to decide whether to put `S::f' or
     `T::f' in the vtable for `R'.

     The solution is to look at all paths to BINFO.  If we find
     different overriders along any two, then there is a problem.  */ /* Determine the depth of the hierarchy.  */ /* If there was no winner, issue an error message.  */