Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@gnat.com>
To: Elena Zannoni <ezannoni@redhat.com>
Cc: schwab@suse.de, gdb-patches@sources.redhat.com
Subject: Re: [PATCH] Handle DW_TAG_subrange_type
Date: Wed, 14 Jan 2004 17:28:00 -0000	[thread overview]
Message-ID: <20040114172803.GO4978@gnat.com> (raw)
In-Reply-To: <16381.59531.51774.449779@localhost.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1627 bytes --]

Hello Helena,

> I agree that the subrange type should be handled in more places, so ok
> with Joel's calls for that.
> 
> Almost identical code is in read_array_type. Would it be possible to
> unify that as well into a single function read_subrange_type?  I.e. do
> you think that that "else if (attr->form == DW_FORM_block1)" clause
> will interfere with the ADA case? If not and we can unify them, then,
> I'd prefer the version that Andreas has, since it handles the default
> high and low, not as -1, but the same as the original code.

Here is a revised patch, which I hope addresses all your comments.
Tested on x86-linux, using gcc HEAD. No regression.

I should also mention that I am about to send a patch to gcc-patches,
which slightly modifies the dwarf-2 output, and will likely cause GCC
to generate more of these subrange_type DIEs. It is more a cleanup
patch than anything else, but I did verify that GDB together with the
attached patch handle the new GCC without trouble.

2004-01-14  J. Brobecker  <brobecker@gnat.com>

        * dwarf2read.c (dwarf2_non_const_array_bound_ignored_complaint):
        Delete, no longer used.
        (read_subrange_type): New function, mostly extracted from
        read_array_type().
        (read_array_type): Replace extracted code by call to
        read_subrange_type().
        (dwarf2_get_attr_constant_value): New function.
        (scan_partial_symbols): Add handling for DW_TAG_subrange_type.
        (add_partial_symbol): Likewise.
        (process_die): Likewise.
        (new_symbol): Likewise.
        (read_type_die): Likewise.

OK to apply?

Thanks,
-- 
Joel

[-- Attachment #2: gdb-subrange.diff --]
[-- Type: text/plain, Size: 9396 bytes --]

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.119
diff -u -p -r1.119 dwarf2read.c
--- dwarf2read.c	9 Jan 2004 22:22:07 -0000	1.119
+++ dwarf2read.c	14 Jan 2004 15:13:02 -0000
@@ -592,13 +592,6 @@ struct field_info
 /* Various complaints about symbol reading that don't abort the process */
 
 static void
-dwarf2_non_const_array_bound_ignored_complaint (const char *arg1)
-{
-  complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored",
-	     arg1);
-}
-
-static void
 dwarf2_statement_list_fits_in_line_number_section_complaint (void)
 {
   complaint (&symfile_complaints,
@@ -781,6 +774,8 @@ static void read_typedef (struct die_inf
 
 static void read_base_type (struct die_info *, struct dwarf2_cu *);
 
+static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu);
+
 static void read_file_scope (struct die_info *, struct dwarf2_cu *);
 
 static void read_func_scope (struct die_info *, struct dwarf2_cu *);
@@ -889,6 +884,8 @@ static void dwarf2_empty_hash_tables (vo
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
 
+static int dwarf2_get_attr_constant_value (struct attribute *, int);
+
 static struct die_info *follow_die_ref (unsigned int);
 
 static struct type *dwarf2_fundamental_type (struct objfile *, int);
@@ -1384,6 +1381,7 @@ scan_partial_symbols (char *info_ptr, CO
 		}
 	      break;
 	    case DW_TAG_base_type:
+            case DW_TAG_subrange_type:
 	      /* File scope base type definitions are added to the partial
 	         symbol table.  */
 	      add_partial_symbol (&pdi, cu, namespace);
@@ -1496,6 +1494,7 @@ add_partial_symbol (struct partial_die_i
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
+    case DW_TAG_subrange_type:
       add_psymbol_to_list (actual_name, strlen (actual_name),
 			   VAR_DOMAIN, LOC_TYPEDEF,
 			   &objfile->static_psymbols,
@@ -1858,6 +1857,14 @@ process_die (struct die_info *die, struc
 	  new_symbol (die, die->type, cu);
 	}
       break;
+    case DW_TAG_subrange_type:
+      read_subrange_type (die, cu);
+      if (dwarf_attr (die, DW_AT_name))
+       {
+         /* Add a typedef symbol for the base type definition.  */
+         new_symbol (die, die->type, cu);
+       }
+      break;
     case DW_TAG_common_block:
       read_common_block (die, cu);
       break;
@@ -3062,88 +3069,22 @@ read_array_type (struct die_info *die, s
     {
       if (child_die->tag == DW_TAG_subrange_type)
 	{
-	  unsigned int low, high;
-
-	  /* Default bounds to an array with unspecified length.  */
-	  low = 0;
-	  high = -1;
-	  if (cu_language == language_fortran)
-	    {
-	      /* FORTRAN implies a lower bound of 1, if not given.  */
-	      low = 1;
-	    }
-
-	  index_type = die_type (child_die, cu);
-	  attr = dwarf_attr (child_die, DW_AT_lower_bound);
-	  if (attr)
-	    {
-	      if (attr->form == DW_FORM_sdata)
-		{
-		  low = DW_SND (attr);
-		}
-	      else if (attr->form == DW_FORM_udata
-		       || attr->form == DW_FORM_data1
-		       || attr->form == DW_FORM_data2
-		       || attr->form == DW_FORM_data4
-		       || attr->form == DW_FORM_data8)
-		{
-		  low = DW_UNSND (attr);
-		}
-	      else
-		{
-		  dwarf2_non_const_array_bound_ignored_complaint
-		    (dwarf_form_name (attr->form));
-		  low = 0;
-		}
-	    }
-	  attr = dwarf_attr (child_die, DW_AT_upper_bound);
-	  if (attr)
-	    {
-	      if (attr->form == DW_FORM_sdata)
-		{
-		  high = DW_SND (attr);
-		}
-	      else if (attr->form == DW_FORM_udata
-		       || attr->form == DW_FORM_data1
-		       || attr->form == DW_FORM_data2
-		       || attr->form == DW_FORM_data4
-		       || attr->form == DW_FORM_data8)
-		{
-		  high = DW_UNSND (attr);
-		}
-	      else if (attr->form == DW_FORM_block1)
-		{
-		  /* GCC encodes arrays with unspecified or dynamic length
-		     with a DW_FORM_block1 attribute.
-		     FIXME: GDB does not yet know how to handle dynamic
-		     arrays properly, treat them as arrays with unspecified
-		     length for now.
-
-                     FIXME: jimb/2003-09-22: GDB does not really know
-                     how to handle arrays of unspecified length
-                     either; we just represent them as zero-length
-                     arrays.  Choose an appropriate upper bound given
-                     the lower bound we've computed above.  */
-		  high = low - 1;
-		}
-	      else
-		{
-		  dwarf2_non_const_array_bound_ignored_complaint
-		    (dwarf_form_name (attr->form));
-		  high = 1;
-		}
-	    }
+          read_subrange_type (child_die, cu);
 
-	  /* Create a range type and save it for array type creation.  */
-	  if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
-	    {
-	      range_types = (struct type **)
-		xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
-			  * sizeof (struct type *));
-	      if (ndim == 0)
-		make_cleanup (free_current_contents, &range_types);
-	    }
-	  range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+          if (child_die->type != NULL)
+            {
+	      /* The range type was succesfully read. Save it for
+                 the array type creation.  */
+              if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+                {
+                  range_types = (struct type **)
+                    xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+                              * sizeof (struct type *));
+                  if (ndim == 0)
+                    make_cleanup (free_current_contents, &range_types);
+	        }
+	      range_types[ndim++] = child_die->type;
+            }
 	}
       child_die = sibling_die (child_die);
     }
@@ -3689,6 +3630,78 @@ read_base_type (struct die_info *die, st
   die->type = type;
 }
 
+/* Read the given DW_AT_subrange DIE.  */
+
+static void
+read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct type *base_type;
+  struct type *range_type;
+  struct attribute *attr;
+  int low = 0;
+  int high = -1;
+  
+  /* If we have already decoded this die, then nothing more to do.  */
+  if (die->type)
+    return;
+
+  base_type = die_type (die, cu);
+  if (base_type == NULL)
+    {
+      complaint (&symfile_complaints,
+                "DW_AT_type missing from DW_TAG_subrange_type");
+      return;
+    }
+
+  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+    base_type = alloc_type (NULL);
+
+  if (cu_language == language_fortran)
+    { 
+      /* FORTRAN implies a lower bound of 1, if not given.  */
+      low = 1;
+    }
+
+  attr = dwarf_attr (die, DW_AT_lower_bound);
+  if (attr)
+    low = dwarf2_get_attr_constant_value (attr, 0);
+
+  attr = dwarf_attr (die, DW_AT_upper_bound);
+  if (attr)
+    {       
+      if (attr->form == DW_FORM_block1)
+        {
+          /* GCC encodes arrays with unspecified or dynamic length
+             with a DW_FORM_block1 attribute.
+             FIXME: GDB does not yet know how to handle dynamic
+             arrays properly, treat them as arrays with unspecified
+             length for now.
+
+             FIXME: jimb/2003-09-22: GDB does not really know
+             how to handle arrays of unspecified length
+             either; we just represent them as zero-length
+             arrays.  Choose an appropriate upper bound given
+             the lower bound we've computed above.  */
+          high = low - 1;
+        }
+      else
+        high = dwarf2_get_attr_constant_value (attr, 1);
+    }
+
+  range_type = create_range_type (NULL, base_type, low, high);
+
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    TYPE_NAME (range_type) = DW_STRING (attr);
+  
+  attr = dwarf_attr (die, DW_AT_byte_size);
+  if (attr)
+    TYPE_LENGTH (range_type) = DW_UNSND (attr);
+
+  die->type = range_type;
+}
+  
+
 /* Read a whole compilation unit into a linked list of dies.  */
 
 static struct die_info *
@@ -5344,6 +5357,7 @@ new_symbol (struct die_info *die, struct
 	  break;
 	case DW_TAG_typedef:
 	case DW_TAG_base_type:
+        case DW_TAG_subrange_type:
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  add_symbol_to_list (sym, list_in_scope);
@@ -5626,6 +5640,9 @@ read_type_die (struct die_info *die, str
     case DW_TAG_typedef:
       read_typedef (die, cu);
       break;
+    case DW_TAG_subrange_type:
+      read_subrange_type (die, cu);
+      break;
     case DW_TAG_base_type:
       read_base_type (die, cu);
       break;
@@ -6733,6 +6750,28 @@ dwarf2_get_ref_die_offset (struct attrib
 		 dwarf_form_name (attr->form));
     }
   return result;
+}
+
+/* Return the constant value held by the given attribute.  Return -1
+   if the value held by the attribute is not constant.  */
+
+static int
+dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+{
+  if (attr->form == DW_FORM_sdata)
+    return DW_SND (attr);
+  else if (attr->form == DW_FORM_udata
+           || attr->form == DW_FORM_data1
+           || attr->form == DW_FORM_data2
+           || attr->form == DW_FORM_data4
+           || attr->form == DW_FORM_data8)
+    return DW_UNSND (attr);
+  else
+    {
+      complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+                 dwarf_form_name (attr->form));
+      return default_value;
+    }
 }
 
 static struct die_info *

  reply	other threads:[~2004-01-14 17:28 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-08 23:33 Elena Zannoni
2004-01-14 17:28 ` Joel Brobecker [this message]
2004-01-15 17:11   ` Elena Zannoni
2004-01-17  5:37     ` Joel Brobecker
  -- strict thread matches above, loose matches on Subject: below --
2003-11-22 20:08 Andreas Schwab
2003-11-24  9:51 ` Joel Brobecker
2003-11-24 12:16   ` Andreas Schwab
2003-12-04 16:51 ` Elena Zannoni
2003-12-04 17:29   ` Andreas Schwab
2003-12-04 17:49   ` Joel Brobecker
2003-12-04 18:16     ` Elena Zannoni

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=20040114172803.GO4978@gnat.com \
    --to=brobecker@gnat.com \
    --cc=ezannoni@redhat.com \
    --cc=gdb-patches@sources.redhat.com \
    --cc=schwab@suse.de \
    /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