📄 stor-layout.c
字号:
BITS_PER_UNIT), var_size); } /* Determine the ultimate size of the union (in bytes). */ if (NULL == var_size) TYPE_SIZE (rec) = build_int (CEIL (const_size, BITS_PER_UNIT)); else if (const_size == 0) TYPE_SIZE (rec) = var_size; else TYPE_SIZE (rec) = genop (MAX_EXPR, var_size, build_int (CEIL (const_size, BITS_PER_UNIT))); /* Determine the desired alignment. */ union_align = MIN (BIGGEST_ALIGNMENT, union_align); TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), union_align); /* Round the size up to be a multiple of the required alignment */ TYPE_SIZE (rec) = convert_units (TYPE_SIZE (rec), BITS_PER_UNIT, TYPE_ALIGN (rec)); TYPE_SIZE_UNIT (rec) = TYPE_ALIGN (rec);}/* 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; int temporary = 0; 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 (TREE_PERMANENT (type) && allocation_temporary_p ()) { temporary = 1; end_temporary_allocation (); } chain_type (type); switch (TREE_CODE (type)) { case LANG_TYPE: /* This kind of type is the responsibility of the languge-specific code. */ abort (); case VOID_TYPE: TYPE_SIZE (type) = size_zero_node; TYPE_SIZE_UNIT (type) = BITS_PER_UNIT; TYPE_ALIGN (type) = 1; TYPE_MODE (type) = VOIDmode; break; case INTEGER_TYPE: case ENUMERAL_TYPE: if (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) >= 0) TREE_UNSIGNED (type) = 1; /* What follows is like agg_mode except that it ignores MAX_FIXED_MODE_SIZE. That applies only to structures. */ { enum machine_mode mode, t; /* Get the last mode which has this size. */ mode = BLKmode; for (t = QImode; GET_MODE_CLASS (t) == MODE_INT; t = (enum machine_mode) ((int) t + 1)) if (GET_MODE_BITSIZE (t) == TYPE_PRECISION (type)) mode = t; TYPE_MODE (type) = mode; } TYPE_SIZE (type) = build_int (GET_MODE_SIZE (TYPE_MODE (type))); TYPE_SIZE_UNIT (type) = BITS_PER_UNIT; TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type)); break; case REAL_TYPE: { register int prec = TYPE_PRECISION (type); if (prec <= GET_MODE_BITSIZE (SFmode)) TYPE_MODE (type) = SFmode; else if (prec <= GET_MODE_BITSIZE (DFmode)) TYPE_MODE (type) = DFmode; else if (prec <= GET_MODE_BITSIZE (TFmode)) TYPE_MODE (type) = TFmode; else abort (); } TYPE_SIZE (type) = build_int (GET_MODE_SIZE (TYPE_MODE (type))); TYPE_SIZE_UNIT (type) = BITS_PER_UNIT; TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type)); break; case POINTER_TYPE: case REFERENCE_TYPE: TYPE_MODE (type) = Pmode; TYPE_SIZE (type) = build_int (POINTER_SIZE / BITS_PER_UNIT); TYPE_SIZE_UNIT (type) = BITS_PER_UNIT; TYPE_ALIGN (type) = POINTER_BOUNDARY; TREE_UNSIGNED (type) = 1; TYPE_PRECISION (type) = POINTER_SIZE; break; case ARRAY_TYPE: { register tree index = TYPE_DOMAIN (type); register tree length; register tree element = TREE_TYPE (type);/* layout_type (element); */ build_pointer_type (element); if (index == 0) length = 0; else length = genop (PLUS_EXPR, size_one_node, genop (MINUS_EXPR, TYPE_MAX_VALUE (index), TYPE_MIN_VALUE (index))); if (TREE_PACKED (type)) abort (); /* ??? Not written yet since not needed for C. */ TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (element); if (length && TYPE_SIZE (element)) TYPE_SIZE (type) = genop (MULT_EXPR, TYPE_SIZE (element), length); TYPE_SEP (type) = TYPE_SIZE (element); TYPE_SEP_UNIT (type) = TYPE_SIZE_UNIT (element); TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT); 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#ifdef STRICT_ALIGNMENT && (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT || TYPE_ALIGN (type) >= (TREE_INT_CST_LOW (TYPE_SIZE (type)) * TYPE_SIZE_UNIT (type)))#endif ) { TYPE_MODE (type) = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type)) * TYPE_SIZE_UNIT (type)); } break; } case RECORD_TYPE: layout_record (type); TYPE_MODE (type) = BLKmode; if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST /* If structure's known alignment is less than what the scalar mode would need, and it matters, then stick with BLKmode. */#ifdef STRICT_ALIGNMENT && (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT || TYPE_ALIGN (type) >= (TREE_INT_CST_LOW (TYPE_SIZE (type)) * TYPE_SIZE_UNIT (type)))#endif ) { tree field; /* A record which has any BLKmode members must itself be BLKmode; it can't go in a register. */ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { if (TYPE_MODE (TREE_TYPE (field)) == BLKmode) goto record_lose; /* Must be BLKmode if any field crosses a word boundary, since extract_bit_field can't handle that in registers. */ if (DECL_OFFSET (field) / BITS_PER_WORD != ((TREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field) + DECL_OFFSET (field) - 1) / BITS_PER_WORD)) goto record_lose; } TYPE_MODE (type) = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type)) * TYPE_SIZE_UNIT (type)); record_lose: ; } break; case UNION_TYPE: layout_union (type); TYPE_MODE (type) = BLKmode; if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST /* If structure's known alignment is less than what the scalar mode would need, and it matters, then stick with BLKmode. */#ifdef STRICT_ALIGNMENT && (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT || TYPE_ALIGN (type) >= (TREE_INT_CST_LOW (TYPE_SIZE (type)) * TYPE_SIZE_UNIT (type)))#endif ) { tree field; /* A union which has any BLKmode members must itself be BLKmode; it can't go in a register. */ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TYPE_MODE (TREE_TYPE (field)) == BLKmode) goto union_lose; TYPE_MODE (type) = agg_mode (TREE_INT_CST_LOW (TYPE_SIZE (type)) * TYPE_SIZE_UNIT (type)); union_lose: ; } break; case FUNCTION_TYPE: case METHOD_TYPE: TYPE_MODE (type) = EPmode; TYPE_SIZE (type) = build_int (2 * POINTER_SIZE / BITS_PER_UNIT); TYPE_SIZE_UNIT (type) = BITS_PER_UNIT; TYPE_ALIGN (type) = POINTER_BOUNDARY; break; default: abort (); } /* end switch */ /* Evaluate nonconstant size only once, either now or as soon as safe. */ if (TYPE_SIZE (type) != 0 && ! TREE_LITERAL (TYPE_SIZE (type))) TYPE_SIZE (type) = variable_size (TYPE_SIZE (type)); /* Also layout any other variants of the type. */ if (TYPE_NEXT_VARIANT (type) || type != TYPE_MAIN_VARIANT (type)) { tree variant; /* Record layout info of this variant. */ tree size = TYPE_SIZE (type); int size_unit = TYPE_SIZE_UNIT (type); int align = TYPE_ALIGN (type); enum machine_mode mode = TYPE_MODE (type); /* Copy it into all variants. */ for (variant = TYPE_MAIN_VARIANT (type); variant; variant = TYPE_NEXT_VARIANT (variant)) { TYPE_SIZE (variant) = size; TYPE_SIZE_UNIT (variant) = size_unit; TYPE_ALIGN (variant) = align; TYPE_MODE (variant) = mode; } } if (temporary) resume_temporary_allocation (); resume_momentary (old);}/* Create and return a type for signed integers of PRECISION bits. */treemake_signed_type (precision) int precision;{ register tree type = make_node (INTEGER_TYPE); TYPE_PRECISION (type) = precision; /* Create the extreme values based on the number of bits. */ TYPE_MIN_VALUE (type) = build_int_2 ((precision-HOST_BITS_PER_INT > 0 ? 0 : (-1)<<(precision-1)), (-1)<<(precision-HOST_BITS_PER_INT-1 > 0 ? precision-HOST_BITS_PER_INT-1 : 0)); TYPE_MAX_VALUE (type) = build_int_2 ((precision-HOST_BITS_PER_INT > 0 ? -1 : (1<<(precision-1))-1), (precision-HOST_BITS_PER_INT-1 > 0 ? (1<<(precision-HOST_BITS_PER_INT-1))-1 : 0)); /* Give this type's extreme values this type as their type. */ TREE_TYPE (TYPE_MIN_VALUE (type)) = type; TREE_TYPE (TYPE_MAX_VALUE (type)) = type; /* The first type made with this or `make_unsigned_type' is the type for size values. */ if (sizetype == 0) sizetype = type; /* Lay out the type: set its alignment, size, etc. */ layout_type (type); return type;}/* Create and return a type for unsigned integers of PRECISION bits. */treemake_unsigned_type (precision) int precision;{ register tree type = make_node (INTEGER_TYPE); TYPE_PRECISION (type) = precision; /* The first type made with this or `make_unsigned_type' is the type for size values. */ if (sizetype == 0) sizetype = type; fixup_unsigned_type (type); return type;}/* Set the extreme values of TYPE based on its precision in bits, the lay it out. This is used both in `make_unsigned_type' and for enumeral types. */voidfixup_unsigned_type (type) tree type;{ register int precision = TYPE_PRECISION (type); TYPE_MIN_VALUE (type) = build_int_2 (0, 0); TYPE_MAX_VALUE (type) = build_int_2 (precision-HOST_BITS_PER_INT >= 0 ? -1 : (1<<precision)-1, precision-HOST_BITS_PER_INT > 0 ? ((unsigned) ~0 >> (HOST_BITS_PER_INT - (precision - HOST_BITS_PER_INT))) : 0); TREE_TYPE (TYPE_MIN_VALUE (type)) = type; TREE_TYPE (TYPE_MAX_VALUE (type)) = type; /* Lay out the type: set its alignment, size, etc. */ layout_type (type);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -