FreeBSD/contrib/gcc/cp/class.c
/* Add a vcall offset entry for ORIG_FN to the vtable.  */
Add a vcall offset entry for ORIG_FN to the vtable.
Add a vcall offset entry for ORIG_FN to the vtable .
static void
add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
{
  size_t i;
  tree vcall_offset;
  tree derived_entry;
  for (i = 0; VEC_iterate (tree, vid->fns, i, derived_entry); ++i)
    {
      if (same_signature_p (derived_entry, orig_fn)
	  || (DECL_DESTRUCTOR_P (derived_entry)
	      && DECL_DESTRUCTOR_P (orig_fn)))
	return;
    }
  if (vid->binfo == TYPE_BINFO (vid->derived))
    {
      tree_pair_p elt = VEC_safe_push (tree_pair_s, gc,
				       CLASSTYPE_VCALL_INDICES (vid->derived),
				       NULL);
      elt->purpose = orig_fn;
      elt->value = vid->index;
    }
  vid->index = size_binop (MINUS_EXPR, vid->index,
			   ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
  VEC_safe_push (tree, gc, vid->fns, orig_fn);
  if (vid->generate_vcall_entries)
    {
      tree base;
      tree fn;
      fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn);
      if (fn == error_mark_node)
	vcall_offset = build1 (NOP_EXPR, vtable_entry_type,
			       integer_zero_node);
      else
	{
	  base = TREE_VALUE (fn);
	  vcall_offset = size_diffop (BINFO_OFFSET (base),
				      BINFO_OFFSET (vid->binfo));
	  vcall_offset = fold_build1 (NOP_EXPR, vtable_entry_type,
				      vcall_offset);
	}
      *vid->last_init = build_tree_list (NULL_TREE, vcall_offset);
      vid->last_init = &TREE_CHAIN (*vid->last_init);
    }
}
static void add_vcall_offset ( tree orig_fn , tree binfo , vtbl_init_data * vid ) { size_t i ; tree vcall_offset ; tree derived_entry ; for ( i = 0 ; VEC_iterate ( tree , vid -> fns , i , derived_entry ) ; ++ i ) { if ( same_signature_p ( derived_entry , orig_fn ) || ( DECL_DESTRUCTOR_P ( derived_entry ) && DECL_DESTRUCTOR_P ( orig_fn ) ) ) return ; } if ( vid -> binfo == TYPE_BINFO ( vid -> derived ) ) { tree_pair_p elt = VEC_safe_push ( tree_pair_s , gc , CLASSTYPE_VCALL_INDICES ( vid -> derived ) , NULL ) ; elt -> purpose = orig_fn ; elt -> value = vid -> index ; } vid -> index = size_binop ( MINUS_EXPR , vid -> index , ssize_int ( TARGET_VTABLE_DATA_ENTRY_DISTANCE ) ) ; VEC_safe_push ( tree , gc , vid -> fns , orig_fn ) ; if ( vid -> generate_vcall_entries ) { tree base ; tree fn ; fn = find_final_overrider ( vid -> rtti_binfo , binfo , orig_fn ) ; if ( fn == error_mark_node ) vcall_offset = build1 ( NOP_EXPR , vtable_entry_type , integer_zero_node ) ; else { base = TREE_VALUE ( fn ) ; vcall_offset = size_diffop ( BINFO_OFFSET ( base ) , BINFO_OFFSET ( vid -> binfo ) ) ; vcall_offset = fold_build1 ( NOP_EXPR , vtable_entry_type , vcall_offset ) ; } * vid -> last_init = build_tree_list ( NULL_TREE , vcall_offset ) ; vid -> last_init = & TREE_CHAIN ( * vid -> last_init ) ; } }
Add a vcall offset entry for ORIG_FN to the vtable.
Add a vcall offset entry for ORIG_FN to the vtable .
/* If there is already an entry for a function with the same
     signature as FN, then we do not need a second vcall offset.
     Check the list of functions already present in the derived
     class vtable.  */ /* We only use one vcall offset for virtual destructors,
	     even though there are two virtual table entries.  */ /* If we are building these vcall offsets as part of building
     the vtable for the most derived class, remember the vcall
     offset.  */ /* The next vcall offset will be found at a more negative
     offset.  */ /* Keep track of this function.  */ /* Find the overriding function.  */ /* The vbase we're working on is a primary base of
	     vid->binfo.  But it might be a lost primary, so its
	     BINFO_OFFSET might be wrong, so we just use the
	     BINFO_OFFSET from vid->binfo.  */ /* Add the initializer to the vtable.  */