diff options
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 76 |
1 files changed, 36 insertions, 40 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 860e0dc..cd6626f 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1415,14 +1415,14 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) case Attr_Pool_Address: { - tree gnu_obj_type; tree gnu_ptr = gnu_prefix; + tree gnu_obj_type; gnu_result_type = get_unpadded_type (Etype (gnat_node)); - /* If this is an unconstrained array, we know the object has been - allocated with the template in front of the object. So compute - the template address. */ + /* If this is fat pointer, the object must have been allocated with the + template in front of the array. So compute the template address; do + it by converting to a thin pointer. */ if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr))) gnu_ptr = convert (build_pointer_type @@ -1431,16 +1431,15 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) gnu_ptr); gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr)); - if (TREE_CODE (gnu_obj_type) == RECORD_TYPE - && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type)) - { - tree gnu_char_ptr_type - = build_pointer_type (unsigned_char_type_node); - tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type)); - gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr); - gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type, - gnu_ptr, gnu_pos); - } + + /* If this is a thin pointer, the object must have been allocated with + the template in front of the array. So compute the template address + and return it. */ + if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr))) + gnu_ptr + = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr), + gnu_ptr, + byte_position (TYPE_FIELDS (gnu_obj_type))); gnu_result = convert (gnu_result_type, gnu_ptr); } @@ -6593,23 +6592,20 @@ gnat_to_gnu (Node_Id gnat_node) { tree gnu_ptr = gnat_to_gnu (Expression (gnat_node)); tree gnu_ptr_type = TREE_TYPE (gnu_ptr); - tree gnu_obj_type; - tree gnu_actual_obj_type = 0; - tree gnu_obj_size; - - /* If this is a thin pointer, we must dereference it to create - a fat pointer, then go back below to a thin pointer. The - reason for this is that we need a fat pointer someplace in - order to properly compute the size. */ + tree gnu_obj_type, gnu_actual_obj_type; + + /* If this is a thin pointer, we must first dereference it to create + a fat pointer, then go back below to a thin pointer. The reason + for this is that we need to have a fat pointer someplace in order + to properly compute the size. */ if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr))) gnu_ptr = build_unary_op (ADDR_EXPR, NULL_TREE, build_unary_op (INDIRECT_REF, NULL_TREE, gnu_ptr)); - /* If this is an unconstrained array, we know the object must - have been allocated with the template in front of the object. - So pass the template address, but get the total size. Do this - by converting to a thin pointer. */ + /* If this is a fat pointer, the object must have been allocated with + the template in front of the array. So pass the template address, + and get the total size; do it by converting to a thin pointer. */ if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr))) gnu_ptr = convert (build_pointer_type @@ -6619,6 +6615,17 @@ gnat_to_gnu (Node_Id gnat_node) gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr)); + /* If this is a thin pointer, the object must have been allocated with + the template in front of the array. So pass the template address, + and get the total size. */ + if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr))) + gnu_ptr + = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr), + gnu_ptr, + byte_position (TYPE_FIELDS (gnu_obj_type))); + + /* If we have a special dynamic constrained subtype on the node, use + it to compute the size; otherwise, use the designated subtype. */ if (Present (Actual_Designated_Subtype (gnat_node))) { gnu_actual_obj_type @@ -6634,21 +6641,10 @@ gnat_to_gnu (Node_Id gnat_node) else gnu_actual_obj_type = gnu_obj_type; - gnu_obj_size = TYPE_SIZE_UNIT (gnu_actual_obj_type); - - if (TREE_CODE (gnu_obj_type) == RECORD_TYPE - && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type)) - { - tree gnu_char_ptr_type - = build_pointer_type (unsigned_char_type_node); - tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type)); - gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr); - gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type, - gnu_ptr, gnu_pos); - } - gnu_result - = build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, gnu_obj_type, + = build_call_alloc_dealloc (gnu_ptr, + TYPE_SIZE_UNIT (gnu_actual_obj_type), + gnu_obj_type, Procedure_To_Call (gnat_node), Storage_Pool (gnat_node), gnat_node); |