This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Ada] Small tweak to help GDB to display aliased dynamic array


> 2012-01-27  Eric Botcazou  <ebotcazou@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  <ebotcazou@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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]