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] |
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));