This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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: [patch] DW_AT_byte_size for array type entries


On Tuesday, November 02, 2010 11:31:03 pm Tom Tromey wrote:
> >>>>> "Ken" == Ken Werner <ken@linux.vnet.ibm.com> writes:
> Ken> Index: gdb/c-valprint.c
> Ken> ===================================================================
> Ken> RCS file: /cvs/src/src/gdb/c-valprint.c,v
> Ken> retrieving revision 1.74
> Ken> diff -p -u -r1.74 c-valprint.c
> Ken> --- gdb/c-valprint.c	15 Oct 2010 18:54:12 -0000	1.74
> Ken> +++ gdb/c-valprint.c	19 Oct 2010 12:15:30 -0000
> Ken> @@ -171,8 +171,13 @@ c_val_print (struct type *type, const gd
> Ken>        elttype = check_typedef (unresolved_elttype);
> Ken>        if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype)
> > 0) Ken>  	{
> Ken> +          LONGEST low_bound, high_bound;
> Ken> +
> Ken> +          if (!get_array_bounds(type, &low_bound, &high_bound))
> 
> Missing space before open paren.

Fixed.

> Ken> +            error (_("Could not determine the array high bound"));
> Ken> +
> Ken>  	  eltlen = TYPE_LENGTH (elttype);
> Ken> -	  len = TYPE_LENGTH (type) / eltlen;
> Ken> +	  len = high_bound - low_bound + 1;
> 
> I guess it is ok to use 'eltlen' elsewhere in the function because it is
> only the array's overall size which is "weird" -- the element size is
> still correct.  (Since we don't implement the DWARF stride stuff...)

Yes, that is also my understanding.

> The patch is ok with the above nit fixed.

Thanks. I've checked in the version below:
http://sourceware.org/ml/gdb-cvs/2010-11/msg00014.html

> I wonder whether f-valprint.c also needs an update.

The f77_create_arrayprint_offset_tbl function seems to setup the 
f77_array_offset_tbl with the appropriate lengths.

Regards
Ken
ChangeLog:

2010-11-03  Ken Werner  <ken.werner@de.ibm.com>

	* dwarf2read.c (read_array_type): Read the DW_AT_byte_size from the
	DIE and set the length of the type.
	* gdbtypes.h (get_array_bounds): Move here from valprint.h.
	* gdbtypes.c (get_array_bounds): Move here from valprint.c and
	return 0 if the corresponding bounds of the type are undefined.
	* valprint.h (get_array_bounds): Move declaration to gdbtypes.h.
	* valprint.c (get_array_bounds): Move implementation to gdbtypes.c.
	(val_print_array_elements): Use get_array_bounds to compute the number
	of array elements instead of dividing the length of the array by the
	length of the element types.
	* valarith.c (vector_binop): Likewise.
	* valops.c (value_cast): Likewise.
	* c-valprint.c (c_val_print): Likewise.
	* c-typeprint.c (c_type_print_varspec_suffix): Likewise.


testsuite/ChangeLog:

2010-11-03  Ken Werner  <ken.werner@de.ibm.com>

	* gdb.base/gnu_vector.exp: Adjust expect messages.

 
Index: gdb/c-valprint.c
===================================================================
--- gdb/c-valprint.c.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/c-valprint.c	2010-11-03 15:09:59.000000000 +0100
@@ -171,8 +171,13 @@ c_val_print (struct type *type, const gd
       elttype = check_typedef (unresolved_elttype);
       if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0)
 	{
+          LONGEST low_bound, high_bound;
+
+          if (!get_array_bounds (type, &low_bound, &high_bound))
+            error (_("Could not determine the array high bound"));
+
 	  eltlen = TYPE_LENGTH (elttype);
-	  len = TYPE_LENGTH (type) / eltlen;
+	  len = high_bound - low_bound + 1;
 	  if (options->prettyprint_arrays)
 	    {
 	      print_spaces_filtered (2 + 2 * recurse, stream);
Index: gdb/dwarf2read.c
===================================================================
--- gdb/dwarf2read.c.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/dwarf2read.c	2010-11-03 15:09:59.000000000 +0100
@@ -7194,6 +7194,19 @@ read_array_type (struct die_info *die, s
   if (attr)
     make_vector_type (type);
 
+  /* The DIE may have DW_AT_byte_size set.  For example an OpenCL
+     implementation may choose to implement triple vectors using this
+     attribute.  */
+  attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+  if (attr)
+    {
+      if (DW_UNSND (attr) >= TYPE_LENGTH (type))
+	TYPE_LENGTH (type) = DW_UNSND (attr);
+      else
+	complaint (&symfile_complaints, _("\
+DW_AT_byte_size for array type smaller than the total size of elements"));
+    }
+
   name = dwarf2_name (die, cu);
   if (name)
     TYPE_NAME (type) = name;
Index: gdb/gdbtypes.c
===================================================================
--- gdb/gdbtypes.c.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/gdbtypes.c	2010-11-03 15:09:59.000000000 +0100
@@ -802,6 +802,50 @@ get_discrete_bounds (struct type *type,
     }
 }
 
+/* Assuming TYPE is a simple, non-empty array type, compute its upper
+   and lower bound.  Save the low bound into LOW_BOUND if not NULL.
+   Save the high bound into HIGH_BOUND if not NULL.
+
+   Return 1 if the operation was successful. Return zero otherwise,
+   in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified.
+
+   We now simply use get_discrete_bounds call to get the values
+   of the low and high bounds.
+   get_discrete_bounds can return three values:
+   1, meaning that index is a range,
+   0, meaning that index is a discrete type,
+   or -1 for failure.  */
+
+int
+get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
+{
+  struct type *index = TYPE_INDEX_TYPE (type);
+  LONGEST low = 0;
+  LONGEST high = 0;
+  int res;
+
+  if (index == NULL)
+    return 0;
+
+  res = get_discrete_bounds (index, &low, &high);
+  if (res == -1)
+    return 0;
+
+  /* Check if the array bounds are undefined.  */
+  if (res == 1
+      && ((low_bound && TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED (type))
+	  || (high_bound && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))))
+    return 0;
+
+  if (low_bound)
+    *low_bound = low;
+
+  if (high_bound)
+    *high_bound = high;
+
+  return 1;
+}
+
 /* Create an array type using either a blank type supplied in
    RESULT_TYPE, or creating a new type, inheriting the objfile from
    RANGE_TYPE.
Index: gdb/gdbtypes.h
===================================================================
--- gdb/gdbtypes.h.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/gdbtypes.h	2010-11-03 15:09:59.000000000 +0100
@@ -1383,6 +1383,9 @@ extern int get_vptr_fieldno (struct type
 
 extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *);
 
+extern int get_array_bounds (struct type *type, LONGEST *low_bound,
+			     LONGEST *high_bound);
+
 extern int class_types_same_p (const struct type *, const struct type *);
 
 extern int is_ancestor (struct type *, struct type *);
Index: gdb/valarith.c
===================================================================
--- gdb/valarith.c.orig	2010-11-03 15:09:24.000000000 +0100
+++ gdb/valarith.c	2010-11-03 15:09:59.000000000 +0100
@@ -1394,7 +1394,8 @@ vector_binop (struct value *val1, struct
 {
   struct value *val, *tmp, *mark;
   struct type *type1, *type2, *eltype1, *eltype2, *result_type;
-  int t1_is_vec, t2_is_vec, elsize, n, i;
+  int t1_is_vec, t2_is_vec, elsize, i;
+  LONGEST low_bound1, high_bound1, low_bound2, high_bound2;
 
   type1 = check_typedef (value_type (val1));
   type2 = check_typedef (value_type (val2));
@@ -1407,23 +1408,23 @@ vector_binop (struct value *val1, struct
   if (!t1_is_vec || !t2_is_vec)
     error (_("Vector operations are only supported among vectors"));
 
+  if (!get_array_bounds (type1, &low_bound1, &high_bound1)
+      || !get_array_bounds (type2, &low_bound2, &high_bound2))
+    error (_("Could not determine the vector bounds"));
+
   eltype1 = check_typedef (TYPE_TARGET_TYPE (type1));
   eltype2 = check_typedef (TYPE_TARGET_TYPE (type2));
+  elsize = TYPE_LENGTH (eltype1);
 
   if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2)
-      || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
-      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2))
+      || elsize != TYPE_LENGTH (eltype2)
+      || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)
+      || low_bound1 != low_bound2 || high_bound1 != high_bound2)
     error (_("Cannot perform operation on vectors with different types"));
 
-  elsize = TYPE_LENGTH (eltype1);
-  n = TYPE_LENGTH (type1) / elsize;
-
-  if (n != TYPE_LENGTH (type2) / TYPE_LENGTH (eltype2))
-    error (_("Cannot perform operation on vectors with different sizes"));
-
   val = allocate_value (type1);
   mark = value_mark ();
-  for (i = 0; i < n; i++)
+  for (i = 0; i < high_bound1 - low_bound1 + 1; i++)
     {
       tmp = value_binop (value_subscript (val1, i),
 			 value_subscript (val2, i), op);
Index: gdb/valops.c
===================================================================
--- gdb/valops.c.orig	2010-11-03 15:09:24.000000000 +0100
+++ gdb/valops.c	2010-11-03 15:09:59.000000000 +0100
@@ -544,14 +544,17 @@ value_cast (struct type *type, struct va
       /* Widen the scalar to a vector.  */
       struct type *eltype;
       struct value *val;
-      int i, n;
+      LONGEST low_bound, high_bound;
+      int i;
+
+      if (!get_array_bounds (type, &low_bound, &high_bound))
+	error (_("Could not determine the vector bounds"));
 
       eltype = check_typedef (TYPE_TARGET_TYPE (type));
       arg2 = value_cast (eltype, arg2);
       val = allocate_value (type);
-      n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
 
-      for (i = 0; i < n; i++)
+      for (i = 0; i < high_bound - low_bound + 1; i++)
 	{
 	  /* Duplicate the contents of arg2 into the destination vector.  */
 	  memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
Index: gdb/valprint.c
===================================================================
--- gdb/valprint.c.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/valprint.c	2010-11-03 15:09:59.000000000 +0100
@@ -1067,44 +1067,6 @@ print_char_chars (struct ui_file *stream
     }
 }
 
-/* Assuming TYPE is a simple, non-empty array type, compute its upper
-   and lower bound.  Save the low bound into LOW_BOUND if not NULL.
-   Save the high bound into HIGH_BOUND if not NULL.
-
-   Return 1 if the operation was successful. Return zero otherwise,
-   in which case the values of LOW_BOUND and HIGH_BOUNDS are unmodified.
-  
-   We now simply use get_discrete_bounds call to get the values
-   of the low and high bounds. 
-   get_discrete_bounds can return three values:
-   1, meaning that index is a range,
-   0, meaning that index is a discrete type,
-   or -1 for failure.  */
-
-int
-get_array_bounds (struct type *type, LONGEST *low_bound, LONGEST *high_bound)
-{
-  struct type *index = TYPE_INDEX_TYPE (type);
-  LONGEST low = 0;
-  LONGEST high = 0;
-  int res;
-                                
-  if (index == NULL)
-    return 0;
-
-  res = get_discrete_bounds (index, &low, &high);
-  if (res == -1)
-    return 0;
-
-  if (low_bound)
-    *low_bound = low;
-
-  if (high_bound)
-    *high_bound = high;
-
-  return 1;
-}
-
 /* Print on STREAM using the given OPTIONS the index for the element
    at INDEX of an array whose index type is INDEX_TYPE.  */
     
@@ -1149,38 +1111,19 @@ val_print_array_elements (struct type *t
   unsigned int rep1;
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
-  LONGEST low_bound_index = 0;
+  LONGEST low_bound, high_bound;
 
   elttype = TYPE_TARGET_TYPE (type);
   eltlen = TYPE_LENGTH (check_typedef (elttype));
   index_type = TYPE_INDEX_TYPE (type);
 
-  /* Compute the number of elements in the array.  On most arrays,
-     the size of its elements is not zero, and so the number of elements
-     is simply the size of the array divided by the size of the elements.
-     But for arrays of elements whose size is zero, we need to look at
-     the bounds.  */
-  if (eltlen != 0)
-    len = TYPE_LENGTH (type) / eltlen;
+  if (get_array_bounds (type, &low_bound, &high_bound))
+    len = high_bound - low_bound + 1;
   else
     {
-      LONGEST low, hi;
-
-      if (get_array_bounds (type, &low, &hi))
-        len = hi - low + 1;
-      else
-        {
-          warning (_("unable to get bounds of array, assuming null array"));
-          len = 0;
-        }
-    }
-
-  /* Get the array low bound.  This only makes sense if the array
-     has one or more element in it.  */
-  if (len > 0 && !get_array_bounds (type, &low_bound_index, NULL))
-    {
-      warning (_("unable to get low bound of array, using zero as default"));
-      low_bound_index = 0;
+      warning (_("unable to get bounds of array, assuming null array"));
+      low_bound = 0;
+      len = 0;
     }
 
   annotate_array_section_begin (i, elttype);
@@ -1200,7 +1143,7 @@ val_print_array_elements (struct type *t
 	    }
 	}
       wrap_here (n_spaces (2 + 2 * recurse));
-      maybe_print_array_index (index_type, i + low_bound_index,
+      maybe_print_array_index (index_type, i + low_bound,
                                stream, options);
 
       rep1 = i + 1;
Index: gdb/valprint.h
===================================================================
--- gdb/valprint.h.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/valprint.h	2010-11-03 15:09:59.000000000 +0100
@@ -109,9 +109,6 @@ extern void get_raw_print_options (struc
 extern void get_formatted_print_options (struct value_print_options *opts,
 					 char format);
 
-extern int get_array_bounds (struct type *type, LONGEST *low_bound,
-			     LONGEST *high_bound);
-
 extern void maybe_print_array_index (struct type *index_type, LONGEST index,
                                      struct ui_file *stream,
 				     const struct value_print_options *options);
Index: gdb/testsuite/gdb.base/gnu_vector.exp
===================================================================
--- gdb/testsuite/gdb.base/gnu_vector.exp.orig	2010-11-03 15:09:24.000000000 +0100
+++ gdb/testsuite/gdb.base/gnu_vector.exp	2010-11-03 15:09:59.000000000 +0100
@@ -129,8 +129,8 @@ gdb_test "print f4a + d2" "Cannot perfor
 gdb_test "print d2 + f4a" "Cannot perform operation on vectors with different types"
 gdb_test "print ui4 + i4a" "Cannot perform operation on vectors with different types"
 gdb_test "print i4a + ui4" "Cannot perform operation on vectors with different types"
-gdb_test "print i4a + i2" "Cannot perform operation on vectors with different sizes"
-gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different sizes"
-gdb_test "print f4a + f2" "Cannot perform operation on vectors with different sizes"
-gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different sizes"
+gdb_test "print i4a + i2" "Cannot perform operation on vectors with different types"
+gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different types"
+gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
+gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
 
Index: gdb/c-typeprint.c
===================================================================
--- gdb/c-typeprint.c.orig	2010-11-03 14:38:39.000000000 +0100
+++ gdb/c-typeprint.c	2010-11-03 15:09:59.000000000 +0100
@@ -572,19 +572,20 @@ c_type_print_varspec_suffix (struct type
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_ARRAY:
-      if (passed_a_ptr)
-	fprintf_filtered (stream, ")");
+      {
+	LONGEST low_bound, high_bound;
 
-      fprintf_filtered (stream, "[");
-      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
-	&& !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
-	fprintf_filtered (stream, "%d",
-			  (TYPE_LENGTH (type)
-			   / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
-      fprintf_filtered (stream, "]");
+	if (passed_a_ptr)
+	  fprintf_filtered (stream, ")");
 
-      c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
-				   0, 0);
+	fprintf_filtered (stream, "[");
+	if (get_array_bounds (type, &low_bound, &high_bound))
+	  fprintf_filtered (stream, "%d", (int) (high_bound - low_bound + 1));
+	fprintf_filtered (stream, "]");
+
+	c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
+				     0, 0);
+      }
       break;
 
     case TYPE_CODE_MEMBERPTR:

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