diff options
Diffstat (limited to 'gdb/dwarf2/attribute.c')
-rw-r--r-- | gdb/dwarf2/attribute.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c index 1278f97..8ff0353 100644 --- a/gdb/dwarf2/attribute.c +++ b/gdb/dwarf2/attribute.c @@ -73,7 +73,8 @@ attribute::form_is_string () const || form == DW_FORM_strx3 || form == DW_FORM_strx4 || form == DW_FORM_GNU_str_index - || form == DW_FORM_GNU_strp_alt); + || form == DW_FORM_GNU_strp_alt + || form == DW_FORM_strp_sup); } /* See attribute.h. */ @@ -185,11 +186,43 @@ attribute::unsigned_constant () const /* See attribute.h. */ +std::optional<LONGEST> +attribute::signed_constant () const +{ + if (form_is_strictly_signed ()) + return u.snd; + + switch (form) + { + case DW_FORM_data8: + case DW_FORM_udata: + /* Not sure if DW_FORM_udata should be handled or not. Anyway + for DW_FORM_data8, there's no need to sign-extend. */ + return u.snd; + + case DW_FORM_data1: + return sign_extend (u.unsnd, 8); + case DW_FORM_data2: + return sign_extend (u.unsnd, 16); + case DW_FORM_data4: + return sign_extend (u.unsnd, 32); + } + + /* For DW_FORM_data16 see attribute::form_is_constant. */ + complaint (_("Attribute value is not a constant (%s)"), + dwarf_form_name (form)); + return {}; +} + +/* See attribute.h. */ + bool attribute::form_is_unsigned () const { return (form == DW_FORM_ref_addr || form == DW_FORM_GNU_ref_alt + || form == DW_FORM_ref_sup4 + || form == DW_FORM_ref_sup8 || form == DW_FORM_data2 || form == DW_FORM_data4 || form == DW_FORM_data8 @@ -293,5 +326,8 @@ attribute::as_boolean () const return true; else if (form == DW_FORM_flag) return u.unsnd != 0; - return constant_value (0) != 0; + /* Using signed_constant here will work even for the weird case + where a negative value is provided. Probably doesn't matter but + also seems harmless. */ + return signed_constant ().value_or (0) != 0; } |