aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2014-01-20 10:51:46 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2014-01-20 10:51:46 +0000
commit44e9e3ec85bf048bcb73f7a013afbd573466972e (patch)
tree0abf9652349928c6a4a433eef4046071074ba0cb /gcc/ada/gcc-interface/utils.c
parent59f5c969a5c5ac08e450ae74c260d57db574a5d0 (diff)
downloadgcc-44e9e3ec85bf048bcb73f7a013afbd573466972e.zip
gcc-44e9e3ec85bf048bcb73f7a013afbd573466972e.tar.gz
gcc-44e9e3ec85bf048bcb73f7a013afbd573466972e.tar.bz2
decl.c (gnat_to_gnu_entity): Tidy up.
* gcc-interface/decl.c (gnat_to_gnu_entity) <case E_Record_Subtype>: Tidy up. For a subtype with discriminants and variant part, if a variant is statically selected and the fields all have a constant position, put them in order of increasing position. Likewise if no variant part but representation clause is present. * gcc-interface/utils.c (make_packable_type): Robustify. (maybe_pad_type): Use local variable and tidy up condition. If no alignment is specified, use the original one. (create_type_stub_decl): Minor tweak. (convert) <case VECTOR_CST>: Fix typo. <case CONSTRUCTOR>: Deal with padding types around the same type. Do not punt on missing fields. (unchecked_convert): Call finish_record_type to lay out the special record types made for conversions from/to problematic integer types. Bump the alignment of CONSTRUCTORs before converting them to a more aligned type. From-SVN: r206796
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c79
1 files changed, 49 insertions, 30 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 36e5b2d..69ea026 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2013, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2014, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
@@ -869,8 +869,9 @@ make_packable_type (tree type, bool in_record)
finish_record_type (new_type, nreverse (field_list), 2, false);
relate_alias_sets (new_type, type, ALIAS_SET_COPY);
- SET_DECL_PARALLEL_TYPE (TYPE_STUB_DECL (new_type),
- DECL_PARALLEL_TYPE (TYPE_STUB_DECL (type)));
+ if (TYPE_STUB_DECL (type))
+ SET_DECL_PARALLEL_TYPE (TYPE_STUB_DECL (new_type),
+ DECL_PARALLEL_TYPE (TYPE_STUB_DECL (type)));
/* If this is a padding record, we never want to make the size smaller
than what was specified. For QUAL_UNION_TYPE, also copy the size. */
@@ -1049,6 +1050,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
bool is_user_type, bool definition, bool set_rm_size)
{
tree orig_size = TYPE_SIZE (type);
+ unsigned int orig_align = TYPE_ALIGN (type);
tree record, field;
/* If TYPE is a padded type, see if it agrees with any size and alignment
@@ -1059,21 +1061,18 @@ maybe_pad_type (tree type, tree size, unsigned int align,
if (TYPE_IS_PADDING_P (type))
{
if ((!size
- || operand_equal_p (round_up (size,
- MAX (align, TYPE_ALIGN (type))),
- round_up (TYPE_SIZE (type),
- MAX (align, TYPE_ALIGN (type))),
- 0))
- && (align == 0 || align == TYPE_ALIGN (type)))
+ || operand_equal_p (round_up (size, orig_align), orig_size, 0))
+ && (align == 0 || align == orig_align))
return type;
if (!size)
- size = TYPE_SIZE (type);
+ size = orig_size;
if (align == 0)
- align = TYPE_ALIGN (type);
+ align = orig_align;
type = TREE_TYPE (TYPE_FIELDS (type));
orig_size = TYPE_SIZE (type);
+ orig_align = TYPE_ALIGN (type);
}
/* If the size is either not being changed or is being made smaller (which
@@ -1086,7 +1085,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
&& tree_int_cst_lt (size, orig_size))))
size = NULL_TREE;
- if (align == TYPE_ALIGN (type))
+ if (align == orig_align)
align = 0;
if (align == 0 && !size)
@@ -1110,7 +1109,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
if (Present (gnat_entity))
TYPE_NAME (record) = create_concat_name (gnat_entity, "PAD");
- TYPE_ALIGN (record) = align;
+ TYPE_ALIGN (record) = align ? align : orig_align;
TYPE_SIZE (record) = size ? size : orig_size;
TYPE_SIZE_UNIT (record)
= convert (sizetype,
@@ -2063,8 +2062,7 @@ create_type_stub_decl (tree type_name, tree type)
/* Using a named TYPE_DECL ensures that a type name marker is emitted in
STABS while setting DECL_ARTIFICIAL ensures that no DW_TAG_typedef is
emitted in DWARF. */
- tree type_decl = build_decl (input_location,
- TYPE_DECL, type_name, type);
+ tree type_decl = build_decl (input_location, TYPE_DECL, type_name, type);
DECL_ARTIFICIAL (type_decl) = 1;
TYPE_ARTIFICIAL (type) = 1;
return type_decl;
@@ -4626,7 +4624,7 @@ convert (tree type, tree expr)
break;
case VECTOR_CST:
- /* If we are converting a VECTOR_CST to a mere variant type, just make
+ /* If we are converting a VECTOR_CST to a mere type variant, just make
a new one in the proper type. */
if (code == ecode && gnat_types_compatible_p (type, etype))
{
@@ -4636,9 +4634,15 @@ convert (tree type, tree expr)
}
case CONSTRUCTOR:
- /* If we are converting a CONSTRUCTOR to a mere variant type, just make
- a new one in the proper type. */
- if (code == ecode && gnat_types_compatible_p (type, etype))
+ /* If we are converting a CONSTRUCTOR to a mere type variant, or to
+ another padding type around the same type, just make a new one in
+ the proper type. */
+ if (code == ecode
+ && (gnat_types_compatible_p (type, etype)
+ || (code == RECORD_TYPE
+ && TYPE_PADDING_P (type) && TYPE_PADDING_P (etype)
+ && TREE_TYPE (TYPE_FIELDS (type))
+ == TREE_TYPE (TYPE_FIELDS (etype)))))
{
expr = copy_node (expr);
TREE_TYPE (expr) = type;
@@ -4669,13 +4673,17 @@ convert (tree type, tree expr)
FOR_EACH_CONSTRUCTOR_ELT(e, idx, index, value)
{
- /* We expect only simple constructors. */
- if (!SAME_FIELD_P (index, efield))
- break;
+ /* Skip the missing fields in the CONSTRUCTOR. */
+ while (efield && field && !SAME_FIELD_P (efield, index))
+ {
+ efield = DECL_CHAIN (efield);
+ field = DECL_CHAIN (field);
+ }
/* The field must be the same. */
- if (!SAME_FIELD_P (efield, field))
+ if (!(efield && field && SAME_FIELD_P (efield, field)))
break;
- constructor_elt elt = {field, convert (TREE_TYPE (field), value)};
+ constructor_elt elt
+ = {field, convert (TREE_TYPE (field), value)};
v->quick_push (elt);
/* If packing has made this field a bitfield and the input
@@ -5321,10 +5329,9 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
SET_TYPE_RM_SIZE (field_type, TYPE_RM_SIZE (type));
field = create_field_decl (get_identifier ("OBJ"), field_type, rec_type,
- NULL_TREE, NULL_TREE, 1, 0);
+ NULL_TREE, bitsize_zero_node, 1, 0);
- TYPE_FIELDS (rec_type) = field;
- layout_type (rec_type);
+ finish_record_type (rec_type, field, 1, false);
expr = unchecked_convert (rec_type, expr, notrunc_p);
expr = build_component_ref (expr, NULL_TREE, field, false);
@@ -5352,10 +5359,9 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
SET_TYPE_RM_SIZE (field_type, TYPE_RM_SIZE (etype));
field = create_field_decl (get_identifier ("OBJ"), field_type, rec_type,
- NULL_TREE, NULL_TREE, 1, 0);
+ NULL_TREE, bitsize_zero_node, 1, 0);
- TYPE_FIELDS (rec_type) = field;
- layout_type (rec_type);
+ finish_record_type (rec_type, field, 1, false);
expr = fold_build1 (NOP_EXPR, field_type, expr);
CONSTRUCTOR_APPEND_ELT (v, field, expr);
@@ -5412,6 +5418,19 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
etype))
expr = convert (type, expr);
+ /* If we are converting a CONSTRUCTOR to a more aligned RECORD_TYPE, bump
+ the alignment of the CONSTRUCTOR to speed up the copy operation. */
+ else if (TREE_CODE (expr) == CONSTRUCTOR
+ && code == RECORD_TYPE
+ && TYPE_ALIGN (etype) < TYPE_ALIGN (type))
+ {
+ expr = convert (maybe_pad_type (etype, NULL_TREE, TYPE_ALIGN (type),
+ Empty, false, false, false, true),
+ expr);
+ return unchecked_convert (type, expr, notrunc_p);
+ }
+
+ /* Otherwise, just build a VIEW_CONVERT_EXPR of the expression. */
else
{
expr = maybe_unconstrained_array (expr);