This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[RFA-v3] dwarf2read.c: Avoid complaint for char array of unspecified size


> Pierre> +  if (die->num_attrs == 0)
> 
> A DW_TAG_subrange_type might have attributes that we ignore.  So, I
> think there is no need for a check that is this specific; just
> determine
> the type according to the above algorithm, and remove the existing
> complaint code.
> 
> Tom

  OK, I tried to follow that route,
the tricky part was that we don't really know which objfile type
is the same size as an address, but the patch is a bit lengthy...
  At the same time, I discovered that DW_AT_count was not supported,
(maybe no compiler uses that, but it can't hurt to add
support for this).


Pierre

2010-05-28  Pierre Muller  <muller@ics.u-strasbg.fr>

	* dwarf2read.c (read_subrange_type): Handle missing base type
	according to Dwarf-2 specifications.
	Also handle DW_AT_count attribute.

Index: src/gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.388
diff -u -p -r1.388 dwarf2read.c
--- src/gdb/dwarf2read.c	21 May 2010 20:45:19 -0000	1.388
+++ src/gdb/dwarf2read.c	28 May 2010 08:39:58 -0000
@@ -6129,16 +6131,8 @@ read_subrange_type (struct die_info *die
   LONGEST high = -1;
   char *name;
   LONGEST negative_mask;
-  
+
   base_type = die_type (die, cu);
-  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
-    {
-      complaint (&symfile_complaints,
-                _("DW_AT_type missing from DW_TAG_subrange_type"));
-      base_type
-	= init_type (TYPE_CODE_INT, gdbarch_addr_bit (gdbarch) / 8,
-		     0, NULL, cu->objfile);
-    }
 
   if (cu->language == language_fortran)
     { 
@@ -6156,10 +6150,10 @@ read_subrange_type (struct die_info *die
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
   if (attr)
     {       
-      if (attr->form == DW_FORM_block1)
+      if (attr->form == DW_FORM_block1 || is_ref_attr (attr))
         {
           /* GCC encodes arrays with unspecified or dynamic length
-             with a DW_FORM_block1 attribute.
+             with a DW_FORM_block1 attribute or a reference attribute.
              FIXME: GDB does not yet know how to handle dynamic
              arrays properly, treat them as arrays with unspecified
              length for now.
@@ -6174,6 +6168,48 @@ read_subrange_type (struct die_info *die
       else
         high = dwarf2_get_attr_constant_value (attr, 1);
     }
+  else
+    {
+      attr = dwarf2_attr (die, DW_AT_count, cu);
+      if (attr)
+	{
+	  int count = dwarf2_get_attr_constant_value (attr, 1);
+	  high = low + count - 1;
+	}
+    }
+
+  /* Dwarf-2 specifications explicitly allows to create subrange types
+     without specifying a base type.
+     In that case, the base type must be set to the type of
+     the lower bound, upper bound or count, in that order, if any of these
+     three attributes references an object that has a type.
+     If no base type is found, the Dwarf-2 specifications say that
+     a signed integer type of size equal to the size of an address should
+     be used.
+     For the following C code: `extern char gdb_int [];'
+     GCC produces an empty range DIE.
+     FIXME: muller/2010-05-28: Possible references to object for low bound,
+     high bound or count are not yet handled by this code.
+  */
+  if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+    {
+      struct objfile *objfile = cu->objfile;
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      int addr_size = gdbarch_addr_bit (gdbarch) /8;
+      struct type *int_type = objfile_type (objfile)->builtin_long_long;
+
+      /* Test "long long int", "long int", and "int" objfile types,
+	 and select the last one having a size above or equal to the
+	 architecture address size.  */
+      if (int_type && TYPE_LENGTH (int_type) >= addr_size)
+	base_type = int_type;
+      int_type = objfile_type (objfile)->builtin_long;
+      if (int_type && TYPE_LENGTH (int_type) >= addr_size)
+	base_type = int_type;
+      int_type = objfile_type (objfile)->builtin_int;
+      if (int_type && TYPE_LENGTH (int_type) >= addr_size)
+	base_type = int_type;
+    }
 
   negative_mask = 
     (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);


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