diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2010-05-08 11:31:31 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2010-05-08 11:31:31 +0000 |
commit | 35e2a4b8423dda850cb7898e30fdd75762226c4b (patch) | |
tree | e7e98508d94aa9e5f2cf639f84217f7a9f0db54f /gcc/ada/gcc-interface/decl.c | |
parent | da01bfee1aafe6c68c2c21d9d6d77a506c7e52c7 (diff) | |
download | gcc-35e2a4b8423dda850cb7898e30fdd75762226c4b.zip gcc-35e2a4b8423dda850cb7898e30fdd75762226c4b.tar.gz gcc-35e2a4b8423dda850cb7898e30fdd75762226c4b.tar.bz2 |
decl.c (gnat_to_gnu_entity): Create variables for size expressions of variant part of record types declared...
* gcc-interface/decl.c (gnat_to_gnu_entity): Create variables for size
expressions of variant part of record types declared at library level.
From-SVN: r159182
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 3050475..b0334f2 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -4516,8 +4516,62 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if (TREE_CODE (gnu_type) == RECORD_TYPE) { + tree variant_part = get_variant_part (gnu_type); tree ada_size = TYPE_ADA_SIZE (gnu_type); + if (variant_part) + { + tree union_type = TREE_TYPE (variant_part); + tree offset = DECL_FIELD_OFFSET (variant_part); + + /* If the position of the variant part is constant, subtract + it from the size of the type of the parent to get the new + size. This manual CSE reduces the data size. */ + if (TREE_CODE (offset) == INTEGER_CST) + { + tree bitpos = DECL_FIELD_BIT_OFFSET (variant_part); + TYPE_SIZE (union_type) + = size_binop (MINUS_EXPR, TYPE_SIZE (gnu_type), + bit_from_pos (offset, bitpos)); + TYPE_SIZE_UNIT (union_type) + = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (gnu_type), + byte_from_pos (offset, bitpos)); + } + else + { + TYPE_SIZE (union_type) + = elaborate_expression_1 (TYPE_SIZE (union_type), + gnat_entity, + get_identifier ("VSIZE"), + definition, false); + + /* ??? For now, store the size as a multiple of the + alignment in bytes so that we can see the alignment + from the tree. */ + TYPE_SIZE_UNIT (union_type) + = elaborate_expression_2 (TYPE_SIZE_UNIT (union_type), + gnat_entity, + get_identifier + ("VSIZE_A_UNIT"), + definition, false, + TYPE_ALIGN (union_type)); + + /* ??? For now, store the offset as a multiple of the + alignment in bytes so that we can see the alignment + from the tree. */ + DECL_FIELD_OFFSET (variant_part) + = elaborate_expression_2 (offset, + gnat_entity, + get_identifier ("VOFFSET"), + definition, false, + DECL_OFFSET_ALIGN + (variant_part)); + } + + DECL_SIZE (variant_part) = TYPE_SIZE (union_type); + DECL_SIZE_UNIT (variant_part) = TYPE_SIZE_UNIT (union_type); + } + if (operand_equal_p (ada_size, size, 0)) ada_size = TYPE_SIZE (gnu_type); else |