public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Ken Werner <ken@linux.vnet.ibm.com>
To: Tom Tromey <tromey@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [patch] DW_AT_byte_size for array type entries
Date: Wed, 03 Nov 2010 14:23:00 -0000	[thread overview]
Message-ID: <201011031522.50715.ken@linux.vnet.ibm.com> (raw)
In-Reply-To: <m3iq0fgxy0.fsf@fleche.redhat.com>

[-- Attachment #1: Type: Text/Plain, Size: 1666 bytes --]

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

[-- Attachment #2: DW_AT_byte_size.patch --]
[-- Type: text/x-patch, Size: 14318 bytes --]

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:

  reply	other threads:[~2010-11-03 14:23 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-19 11:24 Ken Werner
2010-10-19 18:16 ` Ken Werner
2010-11-02  8:23   ` Ken Werner
2010-11-02 22:45   ` Tom Tromey
2010-11-03 14:23     ` Ken Werner [this message]
2010-11-03 19:09       ` Regression on gdb.ada/null_array.exp [Re: [patch] DW_AT_byte_size for array type entries] Jan Kratochvil
2010-11-03 21:16         ` Joel Brobecker
2010-11-03 23:22           ` [commit/Ada] fix warning when printing empty array Joel Brobecker
2010-11-03 23:24         ` Regression on gdb.ada/null_array.exp [Re: [patch] DW_AT_byte_size for array type entries] Joel Brobecker
2010-11-04  0:31           ` Jan Kratochvil
2010-11-04  1:57             ` Joel Brobecker
2010-11-04  3:26               ` Jan Kratochvil
2010-11-04 18:01                 ` Joel Brobecker
2010-11-04 18:10                   ` Jan Kratochvil
2010-11-04 18:23                     ` Joel Brobecker
2010-11-04 18:54                       ` Jan Kratochvil
2010-11-04 22:11                         ` Joel Brobecker
2010-12-13 20:03       ` [patch] DW_AT_byte_size for array type entries Ken Werner
2010-12-14  5:42         ` Joel Brobecker
2010-12-14 10:27           ` Ken Werner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201011031522.50715.ken@linux.vnet.ibm.com \
    --to=ken@linux.vnet.ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).