This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto] PATCH: preserve precision of odd-sized integral types


This patch addresses one of the weirdnesses Kenny noted that showed up when reading and writing bit_size_type (68 bit precision) through the DWARF encoding. OK to commit?

-Sandra

2006-10-10  Sandra Loosemore  <sandra@codesourcery.com>

	* gcc/dwarf2out.c (base_type_die): Add DW_AT_bit_size and
	DW_AT_bit_offset attributes for integral types with a precision
	smaller than the bit size of their containing object.
	* gcc/lto/lto.c (lto_read_base_type_DIE): Do the inverse when
	constructing integral types.
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c	(revision 117581)
--- gcc/dwarf2out.c	(working copy)
*************** base_type_die (tree type)
*** 8108,8113 ****
--- 8108,8114 ----
  {
    dw_die_ref base_type_result;
    enum dwarf_type encoding;
+   int byte_size;
  
    if (TREE_CODE (type) == ERROR_MARK || TREE_CODE (type) == VOID_TYPE)
      return 0;
*************** base_type_die (tree type)
*** 8160,8169 ****
    if (! TYPE_NAME (type))
      add_name_attribute (base_type_result, "__unknown__");
  
!   add_AT_unsigned (base_type_result, DW_AT_byte_size,
! 		   int_size_in_bytes (type));
    add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
  
    return base_type_result;
  }
  
--- 8161,8182 ----
    if (! TYPE_NAME (type))
      add_name_attribute (base_type_result, "__unknown__");
  
!   byte_size = int_size_in_bytes (type);
!   add_AT_unsigned (base_type_result, DW_AT_byte_size, byte_size);
    add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
  
+   /* Emit information to allow the LTO front end to reconstruct integral
+      types whose precision is less than the bit width of their containing
+      object, e.g., bitsizetype.  */
+   if (TREE_CODE (type) == INTEGER_TYPE
+       && TYPE_PRECISION (type) < byte_size * BITS_PER_UNIT)
+     {
+       add_AT_unsigned (base_type_result, DW_AT_bit_size,
+ 		       TYPE_PRECISION (type));
+       add_AT_unsigned (base_type_result, DW_AT_bit_offset,
+ 		       byte_size * BITS_PER_UNIT - TYPE_PRECISION (type));
+     }
+ 
    return base_type_result;
  }
  
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c	(revision 117581)
--- gcc/lto/lto.c	(working copy)
*************** lto_read_base_type_DIE (lto_info_fd *fd,
*** 2596,2610 ****
--- 2596,2618 ----
    bool have_encoding;
    enum dwarf_type encoding;
    bool have_size;
+   bool have_offset;
+   bool have_bits;
    int size;
    tree type;
    int bits;
+   int offset;
+   int maxbits;
  
    name = NULL_TREE;
    have_encoding = false;
    encoding = DW_ATE_void;
    have_size = false;
    size = 0;
+   have_bits = false;
+   bits = 0;
+   have_offset = false;
+   offset = 0;
    type = NULL_TREE;
  
    LTO_BEGIN_READ_ATTRS ()
*************** lto_read_base_type_DIE (lto_info_fd *fd,
*** 2624,2631 ****
        break;
  
      case DW_AT_bit_size:
      case DW_AT_bit_offset:
!       lto_unsupported_attr_error (abbrev, attr);
        break;
      }
    LTO_END_READ_ATTRS ();
--- 2632,2644 ----
        break;
  
      case DW_AT_bit_size:
+       have_bits = true;
+       bits = attribute_value_as_int (&attr_data);
+       break;
+ 
      case DW_AT_bit_offset:
!       have_offset = true;
!       offset = attribute_value_as_int (&attr_data);
        break;
      }
    LTO_END_READ_ATTRS ();
*************** lto_read_base_type_DIE (lto_info_fd *fd,
*** 2633,2641 ****
    if (!have_encoding || !have_size)
      lto_file_corrupt_error ((lto_fd *)fd);
  
!   lto_read_child_DIEs (fd, abbrev, context);
  
!   bits = (BITS_PER_UNIT * size);
  
    /* Build the type.  */
    switch (encoding)
--- 2646,2671 ----
    if (!have_encoding || !have_size)
      lto_file_corrupt_error ((lto_fd *)fd);
  
!   /* The DWARF spec implies that DW_AT_bit_size and DW_AT_bit_offset go
!      together as a pair.  We only support the case where integral types are
!      aligned in the low order bits of its containing word, which is how
!      dwarf2out.c encodes types with "weird" precisions.  */
!   maxbits = BITS_PER_UNIT * size;
!   if (have_offset && have_bits)
!     {
!       if (bits > maxbits)
! 	lto_file_corrupt_error ((lto_fd *)fd);
!       if (encoding != DW_ATE_unsigned && encoding != DW_ATE_signed)
! 	sorry ("bit size attribute only supported for signed/unsigned types");
!       if (offset != maxbits - bits)
! 	sorry ("unaligned base type not supported");
!     }
!   else if (have_offset || have_bits)
!     lto_file_corrupt_error ((lto_fd *)fd);
!   else
!     bits = maxbits;
  
!   lto_read_child_DIEs (fd, abbrev, context);
  
    /* Build the type.  */
    switch (encoding)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]