diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-06-10 18:36:40 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-06-10 18:36:40 +0000 |
commit | a801596b627fbae8ca23d0d098b7b5c31ba30047 (patch) | |
tree | 05c191c3e0692e3f81ae4fa151888959b5108a53 /gcc/ada/utils.c | |
parent | 676792f6faa9b49fa90404248a3771719858c97d (diff) | |
download | gcc-a801596b627fbae8ca23d0d098b7b5c31ba30047.tar.gz |
* decl.c (gnat_to_gnu_entity): Use pointers to dummy nodes, rather
than to void, for the fields when making a new fat pointer type.
(gnat_substitute_in_type): Now substitute_in_type.
* gigi.h (gnat_substitute_in_type): Likewise.
* trans.c (gnat_gimplify_expr): Remove COMPONENT_REF kludge.
* utils.c (update_pointer_to): Update fat pointers by updating the
dummy node pointers used for the fields.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125602 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/utils.c')
-rw-r--r-- | gcc/ada/utils.c | 81 |
1 files changed, 35 insertions, 46 deletions
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c index 69d4a887b8d..a8a673c06de 100644 --- a/gcc/ada/utils.c +++ b/gcc/ada/utils.c @@ -3160,75 +3160,64 @@ update_pointer_to (tree old_type, tree new_type) } /* Now deal with the unconstrained array case. In this case the "pointer" - is actually a RECORD_TYPE where the types of both fields are - pointers to void. In that case, copy the field list from the - old type to the new one and update the fields' context. */ + is actually a RECORD_TYPE where both fields are pointers to dummy nodes. + Turn them into pointers to the correct types using update_pointer_to. */ else if (TREE_CODE (ptr) != RECORD_TYPE || !TYPE_IS_FAT_POINTER_P (ptr)) gcc_unreachable (); else { tree new_obj_rec = TYPE_OBJECT_RECORD_TYPE (new_type); - tree fields = TYPE_FIELDS (TYPE_POINTER_TO (new_type)); - tree new_fields, ptr_temp_type, new_ref, bounds, var; - - /* Replace contents of old pointer with those of new pointer. */ - new_fields = copy_node (fields); - TREE_CHAIN (new_fields) = copy_node (TREE_CHAIN (fields)); - - SET_DECL_ORIGINAL_FIELD (TYPE_FIELDS (ptr), new_fields); - SET_DECL_ORIGINAL_FIELD (TREE_CHAIN (TYPE_FIELDS (ptr)), - TREE_CHAIN (new_fields)); - - TYPE_FIELDS (ptr) = new_fields; - DECL_CONTEXT (new_fields) = ptr; - DECL_CONTEXT (TREE_CHAIN (new_fields)) = ptr; - - /* Rework the PLACEHOLDER_EXPR inside the reference to the template - bounds and update the pointers to them. - - ??? This is now the only use of gnat_substitute_in_type, which - is now a very "heavy" routine to do this, so it should be replaced - at some point. */ - bounds = TREE_TYPE (TREE_TYPE (new_fields)); - ptr_temp_type = TREE_TYPE (TREE_CHAIN (new_fields)); - new_ref = build3 (COMPONENT_REF, ptr_temp_type, + tree array_field = TYPE_FIELDS (ptr); + tree bounds_field = TREE_CHAIN (TYPE_FIELDS (ptr)); + tree new_ptr = TYPE_POINTER_TO (new_type); + tree new_ref; + tree var; + + /* Make pointers to the dummy template point to the real template. */ + update_pointer_to + (TREE_TYPE (TREE_TYPE (bounds_field)), + TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_ptr))))); + + /* The references to the template bounds present in the array type + are made through a PLACEHOLDER_EXPR of type new_ptr. Since we + are updating ptr to make it a full replacement for new_ptr as + pointer to new_type, we must rework the PLACEHOLDER_EXPR so as + to make it of type ptr. */ + new_ref = build3 (COMPONENT_REF, TREE_TYPE (bounds_field), build0 (PLACEHOLDER_EXPR, ptr), - TREE_CHAIN (new_fields), NULL_TREE); - update_pointer_to (bounds, - gnat_substitute_in_type (bounds, - TREE_CHAIN (fields), - new_ref)); + bounds_field, NULL_TREE); - for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var)) - { - SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type); + /* Create the new array for the new PLACEHOLDER_EXPR and make + pointers to the dummy array point to it. - /* This may seem a bit gross, in particular wrt DECL_CONTEXT, but - actually is in keeping with what build_qualified_type does. */ - TYPE_FIELDS (var) = new_fields; - } + ??? This is now the only use of substitute_in_type, + which is a very "heavy" routine to do this, so it + should be replaced at some point. */ + update_pointer_to + (TREE_TYPE (TREE_TYPE (array_field)), + substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))), + TREE_CHAIN (TYPE_FIELDS (new_ptr)), new_ref)); + /* Make ptr the pointer to new_type. */ TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type) = TREE_TYPE (new_type) = ptr; + for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var)) + SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type); + /* Now handle updating the allocation record, what the thin pointer points to. Update all pointers from the old record into the new - one, update the types of the fields, and recompute the size. */ - + one, update the type of the array field, and recompute the size. */ update_pointer_to (TYPE_OBJECT_RECORD_TYPE (old_type), new_obj_rec); - TREE_TYPE (TYPE_FIELDS (new_obj_rec)) - = TREE_TYPE (TREE_TYPE (TREE_CHAIN (new_fields))); - TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))) - = TREE_TYPE (TREE_TYPE (new_fields)); + = TREE_TYPE (TREE_TYPE (array_field)); /* The size recomputation needs to account for alignment constraints, so we let layout_type work it out. This will reset the field offsets to what they would be in a regular record, so we shift them back to what we want them to be for a thin pointer designated type afterwards. */ - DECL_SIZE (TYPE_FIELDS (new_obj_rec)) = 0; DECL_SIZE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))) = 0; TYPE_SIZE (new_obj_rec) = 0; |