From b38086f06abab6f679bc6e63d833b8d853a5e04f Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 30 Apr 2012 08:31:29 +0000 Subject: [PATCH] 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 --- gcc/ada/ChangeLog | 14 +++++++- gcc/ada/gcc-interface/decl.c | 64 +++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 838e4d0f6a8..31d5ac41874 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,15 @@ +2012-04-30 Eric Botcazou + + * 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 * gcc-interface/utils.c (finish_record_type): Force the traditional GCC @@ -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) : Likewise. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 6f351d3db2e..333d33b307e 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; -- 2.30.2