> 2012-01-27 Eric Botcazou <ebotca...@adacore.com> > > * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: For an aliased > object with an unconstrained nominal subtype and if optimization isn't > enabled, create a special VAR_DECL for debugging purposes.
Unfortunately this isn't robust, so the attached patch is needed instead. Tested on i586-suse-linux, applied on the mainline. 2012-02-27 Eric Botcazou <ebotca...@adacore.com> * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Revert previous change that creates a special VAR_DECL for debugging purposes. For an aliased object with an unconstrained nominal subtype, make its type a thin reference to the underlying object. * gcc-interface/utils2.c (build_unary_op) <INDIRECT_REF>: Deal with expressions built for the initialization of above objects. -- Eric Botcazou
Index: gcc-interface/decl.c =================================================================== --- gcc-interface/decl.c (revision 184585) +++ gcc-interface/decl.c (working copy) @@ -1379,6 +1379,49 @@ gnat_to_gnu_entity (Entity_Id gnat_entit const_flag = true; } + /* If this is an aliased object with an unconstrained nominal subtype, + we make its type a thin reference, i.e. the reference counterpart + of a thin pointer, so that it points to the array part. This is + aimed at making it easier for the debugger to decode the object. + Note that we have to do that this late because of the couple of + allocation adjustments that might be made just above. */ + if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity)) + && Is_Array_Type (Etype (gnat_entity)) + && !type_annotate_only) + { + tree gnu_array + = gnat_to_gnu_type (Base_Type (Etype (gnat_entity))); + + /* In case the object with the template has already been allocated + just above, we have nothing to do here. */ + if (!TYPE_IS_THIN_POINTER_P (gnu_type)) + { + gnu_size = NULL_TREE; + used_by_ref = true; + + if (definition && !imported_p) + { + tree gnu_unc_var + = create_var_decl (concat_name (gnu_entity_name, "UNC"), + NULL_TREE, gnu_type, gnu_expr, + const_flag, Is_Public (gnat_entity), + false, static_p, NULL, gnat_entity); + gnu_expr + = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_unc_var); + TREE_CONSTANT (gnu_expr) = 1; + const_flag = true; + } + else + { + gnu_expr = NULL_TREE; + const_flag = false; + } + } + + gnu_type + = build_reference_type (TYPE_OBJECT_RECORD_TYPE (gnu_array)); + } + if (const_flag) gnu_type = build_qualified_type (gnu_type, (TYPE_QUALS (gnu_type) | TYPE_QUAL_CONST)); @@ -1469,41 +1512,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entit } } - /* If this is an aliased object with an unconstrained nominal subtype - and optimization isn't enabled, create a VAR_DECL for debugging - purposes whose type is a thin reference (the reference counterpart - of a thin pointer), so that it will be directly initialized to the - address of the array part. */ - else if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity)) - && Is_Array_Type (Etype (gnat_entity)) - && !type_annotate_only - && !optimize - && debug_info_p) - { - tree gnu_array - = gnat_to_gnu_type (Base_Type (Etype (gnat_entity))); - tree gnu_thin_type - = build_reference_type (TYPE_OBJECT_RECORD_TYPE (gnu_array)); - tree gnu_ref, gnu_debug_decl; - - /* In case the object with the template has already been indirectly - allocated, we have nothing to do here. */ - if (TYPE_IS_THIN_POINTER_P (gnu_type)) - gnu_ref = gnu_decl; - else - gnu_ref = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_decl); - gnu_ref = convert (gnu_thin_type, gnu_ref); - - gnu_debug_decl - = create_var_decl (gnu_entity_name, gnu_ext_name, - gnu_thin_type, NULL_TREE, const_flag, - Is_Public (gnat_entity), !definition, - static_p, attr_list, gnat_entity); - SET_DECL_VALUE_EXPR (gnu_debug_decl, gnu_ref); - DECL_HAS_VALUE_EXPR_P (gnu_debug_decl) = 1; - DECL_IGNORED_P (gnu_decl) = 1; - } - /* If this is a constant and we are defining it or it generates a real symbol at the object level and we are referencing it, we may want or need to have a true variable to represent it: Index: gcc-interface/utils2.c =================================================================== --- gcc-interface/utils2.c (revision 184585) +++ gcc-interface/utils2.c (working copy) @@ -1365,8 +1365,8 @@ build_unary_op (enum tree_code op_code, default: common: - /* If we are taking the address of a padded record whose field is - contains a template, take the address of the template. */ + /* If we are taking the address of a padded record whose field + contains a template, take the address of the field. */ if (TYPE_IS_PADDING_P (type) && TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == RECORD_TYPE && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (TYPE_FIELDS (type)))) @@ -1387,14 +1387,30 @@ build_unary_op (enum tree_code op_code, tree t = remove_conversions (operand, false); bool can_never_be_null = DECL_P (t) && DECL_CAN_NEVER_BE_NULL_P (t); - /* If TYPE is a thin pointer, first convert to the fat pointer. */ - if (TYPE_IS_THIN_POINTER_P (type) - && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))) + /* If TYPE is a thin pointer, either first retrieve the base if this + is an expression with an offset built for the initialization of an + object with an unconstrained nominal subtype, or else convert to + the fat pointer. */ + if (TYPE_IS_THIN_POINTER_P (type)) { - operand = convert - (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))), - operand); - type = TREE_TYPE (operand); + tree rec_type = TREE_TYPE (type); + + if (TREE_CODE (operand) == POINTER_PLUS_EXPR + && integer_zerop + (size_binop (PLUS_EXPR, TREE_OPERAND (operand, 1), + DECL_FIELD_OFFSET (TYPE_FIELDS (rec_type)))) + && TREE_CODE (TREE_OPERAND (operand, 0)) == NOP_EXPR) + { + operand = TREE_OPERAND (TREE_OPERAND (operand, 0), 0); + type = TREE_TYPE (operand); + } + else if (TYPE_UNCONSTRAINED_ARRAY (rec_type)) + { + operand + = convert (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (rec_type)), + operand); + type = TREE_TYPE (operand); + } } /* If we want to refer to an unconstrained array, use the appropriate