aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-06-27 09:16:45 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-06-27 09:16:45 +0000
commitd9338c672687d1eea1aaf1a9593ba44f0ca14cad (patch)
tree20850ce6ad49a6f73566862cf73cc69563654f3c /gcc/ada/utils.c
parentb7d565dd0098c3f2dbf7a4040ce188a99acbfe04 (diff)
downloadgcc-d9338c672687d1eea1aaf1a9593ba44f0ca14cad.zip
gcc-d9338c672687d1eea1aaf1a9593ba44f0ca14cad.tar.gz
gcc-d9338c672687d1eea1aaf1a9593ba44f0ca14cad.tar.bz2
utils.c (convert): When converting it to a packable version of its type...
* utils.c (convert) <CONSTRUCTOR>: When converting it to a packable version of its type, attempt to first convert its elements. From-SVN: r137173
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r--gcc/ada/utils.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index f255d37..92e8348 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -3579,17 +3579,47 @@ 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. Likewise for a conversion between
- original and packable version. */
- if (code == ecode
- && (gnat_types_compatible_p (type, etype)
- || (code == RECORD_TYPE
- && TYPE_NAME (type) == TYPE_NAME (etype))))
+ a new one in the proper type. */
+ if (code == ecode && gnat_types_compatible_p (type, etype))
{
expr = copy_node (expr);
TREE_TYPE (expr) = type;
return expr;
}
+
+ /* Likewise for a conversion between original and packable version, but
+ we have to work harder in order to preserve type consistency. */
+ if (code == ecode
+ && code == RECORD_TYPE
+ && TYPE_NAME (type) == TYPE_NAME (etype))
+ {
+ VEC(constructor_elt,gc) *e = CONSTRUCTOR_ELTS (expr);
+ unsigned HOST_WIDE_INT len = VEC_length (constructor_elt, e);
+ VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, len);
+ tree efield = TYPE_FIELDS (etype), field = TYPE_FIELDS (type);
+ unsigned HOST_WIDE_INT idx;
+ tree index, value;
+
+ FOR_EACH_CONSTRUCTOR_ELT(e, idx, index, value)
+ {
+ constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
+ /* We expect only simple constructors. Otherwise, punt. */
+ if (!(index == efield || index == DECL_ORIGINAL_FIELD (efield)))
+ break;
+ elt->index = field;
+ elt->value = convert (TREE_TYPE (field), value);
+ efield = TREE_CHAIN (efield);
+ field = TREE_CHAIN (field);
+ }
+
+ if (idx == len)
+ {
+ expr = copy_node (expr);
+ TREE_TYPE (expr) = type;
+ CONSTRUCTOR_ELTS (expr) = v;
+ return expr;
+ }
+ }
break;
case UNCONSTRAINED_ARRAY_REF: