Beispiel #1
0
unsigned int
go_field_alignment (tree t)
{
  unsigned int v;

  v = TYPE_ALIGN (t);

#ifdef BIGGEST_FIELD_ALIGNMENT
  if (v > BIGGEST_FIELD_ALIGNMENT)
    v = BIGGEST_FIELD_ALIGNMENT;
#endif

#ifdef ADJUST_FIELD_ALIGN
  {
    tree field ATTRIBUTE_UNUSED;
    field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL, t);
    v = ADJUST_FIELD_ALIGN (field, v);
  }
#endif

  return v / BITS_PER_UNIT;
}
Beispiel #2
0
BOOL
objc_layout_structure_next_member (struct objc_struct_layout *layout)
{
  register int desired_align = 0;

  /* The following are used only if the field is a bitfield */
  register const char *bfld_type = 0;
  register int bfld_type_align = 0, bfld_field_size = 0;

  /* The current type without the type qualifiers */
  const char *type;
  BOOL unionp = layout->original_type[-1] == _C_UNION_B;

  /* Add the size of the previous field to the size of the record.  */
  if (layout->prev_type)
    {
      type = objc_skip_type_qualifiers (layout->prev_type);
      if (unionp)
        layout->record_size = MAX (layout->record_size,
				   objc_sizeof_type (type) * BITS_PER_UNIT);

      else if (*type != _C_BFLD)
        layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
      else {
        /* Get the bitfield's type */
        for (bfld_type = type + 1;
             isdigit ((unsigned char)*bfld_type);
             bfld_type++)
          /* do nothing */;

        bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
        bfld_field_size = atoi (objc_skip_typespec (bfld_type));
        layout->record_size += bfld_field_size;
      }
    }

  if ((unionp && *layout->type == _C_UNION_E)
      || (!unionp && *layout->type == _C_STRUCT_E))
    return NO;

  /* Skip the variable name if any */
  layout->type = objc_skip_variable_name (layout->type);
  type = objc_skip_type_qualifiers (layout->type);

  if (*type != _C_BFLD)
    desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
  else
    {
      desired_align = 1;
      /* Skip the bitfield's offset */
      for (bfld_type = type + 1;
           isdigit ((unsigned char) *bfld_type);
           bfld_type++)
        /* do nothing */;

      bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
      bfld_field_size = atoi (objc_skip_typespec (bfld_type));
    }

  /* The following won't work for vectors.  */
#ifdef BIGGEST_FIELD_ALIGNMENT
  desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
#endif
#ifdef ADJUST_FIELD_ALIGN
  desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
#endif

  /* Record must have at least as much alignment as any field.
     Otherwise, the alignment of the field within the record
     is meaningless.  */
#ifndef HAVE_BITFIELD_TYPE_MATTERS
  layout->record_align = MAX (layout->record_align, desired_align);
#else	/* PCC_BITFIELD_TYPE_MATTERS */
  if (*type == _C_BFLD)
    {
      /* For these machines, a zero-length field does not
         affect the alignment of the structure as a whole.
         It does, however, affect the alignment of the next field
         within the structure.  */
      if (bfld_field_size)
        layout->record_align = MAX (layout->record_align, desired_align);
      else
        desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;

      /* A named bit field of declared type `int'
         forces the entire structure to have `int' alignment.
         Q1: How is encoded this thing and how to check for it?
         Q2: How to determine maximum_field_alignment at runtime? */

/*	  if (DECL_NAME (field) != 0) */
      {
        int type_align = bfld_type_align;
#if 0
        if (maximum_field_alignment != 0)
          type_align = MIN (type_align, maximum_field_alignment);
        else if (DECL_PACKED (field))
          type_align = MIN (type_align, BITS_PER_UNIT);
#endif

        layout->record_align = MAX (layout->record_align, type_align);
      }
    }
  else
    layout->record_align = MAX (layout->record_align, desired_align);
#endif	/* PCC_BITFIELD_TYPE_MATTERS */

  /* Does this field automatically have alignment it needs
     by virtue of the fields that precede it and the record's
     own alignment?  */

  if (*type == _C_BFLD)
    layout->record_size = atoi (type + 1);
  else if (layout->record_size % desired_align != 0)
    {
      /* No, we need to skip space before this field.
         Bump the cumulative size to multiple of field alignment.  */
      layout->record_size = ROUND (layout->record_size, desired_align);
    }

  /* Jump to the next field in record. */

  layout->prev_type = layout->type;
  layout->type = objc_skip_typespec (layout->type);      /* skip component */

  return YES;
}