diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2011-03-17 12:37:53 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-03-17 12:37:53 +0000 |
commit | bb1f792960e1dd896529286d2d2302491959d591 (patch) | |
tree | 0f84b2c4de3fdba8e07cd150c30e22214ec75896 /gcc/ada/gcc-interface/utils.c | |
parent | dabd47e701a73fca7f4e2495b5a86704bf0a1855 (diff) | |
download | gcc-bb1f792960e1dd896529286d2d2302491959d591.zip gcc-bb1f792960e1dd896529286d2d2302491959d591.tar.gz gcc-bb1f792960e1dd896529286d2d2302491959d591.tar.bz2 |
gigi.h (smaller_form_type_p): Declare.
* gcc-interface/gigi.h (smaller_form_type_p): Declare.
* gcc-interface/trans.c (smaller_form_type_p): Make global and move...
* gcc-interface/utils.c (smaller_form_type_p): ...to here.
(convert): Deal with conversions from a smaller form type specially.
From-SVN: r171091
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index eac87e0..4d40f86 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -4043,6 +4043,18 @@ convert (tree type, tree expr) } while (TREE_CODE (child_etype) == RECORD_TYPE); } + /* If we are converting from a smaller form of record type back to it, just + make a VIEW_CONVERT_EXPR. But first pad the expression to have the same + size on both sides. */ + else if (ecode == RECORD_TYPE && code == RECORD_TYPE + && smaller_form_type_p (etype, type)) + { + expr = convert (maybe_pad_type (etype, TYPE_SIZE (type), 0, Empty, + false, false, false, true), + expr); + return build1 (VIEW_CONVERT_EXPR, type, expr); + } + /* In all other cases of related types, make a NOP_EXPR. */ else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype)) return fold_convert (type, expr); @@ -4672,6 +4684,30 @@ type_for_nonaliased_component_p (tree gnu_type) return true; } +/* Return true if TYPE is a smaller form of ORIG_TYPE. */ + +bool +smaller_form_type_p (tree type, tree orig_type) +{ + tree size, osize; + + /* We're not interested in variants here. */ + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig_type)) + return false; + + /* Like a variant, a packable version keeps the original TYPE_NAME. */ + if (TYPE_NAME (type) != TYPE_NAME (orig_type)) + return false; + + size = TYPE_SIZE (type); + osize = TYPE_SIZE (orig_type); + + if (!(TREE_CODE (size) == INTEGER_CST && TREE_CODE (osize) == INTEGER_CST)) + return false; + + return tree_int_cst_lt (size, osize) != 0; +} + /* Perform final processing on global variables. */ void |