FreeBSD/contrib/gcc/cp/class.c
/* DECL is a FIELD_DECL corresponding either to a base subobject of a
   non-static data member of the type indicated by RLI.  BINFO is the
   binfo corresponding to the base subobject, OFFSETS maps offsets to
   types already located at those offsets.  This function determines
   the position of the DECL.  */
DECL is a FIELD_DECL corresponding either to a base subobject of a
non-static data member of the type indicated by RLI.  BINFO is the
binfo corresponding to the base subobject, OFFSETS maps offsets to
types already located at those offsets.  This function determines
the position of the DECL.
DECL is a FIELD_DECL corresponding either to a base subobject of a non - static data member of the type indicated by RLI . BINFO is the binfo corresponding to the base subobject OFFSETS maps offsets to types already located at those offsets . This function determines the position of the DECL .
static void
layout_nonempty_base_or_field (record_layout_info rli,
			       tree decl,
			       tree binfo,
			       splay_tree offsets)
{
  tree offset = NULL_TREE;
  bool field_p;
  tree type;
  if (binfo)
    {
      type = TREE_TYPE (binfo);
      field_p = false;
    }
  else
    {
      type = TREE_TYPE (decl);
      field_p = true;
    }
  while (1)
    {
      struct record_layout_info_s old_rli = *rli;
      place_field (rli, decl);
      offset = byte_position (decl);
      if (TREE_CODE (rli->t) == UNION_TYPE)
	break;
      if (!abi_version_at_least (2) && binfo && BINFO_VIRTUAL_P (binfo))
	break;
      if (layout_conflict_p (field_p ? type : binfo, offset,
			     offsets, field_p))
	{
	  *rli = old_rli;
	  rli->bitpos
	    = size_binop (PLUS_EXPR, rli->bitpos,
			  bitsize_int (binfo
				       ? CLASSTYPE_ALIGN (type)
				       : TYPE_ALIGN (type)));
	  normalize_rli (rli);
	}
      else
	break;
    }
  if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
    propagate_binfo_offsets (binfo,
			     size_diffop (convert (ssizetype, offset),
					  convert (ssizetype,
						   BINFO_OFFSET (binfo))));
}
static void layout_nonempty_base_or_field ( record_layout_info rli , tree decl , tree binfo , splay_tree offsets ) { tree offset = NULL_TREE ; bool field_p ; tree type ; if ( binfo ) { type = TREE_TYPE ( binfo ) ; field_p = false ; } else { type = TREE_TYPE ( decl ) ; field_p = true ; } while ( 1 ) { struct record_layout_info_s old_rli = * rli ; place_field ( rli , decl ) ; offset = byte_position ( decl ) ; if ( TREE_CODE ( rli -> t ) == UNION_TYPE ) break ; if ( ! abi_version_at_least ( 2 ) && binfo && BINFO_VIRTUAL_P ( binfo ) ) break ; if ( layout_conflict_p ( field_p ? type : binfo , offset , offsets , field_p ) ) { * rli = old_rli ; rli -> bitpos = size_binop ( PLUS_EXPR , rli -> bitpos , bitsize_int ( binfo ? CLASSTYPE_ALIGN ( type ) : TYPE_ALIGN ( type ) ) ) ; normalize_rli ( rli ) ; } else break ; } if ( binfo && CLASS_TYPE_P ( BINFO_TYPE ( binfo ) ) ) propagate_binfo_offsets ( binfo , size_diffop ( convert ( ssizetype , offset ) , convert ( ssizetype , BINFO_OFFSET ( binfo ) ) ) ) ; }
DECL is a FIELD_DECL corresponding either to a base subobject of a
non-static data member of the type indicated by RLI.
DECL is a FIELD_DECL corresponding either to a base subobject of a non - static data member of the type indicated by RLI .
/* For the purposes of determining layout conflicts, we want to
	 use the class type of BINFO; TREE_TYPE (DECL) will be the
	 CLASSTYPE_AS_BASE version, which does not contain entries for
	 zero-sized bases.  */ /* Try to place the field.  It may take more than one try if we have
     a hard time placing the field without putting two objects of the
     same type at the same address.  */ /* Place this field.  */ /* We have to check to see whether or not there is already
	 something of the same type at the offset we're about to use.
	 For example, consider:

	   struct S {};
	   struct T : public S { int i; };
	   struct U : public S, public T {};

	 Here, we put S at offset zero in U.  Then, we can't put T at
	 offset zero -- its S component would be at the same address
	 as the S we already allocated.  So, we have to skip ahead.
	 Since all data members, including those whose type is an
	 empty class, have nonzero size, any overlap can happen only
	 with a direct or indirect base-class -- it can't happen with
	 a data member.  */ /* In a union, overlap is permitted; all members are placed at
	 offset zero.  */ /* G++ 3.2 did not check for overlaps when placing a non-empty
	 virtual base.  */ /* Strip off the size allocated to this field.  That puts us
	     at the first place we could have put the field with
	     proper alignment.  */ /* Bump up by the alignment required for the type.  */ /* There was no conflict.  We're done laying out this field.  */ /* Now that we know where it will be placed, update its
     BINFO_OFFSET.  */ /* Indirect virtual bases may have a nonzero BINFO_OFFSET at
       this point because their BINFO_OFFSET is copied from another
       hierarchy.  Therefore, we may not need to add the entire
       OFFSET.  */