Add DW_AT_const_value as unsigned or int depending on type and value used.
authorMark Wielaard <mjw@redhat.com>
Tue, 15 Apr 2014 17:18:20 +0000 (17:18 +0000)
committerMark Wielaard <mark@gcc.gnu.org>
Tue, 15 Apr 2014 17:18:20 +0000 (17:18 +0000)
As the comment in the code already indicated DWARF2 does provide
DW_FORM_sdata/DW_FORM_udata to represent signed/unsigned data.
Enumeration constants wider than HOST_WIDE_INT are already handled
separately. Those constant values that do fit a HOST_WIDE_INT can
be encoded as signed or unsigned depending on type and value for
more efficient encoding.

* dwarf2out.c (gen_enumeration_type_die): Add DW_AT_const_value
as unsigned or int depending on type and value used.

From-SVN: r209424

gcc/ChangeLog
gcc/dwarf2out.c

index de72b92..b7b5a9a 100644 (file)
@@ -1,3 +1,8 @@
+2014-03-21  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_const_value
+       as unsigned or int depending on type and value used.
+
 2014-04-15  Richard Biener  <rguenther@suse.de>
 
        PR rtl-optimization/56965
index 721f761..0cdb3dc 100644 (file)
@@ -17361,22 +17361,23 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
 
          if (simple_type_size_in_bits (TREE_TYPE (value))
              <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value))
-           /* DWARF2 does not provide a way of indicating whether or
-              not enumeration constants are signed or unsigned.  GDB
-              always assumes the values are signed, so we output all
-              values as if they were signed.  That means that
-              enumeration constants with very large unsigned values
-              will appear to have negative values in the debugger.
-
-              TODO: the above comment is wrong, DWARF2 does provide
-              DW_FORM_sdata/DW_FORM_udata to represent signed/unsigned data.
-              This should be re-worked to use correct signed/unsigned
-              int/double tags for all cases, instead of always treating as
-              signed.  */
-           add_AT_int (enum_die, DW_AT_const_value, TREE_INT_CST_LOW (value));
+           {
+             /* For constant forms created by add_AT_unsigned DWARF
+                consumers (GDB, elfutils, etc.) always zero extend
+                the value.  Only when the actual value is negative
+                do we need to use add_AT_int to generate a constant
+                form that can represent negative values.  */
+             HOST_WIDE_INT val = TREE_INT_CST_LOW (value);
+             if (TYPE_UNSIGNED (TREE_TYPE (value)) || val >= 0)
+               add_AT_unsigned (enum_die, DW_AT_const_value,
+                                (unsigned HOST_WIDE_INT) val);
+             else
+               add_AT_int (enum_die, DW_AT_const_value, val);
+           }
          else
            /* Enumeration constants may be wider than HOST_WIDE_INT.  Handle
-              that here.  */
+              that here.  TODO: This should be re-worked to use correct
+              signed/unsigned double tags for all cases.  */
            add_AT_double (enum_die, DW_AT_const_value,
                           TREE_INT_CST_HIGH (value), TREE_INT_CST_LOW (value));
        }