summaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/trans.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-06 10:41:03 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-06 10:41:03 +0000
commit76cb9822418b75842073fdd00d515385162e9480 (patch)
tree2b6e941a54364ab5cb9615c2ee43302a788c946f /gcc/ada/gcc-interface/trans.c
parentfb824021319e8f7bd8f9c08b1ef802d7de91d463 (diff)
downloadgcc-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.c62
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);