diff options
author | Tom Tromey <tromey@redhat.com> | 2011-05-11 17:25:41 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-05-11 17:25:41 +0000 |
commit | 74ac6d431ca65ec3441c392e3467e3d3bf404f8b (patch) | |
tree | 2e3feaf35a00b526edb5a24b51f177c405ccefa7 /gdb/dwarf2read.c | |
parent | 250826bd544589968cfaef3fb087a6327cc48698 (diff) | |
download | gdb-74ac6d431ca65ec3441c392e3467e3d3bf404f8b.zip gdb-74ac6d431ca65ec3441c392e3467e3d3bf404f8b.tar.gz gdb-74ac6d431ca65ec3441c392e3467e3d3bf404f8b.tar.bz2 |
* dwarf2read.c (handle_data_member_location): New function.
(dwarf2_add_field): Use it.
(read_common_block): Likewise.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 81b20c7..fb54655 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -6365,6 +6365,41 @@ dwarf2_default_access_attribute (struct die_info *die, struct dwarf2_cu *cu) } } +/* Look for DW_AT_data_member_location. Set *OFFSET to the byte + offset. If the attribute was not found return 0, otherwise return + 1. If it was found but could not properly be handled, set *OFFSET + to 0. */ + +static int +handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu, + LONGEST *offset) +{ + struct attribute *attr; + + attr = dwarf2_attr (die, DW_AT_data_member_location, cu); + if (attr != NULL) + { + *offset = 0; + + /* Note that we do not check for a section offset first here. + This is because DW_AT_data_member_location is new in DWARF 4, + so if we see it, we can assume that a constant form is really + a constant and not a section offset. */ + if (attr_form_is_constant (attr)) + *offset = dwarf2_get_attr_constant_value (attr, 0); + else if (attr_form_is_section_offset (attr)) + dwarf2_complex_location_expr_complaint (); + else if (attr_form_is_block (attr)) + *offset = decode_locdesc (DW_BLOCK (attr), cu); + else + dwarf2_complex_location_expr_complaint (); + + return 1; + } + + return 0; +} + /* Add an aggregate field to the field list. */ static void @@ -6413,6 +6448,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu)) { + LONGEST offset; + /* Data member other than a C++ static data member. */ /* Get type of field. */ @@ -6432,22 +6469,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } /* Get bit offset of field. */ - attr = dwarf2_attr (die, DW_AT_data_member_location, cu); - if (attr) - { - int byte_offset = 0; - - if (attr_form_is_section_offset (attr)) - dwarf2_complex_location_expr_complaint (); - else if (attr_form_is_constant (attr)) - byte_offset = dwarf2_get_attr_constant_value (attr, 0); - else if (attr_form_is_block (attr)) - byte_offset = decode_locdesc (DW_BLOCK (attr), cu); - else - dwarf2_complex_location_expr_complaint (); - - SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte); - } + if (handle_data_member_location (die, cu, &offset)) + SET_FIELD_BITPOS (*fp, offset * bits_per_byte); attr = dwarf2_attr (die, DW_AT_bit_offset, cu); if (attr) { @@ -6550,23 +6573,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } else if (die->tag == DW_TAG_inheritance) { - /* C++ base class field. */ - attr = dwarf2_attr (die, DW_AT_data_member_location, cu); - if (attr) - { - int byte_offset = 0; - - if (attr_form_is_section_offset (attr)) - dwarf2_complex_location_expr_complaint (); - else if (attr_form_is_constant (attr)) - byte_offset = dwarf2_get_attr_constant_value (attr, 0); - else if (attr_form_is_block (attr)) - byte_offset = decode_locdesc (DW_BLOCK (attr), cu); - else - dwarf2_complex_location_expr_complaint (); + LONGEST offset; - SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte); - } + /* C++ base class field. */ + if (handle_data_member_location (die, cu, &offset)) + SET_FIELD_BITPOS (*fp, offset * bits_per_byte); FIELD_BITSIZE (*fp) = 0; FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = type_name_no_tag (fp->type); @@ -7676,22 +7687,13 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) child_die = die->child; while (child_die && child_die->tag) { + LONGEST offset; + sym = new_symbol (child_die, NULL, cu); - attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu); - if (sym != NULL && attr != NULL) + if (sym != NULL && + handle_data_member_location (child_die, cu, &offset)) { - CORE_ADDR byte_offset = 0; - - if (attr_form_is_section_offset (attr)) - dwarf2_complex_location_expr_complaint (); - else if (attr_form_is_constant (attr)) - byte_offset = dwarf2_get_attr_constant_value (attr, 0); - else if (attr_form_is_block (attr)) - byte_offset = decode_locdesc (DW_BLOCK (attr), cu); - else - dwarf2_complex_location_expr_complaint (); - - SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset; + SYMBOL_VALUE_ADDRESS (sym) = base + offset; add_symbol_to_list (sym, &global_symbols); } child_die = sibling_die (child_die); |