FreeBSD/contrib/gcc/cp/method.c
/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
   offset indicated by VIRTUAL_OFFSET, if that is
   non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
   zero for a result adjusting thunk.  */
Adjust PTR by the constant FIXED_OFFSET, and by the vtable
offset indicated by VIRTUAL_OFFSET, if that is
non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
zero for a result adjusting thunk.
Adjust PTR by the constant FIXED_OFFSET and by the vtable offset indicated by VIRTUAL_OFFSET if that is non - null . THIS_ADJUSTING is nonzero for a this adjusting thunk and zero for a result adjusting thunk .
static tree
thunk_adjust (tree ptr, bool this_adjusting,
	      HOST_WIDE_INT fixed_offset, tree virtual_offset)
{
  if (this_adjusting)
    ptr = fold_build2 (PLUS_EXPR, TREE_TYPE (ptr), ptr,
		       ssize_int (fixed_offset));
  if (virtual_offset)
    {
      tree vtable;
      ptr = save_expr (ptr);
      vtable = build1 (NOP_EXPR,
		       build_pointer_type (build_pointer_type
					   (vtable_entry_type)),
		       ptr);
      vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
      vtable = build2 (PLUS_EXPR, TREE_TYPE (vtable), vtable, virtual_offset);
      vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
      ptr = fold_build2 (PLUS_EXPR, TREE_TYPE (ptr), ptr, vtable);
    }
  if (!this_adjusting)
    ptr = fold_build2 (PLUS_EXPR, TREE_TYPE (ptr), ptr,
		       ssize_int (fixed_offset));
  return ptr;
}
static tree thunk_adjust ( tree ptr , bool this_adjusting , HOST_WIDE_INT fixed_offset , tree virtual_offset ) { if ( this_adjusting ) ptr = fold_build2 ( PLUS_EXPR , TREE_TYPE ( ptr ) , ptr , ssize_int ( fixed_offset ) ) ; if ( virtual_offset ) { tree vtable ; ptr = save_expr ( ptr ) ; vtable = build1 ( NOP_EXPR , build_pointer_type ( build_pointer_type ( vtable_entry_type ) ) , ptr ) ; vtable = build1 ( INDIRECT_REF , TREE_TYPE ( TREE_TYPE ( vtable ) ) , vtable ) ; vtable = build2 ( PLUS_EXPR , TREE_TYPE ( vtable ) , vtable , virtual_offset ) ; vtable = build1 ( INDIRECT_REF , TREE_TYPE ( TREE_TYPE ( vtable ) ) , vtable ) ; ptr = fold_build2 ( PLUS_EXPR , TREE_TYPE ( ptr ) , ptr , vtable ) ; } if ( ! this_adjusting ) ptr = fold_build2 ( PLUS_EXPR , TREE_TYPE ( ptr ) , ptr , ssize_int ( fixed_offset ) ) ; return ptr ; }
Adjust PTR by the constant FIXED_OFFSET, and by the vtable
offset indicated by VIRTUAL_OFFSET, if that is
non-null.
Adjust PTR by the constant FIXED_OFFSET and by the vtable offset indicated by VIRTUAL_OFFSET if that is non - null .
/* Adjust the pointer by the constant.  */ /* If there's a virtual offset, look up that value in the vtable and
     adjust the pointer again.  */ /* The vptr is always at offset zero in the object.  */ /* Form the vtable address.  */ /* Find the entry with the vcall offset.  */ /* Get the offset itself.  */ /* Adjust the `this' pointer.  */ /* Adjust the pointer by the constant.  */