]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2006-05-03 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Wed, 3 May 2006 01:51:29 +0000 (01:51 +0000)
committerPaul Brook <paul@codesourcery.com>
Wed, 3 May 2006 01:51:29 +0000 (01:51 +0000)
* gdb/dwarf2read.c (field_info): Add baseclasses.
(dwarf2_add_field): Check base classes.
(dwarf2_attach_fields_to_type): Ditto.

* gdb/gnu-v3-abi.c (gnuv3_rtti_type): Check for NULL base_type.
(gnuv3_virtual_fn_field): Handle missing base.
(gnuv3_baseclass_offset): Handle missing vptr.
* gdb/varobj.c (cplus_class_num_children): Call fill_in_vptr_fieldno.
(cplus_name_of_child): Ditto.
* gdb/eval.c (evaluate_subexp_standard): Ditto.
* gdb/dwarf2read.c (read_structure_type): Search for vtable pointer
by name in objects built by ARM compiler.

* gdb/dwarf2read.c (dwarf2_add_member_fn): Calculate virtual function
offset for classes without DW_AT_containing_type.

ChangeLog.csl
gdb/dwarf2read.c
gdb/eval.c
gdb/gnu-v3-abi.c
gdb/varobj.c

index 655a71cc44eb4271ed8cd388f29f779f6a6eb7c3..6360714e4eaf08a73ffd65b0e96a2f756db61073 100644 (file)
@@ -1,3 +1,21 @@
+2006-05-03  Paul Brook  <paul@codesourcery.com>
+
+       * gdb/dwarf2read.c (field_info): Add baseclasses.
+       (dwarf2_add_field): Check base classes.
+       (dwarf2_attach_fields_to_type): Ditto.
+       
+       * gdb/gnu-v3-abi.c (gnuv3_rtti_type): Check for NULL base_type.
+       (gnuv3_virtual_fn_field): Handle missing base.
+       (gnuv3_baseclass_offset): Handle missing vptr.
+       * gdb/varobj.c (cplus_class_num_children): Call fill_in_vptr_fieldno.
+       (cplus_name_of_child): Ditto.
+       * gdb/eval.c (evaluate_subexp_standard): Ditto.
+       * gdb/dwarf2read.c (read_structure_type): Search for vtable pointer
+       by name in objects built by ARM compiler.
+       
+       * gdb/dwarf2read.c (dwarf2_add_member_fn): Calculate virtual function
+       offset for classes without DW_AT_containing_type.
+
 2006-04-28  Mark Mitchell  <mark@codesourcery.com>
 
        * gdb/mt-tdep.c (mt_register_name): Correct out-of-range logic to
index 6fe9245f4a24c86dec7b5480def5b46e1459e215..ecca17f11d171e3ed03d420615374014f9c80069 100644 (file)
@@ -604,9 +604,9 @@ struct field_info
        int virtuality;
        struct field field;
       }
-     *fields;
+     *fields, *baseclasses;
 
-    /* Number of fields.  */
+    /* Number of fields (including baseclasses).  */
     int nfields;
 
     /* Number of baseclasses.  */
@@ -3257,8 +3257,17 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
   new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
   make_cleanup (xfree, new_field);
   memset (new_field, 0, sizeof (struct nextfield));
-  new_field->next = fip->fields;
-  fip->fields = new_field;
+
+  if (die->tag == DW_TAG_inheritance)
+    {
+      new_field->next = fip->baseclasses;
+      fip->baseclasses = new_field;
+    }
+  else
+    {
+      new_field->next = fip->fields;
+      fip->fields = new_field;
+    }
   fip->nfields++;
 
   /* Handle accessibility and virtuality of field.
@@ -3464,8 +3473,21 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
      up in the same order in the array in which they were added to the list.  */
   while (nfields-- > 0)
     {
-      TYPE_FIELD (type, nfields) = fip->fields->field;
-      switch (fip->fields->accessibility)
+      struct nextfield *fieldp;
+
+      if (fip->fields)
+       {
+         fieldp = fip->fields;
+         fip->fields = fieldp->next;
+       }
+      else
+       {
+         fieldp = fip->baseclasses;
+         fip->baseclasses = fieldp->next;
+       }
+
+      TYPE_FIELD (type, nfields) = fieldp->field;
+      switch (fieldp->accessibility)
        {
        case DW_ACCESS_private:
          SET_TYPE_FIELD_PRIVATE (type, nfields);
@@ -3482,13 +3504,13 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
          /* Unknown accessibility.  Complain and treat it as public.  */
          {
            complaint (&symfile_complaints, _("unsupported accessibility %d"),
-                      fip->fields->accessibility);
+                      fieldp->accessibility);
          }
          break;
        }
       if (nfields < fip->nbaseclasses)
        {
-         switch (fip->fields->virtuality)
+         switch (fieldp->virtuality)
            {
            case DW_VIRTUALITY_virtual:
            case DW_VIRTUALITY_pure_virtual:
@@ -3496,7 +3518,6 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
              break;
            }
        }
-      fip->fields = fip->fields->next;
     }
 }
 
@@ -3620,9 +3641,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   if (attr && DW_UNSND (attr) != 0)
     fnp->is_artificial = 1;
 
-  /* Get index in virtual function table if it is a virtual member function.  */
+  /* Get index in virtual function table if it is a virtual member
+     function.  For GCC, this is an offset in the appropriate
+     virtual table, as specified by DW_AT_containing_type.  For
+     everyone else, it is an expression to be evaluated relative
+     to the object address.  */
+
   attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
-  if (attr)
+  if (attr && fnp->fcontext)
     {
       /* Support the .debug_loc offsets */
       if (attr_form_is_block (attr))
@@ -3638,7 +3664,28 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
          dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location",
                                                 fieldname);
         }
-   }
+    }
+  else if (attr)
+    {
+      /* We only support trivial expressions here.  This hack will work
+         for v3 classes, which always start with the vtable pointer.  */
+      if (attr_form_is_block (attr) && DW_BLOCK (attr)->size > 0
+         && DW_BLOCK (attr)->data[0] == DW_OP_deref)
+       {
+         struct dwarf_block blk;
+         blk.size = DW_BLOCK (attr)->size - 1;
+         blk.data = DW_BLOCK (attr)->data + 1;
+          fnp->voffset = decode_locdesc (&blk, cu);
+          if ((fnp->voffset % cu->header.addr_size) != 0)
+            dwarf2_complex_location_expr_complaint ();
+          else
+            fnp->voffset /= cu->header.addr_size;
+         fnp->voffset += 2;
+         fnp->fcontext = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (die->type, 0));
+       }
+      else
+       dwarf2_complex_location_expr_complaint ();
+    }
 }
 
 /* Create the vector of member function fields, and attach it to the type.  */
@@ -3825,7 +3872,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 
          /* Get the type which refers to the base class (possibly this
             class itself) which contains the vtable pointer for the current
-            class from the DW_AT_containing_type attribute.  */
+            class from the DW_AT_containing_type attribute.  This use of
+            DW_AT_containing_type is a GNU extension.  */
 
          if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
            {
@@ -3884,6 +3932,28 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
                    }
                }
            }
+         else if (cu->producer
+                  && strncmp (cu->producer,
+                              "ARM/Thumb C/C++ Compiler, RVCT", 30) == 0)
+           {
+             /* The ARM compiler does not provide direct indication
+                of the containing type, but the vtable pointer is
+                always named __vptr.  */
+
+             int i;
+
+             for (i = TYPE_NFIELDS (type) - 1;
+                  i >= TYPE_N_BASECLASSES (type);
+                  --i)
+               {
+                 if (strcmp (TYPE_FIELD_NAME (type, i), "__vptr") == 0)
+                   {
+                     TYPE_VPTR_FIELDNO (type) = i;
+                     TYPE_VPTR_BASETYPE (type) = type;
+                     break;
+                   }
+               }
+           }
        }
 
       do_cleanups (back_to);
index 66776ea3cac2d9afa4824b2264a06cc1acd686e7..ac9a5ee19de6599103d9d341b1ccf8396e01d697 100644 (file)
@@ -1035,6 +1035,7 @@ evaluate_subexp_standard (struct type *expect_type,
              basetype = TYPE_TARGET_TYPE (value_type (arg2));
              if (domain_type != basetype)
                arg2 = value_cast (lookup_pointer_type (domain_type), arg2);
+             fill_in_vptr_fieldno (domain_type);
              basetype = TYPE_VPTR_BASETYPE (domain_type);
              for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--)
                {
index 383b475f1b171c5f12a8975ca6c3e7142044993c..c5fcfa7a5facdd59c6f20c1e96910eb13043bd7d 100644 (file)
@@ -216,7 +216,10 @@ gnuv3_rtti_type (struct value *value,
 
   /* Fetch VALUE's virtual table pointer, and tweak it to point at
      an instance of our imaginary gdb_gnu_v3_abi_vtable structure.  */
-  base_type = check_typedef (TYPE_VPTR_BASETYPE (values_type));
+  base_type = TYPE_VPTR_BASETYPE (values_type);
+  if (base_type == NULL)
+    return NULL;
+  base_type = check_typedef (base_type);
   if (values_type != base_type)
     {
       value = value_cast (base_type, value);
@@ -302,6 +305,10 @@ gnuv3_virtual_fn_field (struct value **value_p,
        multiple inheritance, but it's better than nothing.  */
     vfn_base = TYPE_VPTR_BASETYPE (type);
 
+  if (! vfn_base)
+    error (_("Could not find virtual table pointer for class \"%s\"."),
+          TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "<unknown>");
+
   /* This type may have been defined before its virtual function table
      was.  If so, fill in the virtual function table entry for the
      type now.  */
@@ -397,9 +404,13 @@ gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
      start of whichever baseclass it resides in, as a sanity measure - iff
      we have debugging information for that baseclass.  */
 
+  if (TYPE_VPTR_FIELDNO (type) < 0)
+    fill_in_vptr_fieldno (type);
+  if (TYPE_VPTR_FIELDNO (type) < 0)
+    error (_("Could not find virtual table pointer for class \"%s\"."),
+          TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "<unknown>");
+
   vbasetype = TYPE_VPTR_BASETYPE (type);
-  if (TYPE_VPTR_FIELDNO (vbasetype) < 0)
-    fill_in_vptr_fieldno (vbasetype);
 
   if (TYPE_VPTR_FIELDNO (vbasetype) >= 0
       && TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0)
index 532d819917a6b017ae0a65fd7e5a7689d2601c97..babb685fbf58adf6eac0ac2a4139d06bf47820fc 100644 (file)
@@ -2169,6 +2169,7 @@ cplus_class_num_children (struct type *type, int children[3])
   children[v_private] = 0;
   children[v_protected] = 0;
 
+  fill_in_vptr_fieldno (type);
   for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
     {
       /* If we have a virtual table pointer, omit it. */
@@ -2218,6 +2219,7 @@ cplus_name_of_child (struct varobj *parent, int index)
             have the access control we are looking for to properly
             find the indexed field. */
          int type_index = TYPE_N_BASECLASSES (type);
+         fill_in_vptr_fieldno (type);
          if (strcmp (parent->name, "private") == 0)
            {
              while (index >= 0)