Index: dwarf2read.c =================================================================== RCS file: /nile.c/cvs/Dev/gdb/gdb-6.0/gdb/dwarf2read.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -p -r1.1 -r1.5 --- dwarf2read.c 5 Oct 2003 10:39:45 -0000 1.1 +++ dwarf2read.c 19 Nov 2003 18:02:23 -0000 1.5 @@ -783,6 +783,9 @@ static void read_typedef (struct die_inf static void read_base_type (struct die_info *, struct objfile *); +static void read_subrange_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header); + static void read_file_scope (struct die_info *, struct objfile *, const struct comp_unit_head *); @@ -896,6 +899,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 *); + static struct die_info *follow_die_ref (unsigned int); static struct type *dwarf2_fundamental_type (struct objfile *, int); @@ -1418,6 +1455,7 @@ scan_partial_symbols (char *info_ptr, st case DW_TAG_structure_type: case DW_TAG_union_type: case DW_TAG_enumeration_type: + case DW_TAG_subrange_type: if ((pdi.is_external || nesting_level == file_scope_level) && !pdi.is_declaration) { @@ -1555,6 +1595,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 (pdi->name, strlen (pdi->name), VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, @@ -1803,6 +1844,14 @@ process_die (struct die_info *die, struc new_symbol (die, die->type, objfile, cu_header); } break; + case DW_TAG_subrange_type: + read_subrange_type (die, objfile, cu_header); + if (dwarf_attr (die, DW_AT_name)) + { + /* Add a typedef symbol for the base type definition. */ + new_symbol (die, die->type, objfile, cu_header); + } + break; case DW_TAG_common_block: read_common_block (die, objfile, cu_header); break; @@ -3644,6 +3725,47 @@ 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 objfile *objfile, + const struct comp_unit_head *cu_header) +{ + 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, objfile, cu_header); + if (base_type == NULL) + { + complaint (&symfile_complaints, + "DW_AT_type missing from DW_TAG_subrange_type"); + return; + } + + attr = dwarf_attr (die, DW_AT_lower_bound); + if (attr) + low = dwarf2_get_attr_constant_value (attr); + + attr = dwarf_attr (die, DW_AT_upper_bound); + if (attr) + high = dwarf2_get_attr_constant_value (attr); + + 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); + + die->type = range_type; +} + /* Read a whole compilation unit into a linked list of dies. */ static struct die_info * case DW_TAG_variable: @@ -5274,6 +5409,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); @@ -5555,6 +5691,9 @@ read_type_die (struct die_info *die, str case DW_TAG_typedef: read_typedef (die, objfile, cu_header); break; + case DW_TAG_subrange_type: + read_subrange_type (die, objfile, cu_header); + break; case DW_TAG_base_type: read_base_type (die, objfile); break; @@ -6693,6 +6836,27 @@ 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) +{ + 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"); + return -1; + } } static struct die_info *