This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


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

Patch for DW_TAG_subrange_type


The dwarf2 reader doesn't support subrange types when they aren't an array
index.  Ada has such types and Aonix ObjectAda generates this dwarf2
structure.



Mon May  3 15:07:08 1999 Brian Nettleton <bn@aonix.com>

	* dwarf2read.c: Added read_subrange_type for DW_TAG_subrange types
	not used as array indices (Ada has such types).  Added sym field
	to struct die_info to support subrange types.



Index: gdb/dwarf2read.c
*** ../gdb-4.17.patch/gdb/dwarf2read.c	Mon May  3 15:06:26 1999
--- gdb/dwarf2read.c	Mon May  3 15:06:52 1999
*************** struct die_info
*** 216,221 ****
--- 216,222 ----
      struct die_info *next_ref;	 /* Next die in ref hash table */
      struct die_info *next;	 /* Next die in linked list */
      struct type *type;		 /* Cached type information */
+     struct symbol *sym;          /* Symbol for a die (if there is one) */
    };
  
  /* Attributes have a name and a value */
*************** static void read_common_block PARAMS ((s
*** 664,669 ****
--- 665,672 ----
  
  static void read_enumeration PARAMS ((struct die_info *, struct objfile *));
  
+ static void read_subrange_type PARAMS ((struct die_info *, struct objfile *));
+ 
  static struct type *dwarf_base_type PARAMS ((int, int, struct objfile *));
  
  static CORE_ADDR decode_locdesc PARAMS ((struct dwarf_block *,
*************** read_enumeration (die, objfile)
*** 2457,2462 ****
--- 2460,2602 ----
    die->type = type;
    new_symbol (die, type, objfile);
  }
+ /* Extract all information from a DW_TAG_subrange_type DIE and put it in
+    the DIE's type field.  */
+ 
+ static void
+ read_subrange_type (die, objfile)
+      struct die_info *die;
+      struct objfile *objfile;
+ {
+   struct type *type;
+   struct type *xtype;
+   struct attribute *attr;
+   LONGEST lower_bound, upper_bound;
+   char    use_range_type = 0;
+ 
+   /* If we've already decoded this die, this is a no-op. */
+   if (die->type)
+     {
+       return;
+     }
+ 
+   attr = dwarf_attr (die, DW_AT_type);
+   if (attr)
+     {
+       xtype = die_type (die, objfile);
+       if (TYPE_CODE(xtype) == TYPE_CODE_INT ||
+         TYPE_CODE(xtype) == TYPE_CODE_ENUM ||
+         TYPE_CODE(xtype) == TYPE_CODE_RANGE ||
+         TYPE_CODE(xtype) == TYPE_CODE_BOOL)
+         {
+           use_range_type = 1;
+         }
+     }
+   else
+     {
+       /* see if we can simply read it as a base type */
+       read_base_type (die, objfile);
+       return;
+     }
+   attr = dwarf_attr (die, DW_AT_lower_bound);
+   if (use_range_type && attr)
+     {
+        struct die_info *ref_die;
+ 
+        switch (attr->form)
+          {
+          case DW_FORM_data2:
+          case DW_FORM_data4:
+          case DW_FORM_data8:
+          case DW_FORM_data1:
+          case DW_FORM_sdata:
+          case DW_FORM_udata:
+            lower_bound = DW_SND(attr);
+            use_range_type = 1;
+            break;
+          case DW_FORM_ref1:
+          case DW_FORM_ref2:
+          case DW_FORM_ref4:
+          case DW_FORM_ref_addr:
+          case DW_FORM_ref_udata:
+            ref_die = follow_die_ref( dwarf2_get_ref_die_offset(attr) );
+            if (ref_die && (ref_die->sym != NULL) && SYMBOL_CLASS(ref_die->sym))
+             {
+                lower_bound = SYMBOL_VALUE(ref_die->sym);
+                use_range_type = 1;
+              }
+            else
+              use_range_type = 0;
+            break;
+          default:
+            use_range_type = 0;
+            break;
+          }
+     }
+   else
+     {
+       use_range_type = 0;
+     }
+   attr = dwarf_attr (die, DW_AT_upper_bound);
+   if (use_range_type && attr)
+     {
+        struct die_info *ref_die;
+        switch (attr->form)
+          {
+          case DW_FORM_data2:
+          case DW_FORM_data4:
+          case DW_FORM_data8:
+          case DW_FORM_data1:
+          case DW_FORM_sdata:
+          case DW_FORM_udata:
+            upper_bound = DW_SND(attr);
+            use_range_type = 1;
+            break;
+          case DW_FORM_ref1:
+          case DW_FORM_ref2:
+          case DW_FORM_ref4:
+          case DW_FORM_ref_addr:
+          case DW_FORM_ref_udata:
+            ref_die = follow_die_ref( dwarf2_get_ref_die_offset(attr) );
+            if (ref_die && (ref_die->sym != NULL) && SYMBOL_CLASS(ref_die->sym))
+             {
+                upper_bound = SYMBOL_VALUE(ref_die->sym);
+                use_range_type = 1;
+              }
+            else
+              {
+                use_range_type = 0;
+              }
+            break;
+          default:
+            use_range_type = 0;
+            break;
+          }
+     }
+   else
+     {
+       use_range_type = 0;
+     }
+   if (use_range_type)
+     {
+       type = create_range_type (NULL, xtype, lower_bound, upper_bound);
+     }
+   else
+     {
+       type = alloc_type (objfile);
+       TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
+       TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
+       TYPE_TARGET_TYPE (type) = xtype;
+       attr = dwarf_attr (die, DW_AT_name);
+       if (attr && DW_STRING (attr))
+         TYPE_NAME (type) = obsavestring (DW_STRING (attr),
+                                          strlen (DW_STRING (attr)),
+                                          &objfile->type_obstack);
+ 
+     }
+   die->type = type;
+   new_symbol( die, type, objfile );
+ }
  
  /* Extract all information from a DW_TAG_array_type DIE and put it in
     the DIE's type field.  For now, this only handles one dimensional
*************** new_symbol (die, type, objfile)
*** 4306,4311 ****
--- 4446,4452 ----
  	  break;
  	}
      }
+   die->sym = sym;
    return (sym);
  }
  
*************** read_type_die (die, objfile)
*** 4518,4523 ****
--- 4659,4667 ----
        break;
      case DW_TAG_base_type:
        read_base_type (die, objfile);
+       break;
+     case DW_TAG_subrange_type:
+       read_subrange_type (die, objfile);
        break;
      default:
        complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));