⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stor-layout.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	  register tree dsize = DECL_SIZE (field);	  int field_size = TREE_INT_CST_LOW (dsize);	  if (maximum_field_alignment != 0)	    type_align = MIN (type_align, maximum_field_alignment);	  /* A bit field may not span the unit of alignment of its type.	     Advance to next boundary if necessary.  */	  /* ??? There is some uncertainty here as to what	     should be done if type_align is less than the width of the type.	     That can happen because the width exceeds BIGGEST_ALIGNMENT	     or because it exceeds maximum_field_alignment.  */	  if (const_size / type_align	      != (const_size + field_size - 1) / type_align)	    const_size = CEIL (const_size, type_align) * type_align;	}#endif/* No existing machine description uses this parameter.   So I have made it in this aspect identical to PCC_BITFIELD_TYPE_MATTERS.  */#ifdef BITFIELD_NBYTES_LIMITED      if (BITFIELD_NBYTES_LIMITED	  && TREE_CODE (field) == FIELD_DECL	  && TREE_TYPE (field) != error_mark_node	  && DECL_BIT_FIELD_TYPE (field)	  && !DECL_PACKED (field)	  && !integer_zerop (DECL_SIZE (field)))	{	  int type_align = TYPE_ALIGN (TREE_TYPE (field));	  register tree dsize = DECL_SIZE (field);	  int field_size = TREE_INT_CST_LOW (dsize);	  if (maximum_field_alignment != 0)	    type_align = MIN (type_align, maximum_field_alignment);	  /* A bit field may not span the unit of alignment of its type.	     Advance to next boundary if necessary.  */	  if (const_size / type_align	      != (const_size + field_size - 1) / type_align)	    const_size = CEIL (const_size, type_align) * type_align;	}#endif      /* Size so far becomes the position of this field.  */      if (var_size && const_size)	DECL_FIELD_BITPOS (field)	  = size_binop (PLUS_EXPR, var_size, size_int (const_size));      else if (var_size)	DECL_FIELD_BITPOS (field) = var_size;      else	DECL_FIELD_BITPOS (field) = size_int (const_size);      /* If this field is an anonymous union,	 give each union-member the same position as the union has.  */      if (DECL_NAME (field) == 0	  && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)	{	  tree uelt = TYPE_FIELDS (TREE_TYPE (field));	  for (; uelt; uelt = TREE_CHAIN (uelt))	    {	      DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);	      DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);	    }	}      /* Now add size of this field to the size of the record.  */      {        register tree dsize = DECL_SIZE (field);	/* This can happen when we have an invalid nested struct definition,	   such as struct j { struct j { int i; } }.  The error message is	   printed in finish_struct.  */	if (dsize == 0)	  /* Do nothing.  */;	else if (TREE_CODE (dsize) == INTEGER_CST)	  const_size += TREE_INT_CST_LOW (dsize);	else	  {	    if (var_size == 0)	      var_size = dsize;	    else	      var_size = size_binop (PLUS_EXPR, var_size, dsize);	  }      }    }  /* Work out the total size and alignment of the record     as one expression and store in the record type.     Round it up to a multiple of the record's alignment.  */  if (var_size == 0)    {      TYPE_SIZE (rec) = size_int (const_size);    }  else    {      if (const_size)	var_size	  = size_binop (PLUS_EXPR, var_size, size_int (const_size));      TYPE_SIZE (rec) = var_size;    }  /* Determine the desired alignment.  */#ifdef ROUND_TYPE_ALIGN  TYPE_ALIGN (rec) = ROUND_TYPE_ALIGN (rec, TYPE_ALIGN (rec), record_align);#else  TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), record_align);#endif#ifdef ROUND_TYPE_SIZE  TYPE_SIZE (rec) = ROUND_TYPE_SIZE (rec, TYPE_SIZE (rec), TYPE_ALIGN (rec));#else  /* Round the size up to be a multiple of the required alignment */  TYPE_SIZE (rec) = round_up (TYPE_SIZE (rec), TYPE_ALIGN (rec));#endif  return pending_statics;}/* Lay out a UNION_TYPE type.   Lay out all the fields, set their positions to zero,   and compute the size and alignment of the union (maximum of any field).   Note that if you set the TYPE_ALIGN before calling this   then the union align is aligned to at least that boundary.  */static voidlayout_union (rec)     tree rec;{  register tree field;#ifdef STRUCTURE_SIZE_BOUNDARY  unsigned union_align = STRUCTURE_SIZE_BOUNDARY;#else  unsigned union_align = BITS_PER_UNIT;#endif  /* The size of the union, based on the fields scanned so far,     is max (CONST_SIZE, VAR_SIZE).     VAR_SIZE may be null; then CONST_SIZE by itself is the size.  */  register int const_size = 0;  register tree var_size = 0;  for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field))    {      /* Enums which are local to this class need not be laid out.  */      if (TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TYPE_DECL)	continue;      layout_decl (field, 0);      DECL_FIELD_BITPOS (field) = size_int (0);      /* Union must be at least as aligned as any field requires.  */      union_align = MAX (union_align, DECL_ALIGN (field));#ifdef PCC_BITFIELD_TYPE_MATTERS      /* On the m88000, a bit field of declare type `int'	 forces the entire union to have `int' alignment.  */      if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field))	union_align = MAX (union_align, TYPE_ALIGN (TREE_TYPE (field)));#endif      /* Set union_size to max (decl_size, union_size).	 There are more and less general ways to do this.	 Use only CONST_SIZE unless forced to use VAR_SIZE.  */      if (TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)	const_size = MAX (const_size, TREE_INT_CST_LOW (DECL_SIZE (field)));      else if (var_size == 0)	var_size = DECL_SIZE (field);      else	var_size = size_binop (MAX_EXPR, var_size, DECL_SIZE (field));    }  /* Determine the ultimate size of the union (in bytes).  */  if (NULL == var_size)    TYPE_SIZE (rec) = size_int (CEIL (const_size, BITS_PER_UNIT)				* BITS_PER_UNIT);  else if (const_size == 0)    TYPE_SIZE (rec) = var_size;  else    TYPE_SIZE (rec) = size_binop (MAX_EXPR, var_size,				  round_up (size_int (const_size),					    BITS_PER_UNIT));  /* Determine the desired alignment.  */#ifdef ROUND_TYPE_ALIGN  TYPE_ALIGN (rec) = ROUND_TYPE_ALIGN (rec, TYPE_ALIGN (rec), union_align);#else  TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), union_align);#endif#ifdef ROUND_TYPE_SIZE  TYPE_SIZE (rec) = ROUND_TYPE_SIZE (rec, TYPE_SIZE (rec), TYPE_ALIGN (rec));#else  /* Round the size up to be a multiple of the required alignment */  TYPE_SIZE (rec) = round_up (TYPE_SIZE (rec), TYPE_ALIGN (rec));#endif}/* Calculate the mode, size, and alignment for TYPE.   For an array type, calculate the element separation as well.   Record TYPE on the chain of permanent or temporary types   so that dbxout will find out about it.   TYPE_SIZE of a type is nonzero if the type has been laid out already.   layout_type does nothing on such a type.   If the type is incomplete, its TYPE_SIZE remains zero.  */voidlayout_type (type)     tree type;{  int old;  tree pending_statics;  if (type == 0)    abort ();  /* Do nothing if type has been laid out before.  */  if (TYPE_SIZE (type))    return;  /* Make sure all nodes we allocate are not momentary;     they must last past the current statement.  */  old = suspend_momentary ();  /* If we are processing a permanent type, make nodes permanent.     If processing a temporary type, make it saveable, since the     type node itself is.  This is important if the function is inline,     since its decls will get copied later.  */  push_obstacks_nochange ();  if (allocation_temporary_p ())    {      if (TREE_PERMANENT (type))	end_temporary_allocation ();      else	saveable_allocation ();    }  switch (TREE_CODE (type))    {    case LANG_TYPE:      /* This kind of type is the responsibility	 of the languge-specific code.  */      abort ();    case INTEGER_TYPE:    case ENUMERAL_TYPE:      if (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) >= 0)	TREE_UNSIGNED (type) = 1;      /* We pass 0 for the last arg of mode_for_size because otherwise	 on the Apollo using long long causes a crash.	 It seems better to use integer modes than to try to support	 integer types with BLKmode.  */      TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_INT, 0);      TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));      break;    case REAL_TYPE:      TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);      TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));      break;    case COMPLEX_TYPE:      TREE_UNSIGNED (type) = TREE_UNSIGNED (TREE_TYPE (type));      TYPE_MODE (type)	= mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),			 (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE			  ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),			 0);      TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));      break;    case VOID_TYPE:      TYPE_SIZE (type) = size_zero_node;      TYPE_ALIGN (type) = 1;      TYPE_MODE (type) = VOIDmode;      break;    case OFFSET_TYPE:      TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (Pmode));      TYPE_MODE (type) = Pmode;      break;    case FUNCTION_TYPE:    case METHOD_TYPE:      TYPE_MODE (type) = mode_for_size (2 * GET_MODE_BITSIZE (Pmode),					MODE_INT, 0);      TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));      break;    case POINTER_TYPE:    case REFERENCE_TYPE:      TYPE_MODE (type) = Pmode;      TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));      TREE_UNSIGNED (type) = 1;      TYPE_PRECISION (type) = GET_MODE_BITSIZE (TYPE_MODE (type));      break;    case ARRAY_TYPE:      {	register tree index = TYPE_DOMAIN (type);	register tree element = TREE_TYPE (type);	build_pointer_type (element);	/* We need to know both bounds in order to compute the size.  */	if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)	    && TYPE_SIZE (element))	  {	    tree length	      = size_binop (PLUS_EXPR, size_one_node,			    size_binop (MINUS_EXPR, TYPE_MAX_VALUE (index),					TYPE_MIN_VALUE (index)));	    TYPE_SIZE (type) = size_binop (MULT_EXPR, length,					   TYPE_SIZE (element));	  }	/* Now round the alignment and size,	   using machine-dependent criteria if any.  */#ifdef ROUND_TYPE_ALIGN	TYPE_ALIGN (type)	  = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);#else	TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);#endif#ifdef ROUND_TYPE_SIZE	if (TYPE_SIZE (type) != 0)	  TYPE_SIZE (type)	    = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));#endif	TYPE_MODE (type) = BLKmode;	if (TYPE_SIZE (type) != 0	    && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST	    /* BLKmode elements force BLKmode aggregate;	       else extract/store fields may lose.  */	    && (TYPE_MODE (TREE_TYPE (type)) != BLKmode		|| TYPE_NO_FORCE_BLK (TREE_TYPE (type))))	  {	    TYPE_MODE (type)	      = mode_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)),			       MODE_INT, 1);	    if (STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT		&& TYPE_ALIGN (type) < TREE_INT_CST_LOW (TYPE_SIZE (type))		&& TYPE_MODE (type) != BLKmode)	      {		TYPE_NO_FORCE_BLK (type) = 1;		TYPE_MODE (type) = BLKmode;	      }	  }	break;      }    case RECORD_TYPE:      pending_statics = layout_record (type);      TYPE_MODE (type) = BLKmode;      if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)	{	  tree field;	  /* A record which has any BLKmode members must itself be BLKmode;	     it can't go in a register.	     Unless the member is BLKmode only because it isn't aligned.  */	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))	    {	      int bitpos;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -