diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 82 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/arr-subrange.c | 20 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/arr-subrange.exp | 99 |
5 files changed, 197 insertions, 16 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 53666b3..8f2f0dc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2014-02-27 Joel Brobecker <brobecker@adacore.com> + + * dwarf2read.c (update_enumeration_type_from_children): New + function, mostly extracted from process_structure_scope. + (read_enumeration_type): Call update_enumeration_type_from_children. + (process_enumeration_scope): Do not set THIS_TYPE's flag_unsigned + and flag_flag_enum fields. + 2014-02-26 Pedro Alves <palves@redhat.com> * bsd-uthread.c (bsd_uthread_xfer_partial): Delete function. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index d7dc38c..00bba47 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -13107,6 +13107,69 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) new_symbol (die, type, cu); } +/* Assuming DIE is an enumeration type, and TYPE is its associated type, + update TYPE using some information only available in DIE's children. */ + +static void +update_enumeration_type_from_children (struct die_info *die, + struct type *type, + struct dwarf2_cu *cu) +{ + struct obstack obstack; + struct die_info *child_die = die->child; + int unsigned_enum = 1; + int flag_enum = 1; + ULONGEST mask = 0; + struct cleanup *old_chain; + + obstack_init (&obstack); + old_chain = make_cleanup_obstack_free (&obstack); + + while (child_die != NULL && child_die->tag) + { + struct attribute *attr; + LONGEST value; + const gdb_byte *bytes; + struct dwarf2_locexpr_baton *baton; + const char *name; + if (child_die->tag != DW_TAG_enumerator) + continue; + + attr = dwarf2_attr (child_die, DW_AT_const_value, cu); + if (attr == NULL) + continue; + + name = dwarf2_name (child_die, cu); + if (name == NULL) + name = "<anonymous enumerator>"; + + dwarf2_const_value_attr (attr, type, name, &obstack, cu, + &value, &bytes, &baton); + if (value < 0) + { + unsigned_enum = 0; + flag_enum = 0; + } + else if ((mask & value) != 0) + flag_enum = 0; + else + mask |= value; + + /* If we already know that the enum type is neither unsigned, nor + a flag type, no need to look at the rest of the enumerates. */ + if (!unsigned_enum && !flag_enum) + break; + child_die = sibling_die (child_die); + } + + if (unsigned_enum) + TYPE_UNSIGNED (type) = 1; + if (flag_enum) + TYPE_FLAG_ENUM (type) = 1; + + do_cleanups (old_chain); +} + /* Given a DW_AT_enumeration_type die, set its type. We do not complete the type's fields yet, or create any symbols. */ @@ -13156,6 +13219,9 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) if (die_is_declaration (die, cu)) TYPE_STUB (type) = 1; + /* Finish the creation of this type by using the enum's children. */ + update_enumeration_type_from_children (die, type, cu); + return set_die_type (die, type, cu); } @@ -13180,10 +13246,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) struct symbol *sym; struct field *fields = NULL; int num_fields = 0; - int unsigned_enum = 1; const char *name; - int flag_enum = 1; - ULONGEST mask = 0; child_die = die->child; while (child_die && child_die->tag) @@ -13198,15 +13261,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) if (name) { sym = new_symbol (child_die, this_type, cu); - if (SYMBOL_VALUE (sym) < 0) - { - unsigned_enum = 0; - flag_enum = 0; - } - else if ((mask & SYMBOL_VALUE (sym)) != 0) - flag_enum = 0; - else - mask |= SYMBOL_VALUE (sym); if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0) { @@ -13237,10 +13291,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) sizeof (struct field) * num_fields); xfree (fields); } - if (unsigned_enum) - TYPE_UNSIGNED (this_type) = 1; - if (flag_enum) - TYPE_FLAG_ENUM (this_type) = 1; } /* If we are reading an enum from a .debug_types unit, and the enum diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 476e1a3..b14257f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2014-02-26 Joel Brobecker <brobecker@adacore.com> + * gdb.dwarf2/arr-subrange.c, gdb.dwarf2/arr-subrange.exp: New files. + +2014-02-26 Joel Brobecker <brobecker@adacore.com> + * gdb.dwarf2/arr-stride.c: New file. * gdb.dwarf2/arr-stride.exp: New file. diff --git a/gdb/testsuite/gdb.dwarf2/arr-subrange.c b/gdb/testsuite/gdb.dwarf2/arr-subrange.c new file mode 100644 index 0000000..978ef8d --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/arr-subrange.c @@ -0,0 +1,20 @@ +/* Copyright 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/arr-subrange.exp b/gdb/testsuite/gdb.dwarf2/arr-subrange.exp new file mode 100644 index 0000000..9847c13 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/arr-subrange.exp @@ -0,0 +1,99 @@ +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile arr-subrange.c arr-subrange-dw.S + +# Make some DWARF for the test. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_Ada95} + {DW_AT_name foo.adb} + {DW_AT_comp_dir /tmp} + {DW_AT_low_pc 0x1000} + {DW_AT_high_pc 0x2000} + } { + declare_labels boolean_label typedef_label array_label enum_label + + boolean_label: DW_TAG_base_type { + {DW_AT_byte_size 1 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_boolean} + {DW_AT_name boolean} + } + + typedef_label: DW_TAG_typedef { + {DW_AT_name pck__table} + {DW_AT_type :$array_label} + } + + array_label: DW_TAG_array_type { + {DW_AT_name pck__table} + {DW_AT_type :$boolean_label} + } { + DW_TAG_subrange_type { + {DW_AT_type :$enum_label} + {DW_AT_lower_bound 0 DW_FORM_data1} + {DW_AT_upper_bound 128 DW_FORM_data1} + } + } + + enum_label: DW_TAG_enumeration_type { + {DW_AT_name pck__enum_t} + {DW_AT_byte_size 1 DW_FORM_sdata} + } { + DW_TAG_enumerator { + {DW_AT_name pck__enum_000} + {DW_AT_const_value 0 DW_FORM_sdata} + } + DW_TAG_enumerator { + {DW_AT_name pck__enum_001} + {DW_AT_const_value 1 DW_FORM_sdata} + } + DW_TAG_enumerator { + {DW_AT_name pck__enum_128} + {DW_AT_const_value 128 DW_FORM_sdata} + } + } + } + } +} + +if {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \ + object {nodebug}] != ""} { + return -1 +} + +if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} { + return -1 +} + +if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \ + "${binfile}" executable {}] != ""} { + return -1 +} + +clean_restart ${testfile} + +gdb_test_no_output "set language ada" + +gdb_test "ptype pck.table" \ + "type = array \\(enum_000 \\.\\. enum_128\\) of boolean" |