diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-06-27 09:16:45 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-06-27 09:16:45 +0000 |
commit | d9338c672687d1eea1aaf1a9593ba44f0ca14cad (patch) | |
tree | 20850ce6ad49a6f73566862cf73cc69563654f3c /gcc/ada/utils.c | |
parent | b7d565dd0098c3f2dbf7a4040ce188a99acbfe04 (diff) | |
download | gcc-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.c | 42 |
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: |