diff options
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 7a827b7..a63cc18 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -8291,7 +8291,8 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type) gnu_list); if (t) { - tree parent_offset; + tree offset = TREE_VEC_ELT (TREE_VALUE (t), 0); + tree bit_offset = TREE_VEC_ELT (TREE_VALUE (t), 2); /* If we are just annotating types and the type is tagged, the tag and the parent components are not generated by the front-end so @@ -8301,31 +8302,46 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type) && Is_Tagged_Type (gnat_entity) && No (Component_Clause (gnat_field))) { + tree parent_bit_offset; + /* For a component appearing in the current extension, the offset is the size of the parent. */ if (Is_Derived_Type (gnat_entity) && Original_Record_Component (gnat_field) == gnat_field) - parent_offset + parent_bit_offset = UI_To_gnu (Esize (Etype (Base_Type (gnat_entity))), bitsizetype); else - parent_offset = bitsize_int (POINTER_SIZE); + parent_bit_offset = bitsize_int (POINTER_SIZE); if (TYPE_FIELDS (gnu_type)) - parent_offset - = round_up (parent_offset, + parent_bit_offset + = round_up (parent_bit_offset, DECL_ALIGN (TYPE_FIELDS (gnu_type))); + + offset + = size_binop (PLUS_EXPR, offset, + fold_convert (sizetype, + size_binop (TRUNC_DIV_EXPR, + parent_bit_offset, + bitsize_unit_node))); + } + + /* If the field has a variable offset, also compute the normalized + position since it's easier to do on trees here than to deduce + it from the annotated expression of Component_Bit_Offset. */ + if (TREE_CODE (offset) != INTEGER_CST) + { + normalize_offset (&offset, &bit_offset, BITS_PER_UNIT); + Set_Normalized_Position (gnat_field, + annotate_value (offset)); + Set_Normalized_First_Bit (gnat_field, + annotate_value (bit_offset)); } - else - parent_offset = bitsize_zero_node; Set_Component_Bit_Offset (gnat_field, - annotate_value - (size_binop (PLUS_EXPR, - bit_from_pos (TREE_VEC_ELT (TREE_VALUE (t), 0), - TREE_VEC_ELT (TREE_VALUE (t), 2)), - parent_offset))); + annotate_value (bit_from_pos (offset, bit_offset))); Set_Esize (gnat_field, annotate_value (DECL_SIZE (TREE_PURPOSE (t)))); @@ -8334,19 +8350,27 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type) { /* If there is no entry, this is an inherited component whose position is the same as in the parent type. */ - Entity_Id gnat_orig_field = Original_Record_Component (gnat_field); + Entity_Id gnat_orig = Original_Record_Component (gnat_field); /* If we are just annotating types, discriminants renaming those of the parent have no entry so deal with them specifically. */ if (type_annotate_only - && gnat_orig_field == gnat_field + && gnat_orig == gnat_field && Ekind (gnat_field) == E_Discriminant) - gnat_orig_field = Corresponding_Discriminant (gnat_field); + gnat_orig = Corresponding_Discriminant (gnat_field); + + if (Known_Normalized_Position (gnat_orig)) + { + Set_Normalized_Position (gnat_field, + Normalized_Position (gnat_orig)); + Set_Normalized_First_Bit (gnat_field, + Normalized_First_Bit (gnat_orig)); + } Set_Component_Bit_Offset (gnat_field, - Component_Bit_Offset (gnat_orig_field)); + Component_Bit_Offset (gnat_orig)); - Set_Esize (gnat_field, Esize (gnat_orig_field)); + Set_Esize (gnat_field, Esize (gnat_orig)); } } } |