aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-04-13 07:21:15 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-04-13 07:21:15 +0000
commit76af763dfeb704b85edf79c87dfda0cead34d698 (patch)
tree4257299e64b5687a21f011613e5caeb13a2139dc /gcc/ada/gcc-interface/utils.c
parentcb3d597d15475a12d37a3c01dc7f8e12d2c9eff1 (diff)
downloadgcc-76af763dfeb704b85edf79c87dfda0cead34d698.zip
gcc-76af763dfeb704b85edf79c87dfda0cead34d698.tar.gz
gcc-76af763dfeb704b85edf79c87dfda0cead34d698.tar.bz2
gigi.h (standard_datatypes): Add ADT_parent_name_id.
* gcc-interface/gigi.h (standard_datatypes): Add ADT_parent_name_id. (parent_name_id): New macro. * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: Use it. * gcc-interface/trans.c (gigi): Initialize it. (lvalue_required_p) <N_Type_Conversion>: New case. <N_Qualified_Expression>: Likewise. <N_Allocator>: Likewise. * gcc-interface/utils.c (convert): Try to properly upcast tagged types. From-SVN: r158255
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 7353bdc..335941a2 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4027,6 +4027,19 @@ convert (tree type, tree expr)
etype)))
return build1 (VIEW_CONVERT_EXPR, type, expr);
+ /* If we are converting between tagged types, try to upcast properly. */
+ else if (ecode == RECORD_TYPE && code == RECORD_TYPE
+ && TYPE_ALIGN_OK (etype) && TYPE_ALIGN_OK (type))
+ {
+ tree child_etype = etype;
+ do {
+ tree field = TYPE_FIELDS (child_etype);
+ if (DECL_NAME (field) == parent_name_id && TREE_TYPE (field) == type)
+ return build_component_ref (expr, NULL_TREE, field, false);
+ child_etype = TREE_TYPE (field);
+ } while (TREE_CODE (child_etype) == RECORD_TYPE);
+ }
+
/* In all other cases of related types, make a NOP_EXPR. */
else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype)
|| (code == INTEGER_CST && ecode == INTEGER_CST