FreeBSD/contrib/gcc/cp/class.c
/* Recursively build the VTT-initializer for BINFO (which is in the
   hierarchy dominated by T).  INITS points to the end of the initializer
   list to date.  INDEX is the VTT index where the next element will be
   replaced.  Iff BINFO is the binfo for T, this is the top level VTT (i.e.
   not a subvtt for some base of T).  When that is so, we emit the sub-VTTs
   for virtual bases of T. When it is not so, we build the constructor
   vtables for the BINFO-in-T variant.  */
Recursively build the VTT-initializer for BINFO (which is in the
hierarchy dominated by T).  INITS points to the end of the initializer
list to date.  INDEX is the VTT index where the next element will be
replaced.  Iff BINFO is the binfo for T, this is the top level VTT .  When that is so, we emit the sub-VTTs
for virtual bases of T. When it is not so, we build the constructor
vtables for the BINFO-in-T variant.
Recursively build the VTT - initializer for BINFO ( which is in the hierarchy dominated by T ) . INITS points to the end of the initializer list to date . INDEX is the VTT index where the next element will be replaced . Iff BINFO is the binfo for T this is the top level VTT . When that is so we emit the sub - VTTs for virtual bases of T . When it is not so we build the constructor vtables for the BINFO - in - T variant .
static tree *
build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
{
  int i;
  tree b;
  tree init;
  tree secondary_vptrs;
  secondary_vptr_vtt_init_data data;
  int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
  if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
    return inits;
  if (!top_level_p)
    {
      build_ctor_vtbl_group (binfo, t);
      BINFO_SUBVTT_INDEX (binfo) = *index;
    }
  init = binfo_ctor_vtable (binfo);
  *inits = build_tree_list (NULL_TREE, init);
  inits = &TREE_CHAIN (*inits);
  if (top_level_p)
    {
      gcc_assert (!BINFO_VPTR_INDEX (binfo));
      BINFO_VPTR_INDEX (binfo) = *index;
    }
  *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
    if (!BINFO_VIRTUAL_P (b))
      inits = build_vtt_inits (b, t, inits, index);
  data.top_level_p = top_level_p;
  data.index = *index;
  data.inits = NULL;
  data.type_being_constructed = BINFO_TYPE (binfo);
  dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);
  *index = data.index;
  secondary_vptrs = data.inits;
  if (secondary_vptrs)
    {
      *inits = nreverse (secondary_vptrs);
      inits = &TREE_CHAIN (secondary_vptrs);
      gcc_assert (*inits == NULL_TREE);
    }
  if (top_level_p)
    for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
      {
	if (!BINFO_VIRTUAL_P (b))
	  continue;
	inits = build_vtt_inits (b, t, inits, index);
      }
  else
    dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
  return inits;
}
static tree * build_vtt_inits ( tree binfo , tree t , tree * inits , tree * index ) { int i ; tree b ; tree init ; tree secondary_vptrs ; secondary_vptr_vtt_init_data data ; int top_level_p = SAME_BINFO_TYPE_P ( BINFO_TYPE ( binfo ) , t ) ; if ( ! CLASSTYPE_VBASECLASSES ( BINFO_TYPE ( binfo ) ) ) return inits ; if ( ! top_level_p ) { build_ctor_vtbl_group ( binfo , t ) ; BINFO_SUBVTT_INDEX ( binfo ) = * index ; } init = binfo_ctor_vtable ( binfo ) ; * inits = build_tree_list ( NULL_TREE , init ) ; inits = & TREE_CHAIN ( * inits ) ; if ( top_level_p ) { gcc_assert ( ! BINFO_VPTR_INDEX ( binfo ) ) ; BINFO_VPTR_INDEX ( binfo ) = * index ; } * index = size_binop ( PLUS_EXPR , * index , TYPE_SIZE_UNIT ( ptr_type_node ) ) ; for ( i = 0 ; BINFO_BASE_ITERATE ( binfo , i , b ) ; ++ i ) if ( ! BINFO_VIRTUAL_P ( b ) ) inits = build_vtt_inits ( b , t , inits , index ) ; data . top_level_p = top_level_p ; data . index = * index ; data . inits = NULL ; data . type_being_constructed = BINFO_TYPE ( binfo ) ; dfs_walk_once ( binfo , dfs_build_secondary_vptr_vtt_inits , NULL , & data ) ; * index = data . index ; secondary_vptrs = data . inits ; if ( secondary_vptrs ) { * inits = nreverse ( secondary_vptrs ) ; inits = & TREE_CHAIN ( secondary_vptrs ) ; gcc_assert ( * inits == NULL_TREE ) ; } if ( top_level_p ) for ( b = TYPE_BINFO ( BINFO_TYPE ( binfo ) ) ; b ; b = TREE_CHAIN ( b ) ) { if ( ! BINFO_VIRTUAL_P ( b ) ) continue ; inits = build_vtt_inits ( b , t , inits , index ) ; } else dfs_walk_all ( binfo , dfs_fixup_binfo_vtbls , NULL , binfo ) ; return inits ; }
Recursively build the VTT-initializer for BINFO (which is in the
hierarchy dominated by T).
Recursively build the VTT - initializer for BINFO ( which is in the hierarchy dominated by T ) .
/* We only need VTTs for subobjects with virtual bases.  */ /* We need to use a construction vtable if this is not the primary
     VTT.  */ /* Record the offset in the VTT where this sub-VTT can be found.  */ /* Add the address of the primary vtable for the complete object.  */ /* Recursively add the secondary VTTs for non-virtual bases.  */ /* Add secondary virtual pointers for all subobjects of BINFO with
     either virtual bases or reachable along a virtual path, except
     subobjects that are non-virtual primary bases.  */ /* The secondary vptrs come back in reverse order.  After we reverse
     them, and add the INITS, the last init will be the first element
     of the chain.  */ /* Add the secondary VTTs for virtual bases in inheritance graph
       order.  */ /* Remove the ctor vtables we created.  */