aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2014-03-26 08:54:56 -0600
committerTom Tromey <tromey@redhat.com>2014-04-14 11:42:17 -0600
commit0626fc76d1b95c1c5b158a9b0be17791aa9078f8 (patch)
treed791c48f8f03f596ea5ff05c0c1978fa580a4a61 /gdb/dwarf2read.c
parentdca325b370730f8cfd3b63ac848569bf58d8746c (diff)
downloadgdb-0626fc76d1b95c1c5b158a9b0be17791aa9078f8.zip
gdb-0626fc76d1b95c1c5b158a9b0be17791aa9078f8.tar.gz
gdb-0626fc76d1b95c1c5b158a9b0be17791aa9078f8.tar.bz2
handle DW_AT_type on an enumeration
DWARF allows an enumeration type to have a DW_AT_type. GDB doesn't recognize this, but there is a patch to change GCC to emit it, and a DWARF proposal to further allow an enum type with a DW_AT_type to omit the DW_AT_byte_size. This patch changes gdb to implement this. Built and regtested on x86-64 Fedora 20. 2014-04-14 Tom Tromey <tromey@redhat.com> * dwarf2read.c (read_enumeration_type): Handle DW_AT_type. 2014-04-14 Tom Tromey <tromey@redhat.com> * gdb.dwarf2/enum-type.exp: New file.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 7c64491..cede6b4 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13225,6 +13225,14 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
if (name != NULL)
TYPE_TAG_NAME (type) = name;
+ attr = dwarf2_attr (die, DW_AT_type, cu);
+ if (attr != NULL)
+ {
+ struct type *underlying_type = die_type (die, cu);
+
+ TYPE_TARGET_TYPE (type) = underlying_type;
+ }
+
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
@@ -13243,9 +13251,25 @@ 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. */
+ /* Finish the creation of this type by using the enum's children.
+ We must call this even when the underlying type has been provided
+ so that we can determine if we're looking at a "flag" enum. */
update_enumeration_type_from_children (die, type, cu);
+ /* If this type has an underlying type that is not a stub, then we
+ may use its attributes. We always use the "unsigned" attribute
+ in this situation, because ordinarily we guess whether the type
+ is unsigned -- but the guess can be wrong and the underlying type
+ can tell us the reality. However, we defer to a local size
+ attribute if one exists, because this lets the compiler override
+ the underlying type if needed. */
+ if (TYPE_TARGET_TYPE (type) != NULL && !TYPE_STUB (TYPE_TARGET_TYPE (type)))
+ {
+ TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
+ if (TYPE_LENGTH (type) == 0)
+ TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+ }
+
return set_die_type (die, type, cu);
}