diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-05-06 10:41:03 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-05-06 10:41:03 +0000 |
commit | 76cb9822418b75842073fdd00d515385162e9480 (patch) | |
tree | 2b6e941a54364ab5cb9615c2ee43302a788c946f /gcc/ada/gcc-interface/trans.c | |
parent | fb824021319e8f7bd8f9c08b1ef802d7de91d463 (diff) | |
download | gcc-76cb9822418b75842073fdd00d515385162e9480.tar.gz |
* gcc-interface/gigi.h (make_packable_type): Declare.
(make_type_from_size): Likewise.
(relate_alias_sets): Likewise.
(maybe_pad_type): Adjust.
(init_gnat_to_gnu): Delete.
(destroy_gnat_to_gnu): Likewise.
(init_dummy_type): Likewise.
(destroy_dummy_type): Likewise.
(init_gnat_utils): Declare.
(destroy_gnat_utils): Likewise.
(ceil_pow2): New inline function.
* gcc-interface/decl.c (gnat_to_gnu_entity): Use ceil_pow2.
<object>: Pass True for the final processing of alignment and size.
<E_Subprogram_Type>: Only create the TYPE_DECL for a padded return
type if necessary.
(round_up_to_align): Delete.
(ceil_alignment): Likewise.
(relate_alias_sets): Move to...
(make_aligning_type): Likewise.
(make_packable_type): Likewise.
(maybe_pad_type): Likewise.
(make_type_from_size): Likewise.
* gcc-interface/utils.c (MAX_BITS_PER_WORD): Delete.
(struct pad_type_hash): New type.
(pad_type_hash_table): New static variable.
(init_gnat_to_gnu): Merge into...
(init_dummy_type): Likewise.
(init_gnat_utils): ...this. New function.
(destroy_gnat_to_gnu): Merge into...
(destroy_dummy_type): Likewise.
(destroy_gnat_utils): ...this. New function.
(pad_type_hash_marked_p): New function.
(pad_type_hash_hash): Likewise.
(pad_type_hash_eq): Likewise.
(relate_alias_sets): ...here.
(make_aligning_type): Likewise.
(make_packable_type): Likewise.
(maybe_pad_type): Likewise. Change same_rm_size parameter into
set_rm_size; do not set TYPE_ADA_SIZE if it is false. Do not set
null as Ada size. Do not set TYPE_VOLATILE on the padded type. If it
is complete and has constant size, canonicalize it. Bail out earlier
if a warning need not be issued.
(make_type_from_size): Likewise.
<INTEGER_TYPE>: Bail out if size is too large
(gnat_types_compatible_p): Do not deal with padded types.
(convert): Compare main variants for padded types.
* gcc-interface/trans.c (gigi): Call {init|destroy}_gnat_utils.
(gnat_to_gnu): Do not convert at the end for a call to a function that
returns an unconstrained type with default discriminant.
(Attribute_to_gnu) <Attr_Size>: Simplify handling of padded objects.
* gcc-interface/utils2.c (build_binary_op) <MODIFY_EXPR>: Likewise.
Do not use the padded type if it is BLKmode and the inner type is
non-BLKmode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187206 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 62 |
1 files changed, 23 insertions, 39 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 3698dcaf2a4..fb4a2cd5ffe 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -338,8 +338,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED, /* Initialize ourselves. */ init_code_table (); - init_gnat_to_gnu (); - init_dummy_type (); + init_gnat_utils (); /* If we are just annotating types, give VOID_TYPE zero sizes to avoid errors. */ @@ -685,8 +684,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED, } /* Destroy ourselves. */ - destroy_gnat_to_gnu (); - destroy_dummy_type (); + destroy_gnat_utils (); /* We cannot track the location of errors past this point. */ error_gnat_node = Empty; @@ -1501,34 +1499,25 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) gnu_type = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type))); } - /* If we're looking for the size of a field, return the field size. - Otherwise, if the prefix is an object, or if we're looking for - 'Object_Size or 'Max_Size_In_Storage_Elements, the result is the - GCC size of the type. Otherwise, it is the RM size of the type. */ + /* If we're looking for the size of a field, return the field size. */ if (TREE_CODE (gnu_prefix) == COMPONENT_REF) gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1)); - else if (TREE_CODE (gnu_prefix) != TYPE_DECL + + /* Otherwise, if the prefix is an object, or if we are looking for + 'Object_Size or 'Max_Size_In_Storage_Elements, the result is the + GCC size of the type. We make an exception for padded objects, + as we do not take into account alignment promotions for the size. + This is in keeping with the object case of gnat_to_gnu_entity. */ + else if ((TREE_CODE (gnu_prefix) != TYPE_DECL + && !(TYPE_IS_PADDING_P (gnu_type) + && TREE_CODE (gnu_expr) == COMPONENT_REF)) || attribute == Attr_Object_Size || attribute == Attr_Max_Size_In_Storage_Elements) { - /* If the prefix is an object of a padded type, the GCC size isn't - relevant to the programmer. Normally what we want is the RM size, - which was set from the specified size, but if it was not set, we - want the size of the field. Using the MAX of those two produces - the right result in all cases. Don't use the size of the field - if it's self-referential, since that's never what's wanted. */ - if (TREE_CODE (gnu_prefix) != TYPE_DECL - && TYPE_IS_PADDING_P (gnu_type) - && TREE_CODE (gnu_expr) == COMPONENT_REF) - { - gnu_result = rm_size (gnu_type); - if (!CONTAINS_PLACEHOLDER_P - (DECL_SIZE (TREE_OPERAND (gnu_expr, 1)))) - gnu_result - = size_binop (MAX_EXPR, gnu_result, - DECL_SIZE (TREE_OPERAND (gnu_expr, 1))); - } - else if (Nkind (Prefix (gnat_node)) == N_Explicit_Dereference) + /* If this is a dereference and we have a special dynamic constrained + subtype on the prefix, use it to compute the size; otherwise, use + the designated subtype. */ + if (Nkind (Prefix (gnat_node)) == N_Explicit_Dereference) { Node_Id gnat_deref = Prefix (gnat_node); Node_Id gnat_actual_subtype @@ -1547,12 +1536,12 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) get_identifier ("SIZE"), false); } - - gnu_result = TYPE_SIZE (gnu_type); } - else - gnu_result = TYPE_SIZE (gnu_type); + + gnu_result = TYPE_SIZE (gnu_type); } + + /* Otherwise, the result is the RM size of the type. */ else gnu_result = rm_size (gnu_type); @@ -6921,15 +6910,10 @@ gnat_to_gnu (Node_Id gnat_node) else if (TREE_CODE (gnu_result) == CALL_EXPR && TYPE_IS_PADDING_P (TREE_TYPE (gnu_result)) + && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))) + == gnu_result_type && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))) - { - /* ??? We need to convert if the padded type has fixed size because - gnat_types_compatible_p will say that padded types are compatible - but the gimplifier will not and, therefore, will ultimately choke - if there isn't a conversion added early. */ - if (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_result))) == INTEGER_CST) - gnu_result = convert (gnu_result_type, gnu_result); - } + ; else if (TREE_TYPE (gnu_result) != gnu_result_type) gnu_result = convert (gnu_result_type, gnu_result); |