Exemplo n.º 1
0
Arquivo: encoding.c Projeto: giaf/gcc
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;
}
Exemplo n.º 2
0
Arquivo: encoding.c Projeto: giaf/gcc
inline
const char *
objc_skip_typespec (const char *type)
{
  type = objc_skip_variable_name (type);
  type = objc_skip_type_qualifiers (type);

  switch (*type) {

  case _C_ID:
    /* An id may be annotated by the actual type if it is known
       with the @"ClassName" syntax */

    if (*++type != '"')
      return type;
    else
      {
	while (*++type != '"')
	  /* do nothing */;
	return type + 1;
      }

    /* The following are one character type codes */
  case _C_CLASS:
  case _C_SEL:
  case _C_CHR:
  case _C_UCHR:
  case _C_CHARPTR:
  case _C_ATOM:
  case _C_SHT:
  case _C_USHT:
  case _C_INT:
  case _C_UINT:
  case _C_LNG:
  case _C_BOOL:
  case _C_ULNG:
  case _C_LNG_LNG:
  case _C_ULNG_LNG:
  case _C_FLT:
  case _C_DBL:
  case _C_LNG_DBL:
  case _C_VOID:
  case _C_UNDEF:
    return ++type;
    break;
    
  case _C_COMPLEX:
    return type + 2;
    break;

  case _C_ARY_B:
    /* skip digits, typespec and closing ']' */
    while (isdigit ((unsigned char)*++type))
      ;
    type = objc_skip_typespec (type);
    if (*type == _C_ARY_E)
      return ++type;
    else
      {
	_objc_abort ("bad array type %s\n", type);
	return 0;
      }

  case _C_VECTOR:
    /* Skip '!' */
    type++;
    /* Skip '[' */
    type++;
    /* Skip digits (size) */
    while (isdigit ((unsigned char)*type))
      type++;
    /* Skip ',' */
    type++;
    /* Skip digits (alignment) */
    while (isdigit ((unsigned char)*type))
      type++;
    /* Skip typespec.  */
    type = objc_skip_typespec (type);
    /* Skip closing ']'.  */
    if (*type == _C_ARY_E)
      return ++type;
    else
      {
	_objc_abort ("bad vector type %s\n", type);
	return 0;
      }

  case _C_BFLD:
    /* The GNU encoding of bitfields is: b 'position' 'type'
       'size'.  */
    while (isdigit ((unsigned char)*++type))
      ;	/* skip position */
    while (isdigit ((unsigned char)*++type))
      ;	/* skip type and size */
    return type;

  case _C_STRUCT_B:
    /* skip name, and elements until closing '}'  */

    while (*type != _C_STRUCT_E && *type++ != '=')
      ;
    while (*type != _C_STRUCT_E)
      {
	type = objc_skip_typespec (type);
      }
    return ++type;

  case _C_UNION_B:
    /* skip name, and elements until closing ')'  */

    while (*type != _C_UNION_E && *type++ != '=')
      ;
    while (*type != _C_UNION_E)
      {
	type = objc_skip_typespec (type);
      }
    return ++type;

  case _C_PTR:
    /* Just skip the following typespec */

    return objc_skip_typespec (++type);

  default:
    {
      _objc_abort ("unknown type %s\n", type);
      return 0;
    }
  }
}
Exemplo n.º 3
0
Arquivo: encoding.c Projeto: aosm/gcc3
const char* 
objc_skip_typespec (const char* type)
{
  /* Skip the variable name if any */
  if (*type == '"')
    {
      for (type++; *type++ != '"';)
	/* do nothing */;
    }

  type = objc_skip_type_qualifiers (type);
  
  switch (*type) {

  case _C_ID:
    /* An id may be annotated by the actual type if it is known
       with the @"ClassName" syntax */

    if (*++type != '"')
      return type;
    else
      {
	while (*++type != '"') /* do nothing */;
	return type + 1;
      }

    /* The following are one character type codes */
  case _C_CLASS:
  case _C_SEL:
  case _C_CHR:
  case _C_UCHR:
  case _C_CHARPTR:
  case _C_ATOM:
  case _C_SHT:
  case _C_USHT:
  case _C_INT:
  case _C_UINT:
  case _C_LNG:
  case _C_ULNG:
  case _C_LNG_LNG:
  case _C_ULNG_LNG:
  case _C_FLT:
  case _C_DBL:
  case _C_VOID:
  case _C_UNDEF:
    return ++type;
    break;

  case _C_ARY_B:
    /* skip digits, typespec and closing ']' */
    
    while(isdigit(*++type));
    type = objc_skip_typespec(type);
    if (*type == _C_ARY_E)
      return ++type;
    else
      {
	objc_error(nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type);
	return 0;
      }

  case _C_BFLD:
    /* The new encoding of bitfields is: b 'position' 'type' 'size' */
    while (isdigit (*++type));	/* skip position */
    while (isdigit (*++type));	/* skip type and size */
    return type;

  case _C_STRUCT_B:
    /* skip name, and elements until closing '}'  */
    
    while (*type != _C_STRUCT_E && *type++ != '=');
    while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
    return ++type;

  case _C_UNION_B:
    /* skip name, and elements until closing ')'  */
    
    while (*type != _C_UNION_E && *type++ != '=');
    while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
    return ++type;

  case _C_PTR:
    /* Just skip the following typespec */
    
    return objc_skip_typespec (++type);
    
  default:
    {
      objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
      return 0;
    }
  }
}