aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2012-04-30 08:31:29 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-04-30 08:31:29 +0000
commitb38086f06abab6f679bc6e63d833b8d853a5e04f (patch)
tree344606836405cdc8b8aabc044d626774a697e93e
parentbb358f1cd9fbf80190bfcc77fea21237d6f5a44d (diff)
downloadgcc-b38086f06abab6f679bc6e63d833b8d853a5e04f.zip
gcc-b38086f06abab6f679bc6e63d833b8d853a5e04f.tar.gz
gcc-b38086f06abab6f679bc6e63d833b8d853a5e04f.tar.bz2
decl.c (gnat_to_gnu_entity): In type annotation mode...
* gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode, do not adjust the size of a tagged type if there is a representation clause on it. Otherwise, round the adjustment up to the alignment of the first field and use the appropriate helper routine. (maybe_pad_type): Do not warn in type annotation mode on a tagged type. (gnat_to_gnu_field): Do not error out under the same circumstances. (annotate_rep): In type annotation mode, do not adjust the offset of components of a tagged type with representation clause. Otherwise, round the adjustment up to the alignment of the first field. From-SVN: r186961
-rw-r--r--gcc/ada/ChangeLog14
-rw-r--r--gcc/ada/gcc-interface/decl.c64
2 files changed, 55 insertions, 23 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 838e4d0..31d5ac4 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,17 @@
2012-04-30 Eric Botcazou <ebotcazou@adacore.com>
+ * gcc-interface/decl.c (gnat_to_gnu_entity): In type annotation mode,
+ do not adjust the size of a tagged type if there is a representation
+ clause on it. Otherwise, round the adjustment up to the alignment
+ of the first field and use the appropriate helper routine.
+ (maybe_pad_type): Do not warn in type annotation mode on a tagged type.
+ (gnat_to_gnu_field): Do not error out under the same circumstances.
+ (annotate_rep): In type annotation mode, do not adjust the offset of
+ components of a tagged type with representation clause. Otherwise,
+ round the adjustment up to the alignment of the first field.
+
+2012-04-30 Eric Botcazou <ebotcazou@adacore.com>
+
* gcc-interface/utils.c (finish_record_type): Force the traditional GCC
layout for bitfields on the type if it is packed or has a representation
clause and an alternate layout is available.
@@ -14,7 +26,7 @@
(destroy_dummy_type): Likewise.
* gcc-interface/trans.c (gnat_validate_uc_list): New variable.
(gigi): Call validate_unchecked_conversion on gnat_validate_uc_list
- after the translation is completed.  Call destroy_gnat_to_gnu and
+ after the translation is completed. Call destroy_gnat_to_gnu and
destroy_dummy_type at the end.
(Subprogram_Body_to_gnu): Do not call mark_out_of_scope.
(gnat_to_gnu) <N_Block_Statement>: Likewise.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 6f351d3..333d33b 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -5027,28 +5027,33 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (CONTAINS_PLACEHOLDER_P (gnu_size))
gnu_size = max_size (gnu_size, true);
- if (type_annotate_only && Is_Tagged_Type (gnat_entity))
+ /* 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
+ sizes must be adjusted if there is no representation clause. */
+ if (type_annotate_only
+ && Is_Tagged_Type (gnat_entity)
+ && !VOID_TYPE_P (gnu_type)
+ && (!TYPE_FIELDS (gnu_type)
+ || integer_zerop (bit_position (TYPE_FIELDS (gnu_type)))))
{
- /* In this mode, the tag and the parent components are not
- generated by the front-end so the sizes must be adjusted. */
tree pointer_size = bitsize_int (POINTER_SIZE), offset;
Uint uint_size;
if (Is_Derived_Type (gnat_entity))
{
- offset = UI_To_gnu (Esize (Etype (Base_Type (gnat_entity))),
- bitsizetype);
- Set_Alignment (gnat_entity,
- Alignment (Etype (Base_Type (gnat_entity))));
+ Entity_Id gnat_parent = Etype (Base_Type (gnat_entity));
+ offset = UI_To_gnu (Esize (gnat_parent), bitsizetype);
+ Set_Alignment (gnat_entity, Alignment (gnat_parent));
}
else
offset = pointer_size;
+ if (TYPE_FIELDS (gnu_type))
+ offset
+ = round_up (offset, DECL_ALIGN (TYPE_FIELDS (gnu_type)));
+
gnu_size = size_binop (PLUS_EXPR, gnu_size, offset);
- gnu_size = size_binop (MULT_EXPR, pointer_size,
- size_binop (CEIL_DIV_EXPR,
- gnu_size,
- pointer_size));
+ gnu_size = round_up (gnu_size, POINTER_SIZE);
uint_size = annotate_value (gnu_size);
Set_Esize (gnat_entity, uint_size);
Set_RM_Size (gnat_entity, uint_size);
@@ -6619,7 +6624,9 @@ maybe_pad_type (tree type, tree size, unsigned int align,
/* If the size was widened explicitly, maybe give a warning. Take the
original size as the maximum size of the input if there was an
unconstrained record involved and round it up to the specified alignment,
- if one was specified. */
+ if one was specified. But don't do it if we are just annotating types
+ and the type is tagged, since tagged types aren't fully laid out in this
+ mode. */
if (CONTAINS_PLACEHOLDER_P (orig_size))
orig_size = max_size (orig_size, true);
@@ -6635,7 +6642,8 @@ maybe_pad_type (tree type, tree size, unsigned int align,
&& TREE_CODE (orig_size) == INTEGER_CST
&& (TREE_OVERFLOW (size)
|| TREE_OVERFLOW (orig_size)
- || tree_int_cst_lt (size, orig_size))))
+ || tree_int_cst_lt (size, orig_size)))
+ && !(type_annotate_only && Is_Tagged_Type (Etype (gnat_entity))))
{
Node_Id gnat_error_node = Empty;
@@ -6901,10 +6909,13 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
}
}
- /* If this field needs strict alignment, ensure the record is
- sufficiently aligned and that that position and size are
- consistent with the alignment. */
- if (needs_strict_alignment)
+ /* If this field needs strict alignment, check that the record is
+ sufficiently aligned and that position and size are consistent
+ with the alignment. But don't do it if we are just annotating
+ types and the field's type is tagged, since tagged types aren't
+ fully laid out in this mode. */
+ if (needs_strict_alignment
+ && !(type_annotate_only && Is_Tagged_Type (gnat_field_type)))
{
TYPE_ALIGN (gnu_record_type)
= MAX (TYPE_ALIGN (gnu_record_type), TYPE_ALIGN (gnu_field_type));
@@ -7839,12 +7850,16 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
{
tree parent_offset;
- if (type_annotate_only && Is_Tagged_Type (gnat_entity))
+ /* 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
+ we need to add the appropriate offset to each component without
+ representation clause. */
+ if (type_annotate_only
+ && Is_Tagged_Type (gnat_entity)
+ && No (Component_Clause (gnat_field)))
{
- /* In this mode the tag and parent components are not
- generated, so we add the appropriate offset to each
- component. For a component appearing in the current
- extension, the offset is the size of the parent. */
+ /* 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
@@ -7852,6 +7867,11 @@ annotate_rep (Entity_Id gnat_entity, tree gnu_type)
bitsizetype);
else
parent_offset = bitsize_int (POINTER_SIZE);
+
+ if (TYPE_FIELDS (gnu_type))
+ parent_offset
+ = round_up (parent_offset,
+ DECL_ALIGN (TYPE_FIELDS (gnu_type)));
}
else
parent_offset = bitsize_zero_node;