]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
new_fn_field refactor.
authorKeith Seitz <keiths@redhat.com>
Tue, 21 Feb 2017 21:32:51 +0000 (13:32 -0800)
committerKeith Seitz <keiths@redhat.com>
Tue, 21 Feb 2017 21:32:51 +0000 (13:32 -0800)
gdb/dwarf2read.c

index 3edf6dbf77bd7679c387b3edebc2670c064ad590..d6e074725af9f29f5fbdc5d8012bccb185adfa8a 100644 (file)
@@ -1796,6 +1796,12 @@ static int attr_to_dynamic_prop (const struct attribute *attr,
                                 struct die_info *die, struct dwarf2_cu *cu,
                                 struct dynamic_prop *prop);
 
+static struct fn_field new_fn_field
+  (struct die_info *name_die, struct dwarf2_cu *name_cu,
+   struct die_info *type_die, struct dwarf2_cu *type_cu,
+   struct type *type, const char *fieldname,
+   int fnl_idx, int field_idx);
+
 /* memory allocation interface */
 
 static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
@@ -13051,91 +13057,53 @@ dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu)
          && (type_name[len] == '\0' || type_name[len] == '<'));
 }
 
-/* Add a member function to the proper fieldlist.  */
+/* Create a new fn_field which may represent an alias to an existing
+   field (if a constructor or destructor).  TYPE_DIE and TYPE_CU
+   may be NULL, in which case they default to NAME_DIE and NAME_CU,
+   i.e., not an aliased method.  */
 
-static void
-dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
-                     struct type *type, struct dwarf2_cu *cu)
+static struct fn_field
+new_fn_field (struct die_info *name_die, struct dwarf2_cu *name_cu,
+             struct die_info *type_die, struct dwarf2_cu *type_cu,
+             struct type *type, const char *fieldname,
+             int fnl_idx, int field_idx)
 {
-  struct objfile *objfile = cu->objfile;
+  struct fn_field fnfield;
+  struct objfile *objfile;
   struct attribute *attr;
-  struct fnfieldlist *flp;
-  int i;
-  struct fn_field *fnp;
-  const char *fieldname;
-  struct nextfnfield *new_fnfield;
   struct type *this_type;
   enum dwarf_access_attribute accessibility;
 
-  if (cu->language == language_ada)
-    error (_("unexpected member function in Ada type"));
+  memset (&fnfield, 0, sizeof (fnfield));
 
-  /* Get name of member function.  */
-  fieldname = dwarf2_name (die, cu);
-  if (fieldname == NULL)
-    return;
+  if (type_die == NULL)
+    type_die = name_die;
+  if (type_cu == NULL)
+    type_cu = name_cu;
 
-  /* Look up member function name in fieldlist.  */
-  for (i = 0; i < fip->nfnfields; i++)
-    {
-      if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0)
-       break;
-    }
-
-  /* Create new list element if necessary.  */
-  if (i < fip->nfnfields)
-    flp = &fip->fnfieldlists[i];
-  else
-    {
-      if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
-       {
-         fip->fnfieldlists = (struct fnfieldlist *)
-           xrealloc (fip->fnfieldlists,
-                     (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
-                     * sizeof (struct fnfieldlist));
-         if (fip->nfnfields == 0)
-           make_cleanup (free_current_contents, &fip->fnfieldlists);
-       }
-      flp = &fip->fnfieldlists[fip->nfnfields];
-      flp->name = fieldname;
-      flp->length = 0;
-      flp->head = NULL;
-      i = fip->nfnfields++;
-    }
-
-  /* Create a new member function field and chain it to the field list
-     entry.  */
-  new_fnfield = XNEW (struct nextfnfield);
-  make_cleanup (xfree, new_fnfield);
-  memset (new_fnfield, 0, sizeof (struct nextfnfield));
-  new_fnfield->next = flp->head;
-  flp->head = new_fnfield;
-  flp->length++;
-
-  /* Fill in the member function field info.  */
-  fnp = &new_fnfield->fnfield;
+  objfile = type_cu->objfile;
 
   /* Delay processing of the physname until later.  */
-  if (cu->language == language_cplus)
+  if (type_cu->language == language_cplus)
     {
-      add_to_method_list (type, i, flp->length - 1, fieldname,
-                         die, cu);
+      add_to_method_list (type, field_idx, fnl_idx, fieldname,
+                         name_die, name_cu);
     }
   else
     {
-      const char *physname = dwarf2_physname (fieldname, die, cu);
-      fnp->physname = physname ? physname : "";
+      const char *physname = dwarf2_physname (fieldname, name_die, name_cu);
+      fnfield.physname = physname ? physname : "";
     }
 
-  fnp->type = alloc_type (objfile);
-  this_type = read_type_die (die, cu);
+  fnfield.type = alloc_type (objfile);
+  this_type = read_type_die (type_die, type_cu);
   if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
     {
       int nparams = TYPE_NFIELDS (this_type);
 
       /* TYPE is the domain of this method, and THIS_TYPE is the type
           of the method itself (TYPE_CODE_METHOD).  */
-      smash_to_method_type (fnp->type, type,
+      smash_to_method_type (fnfield.type, type,
                            TYPE_TARGET_TYPE (this_type),
                            TYPE_FIELDS (this_type),
                            TYPE_NFIELDS (this_type),
@@ -13148,41 +13116,44 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
          pointer) as artificial.  We obtain this information from
          read_subroutine_type via TYPE_FIELD_ARTIFICIAL.  */
       if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (this_type, 0) == 0)
-       fnp->voffset = VOFFSET_STATIC;
+       fnfield.voffset = VOFFSET_STATIC;
     }
   else
     complaint (&symfile_complaints, _("member function type missing for '%s'"),
-              dwarf2_full_name (fieldname, die, cu));
+              dwarf2_full_name (fieldname, name_die, name_cu));
 
   /* Get fcontext from DW_AT_containing_type if present.  */
-  if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
-    fnp->fcontext = die_containing_type (die, cu);
+  if (dwarf2_attr (type_die, DW_AT_containing_type, type_cu) != NULL)
+    fnfield.fcontext = die_containing_type (type_die, type_cu);
 
   /* dwarf2 doesn't have stubbed physical names, so the setting of is_const and
      is_volatile is irrelevant, as it is needed by gdb_mangle_name only.  */
 
   /* Get accessibility.  */
-  attr = dwarf2_attr (die, DW_AT_accessibility, cu);
+  attr = dwarf2_attr (type_die, DW_AT_accessibility, type_cu);
   if (attr)
     accessibility = (enum dwarf_access_attribute) DW_UNSND (attr);
   else
-    accessibility = dwarf2_default_access_attribute (die, cu);
+    accessibility = dwarf2_default_access_attribute (type_die, type_cu);
   switch (accessibility)
     {
+    case DW_ACCESS_public:
+      fnfield.is_public = 1;
+      break;
     case DW_ACCESS_private:
-      fnp->is_private = 1;
+      fnfield.is_private = 1;
       break;
     case DW_ACCESS_protected:
-      fnp->is_protected = 1;
+      fnfield.is_protected = 1;
       break;
     }
 
   /* Check for artificial methods.  */
-  attr = dwarf2_attr (die, DW_AT_artificial, cu);
+  attr = dwarf2_attr (type_die, DW_AT_artificial, type_cu);
   if (attr && DW_UNSND (attr) != 0)
-    fnp->is_artificial = 1;
+    fnfield.is_artificial = 1;
 
-  fnp->is_constructor = dwarf2_is_constructor (die, cu);
+  fnfield.is_constructor = dwarf2_is_constructor (name_die, type_cu);
 
   /* Get index in virtual function table if it is a virtual member
      function.  For older versions of GCC, this is an offset in the
@@ -13190,7 +13161,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
      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);
+  attr = dwarf2_attr (type_die, DW_AT_vtable_elem_location, type_cu);
   if (attr)
     {
       if (attr_form_is_block (attr) && DW_BLOCK (attr)->size > 0)
@@ -13198,24 +13169,24 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
          if (DW_BLOCK (attr)->data[0] == DW_OP_constu)
            {
              /* Old-style GCC.  */
-             fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
+             fnfield.voffset = decode_locdesc (DW_BLOCK (attr), type_cu) + 2;
            }
          else if (DW_BLOCK (attr)->data[0] == DW_OP_deref
                   || (DW_BLOCK (attr)->size > 1
                       && DW_BLOCK (attr)->data[0] == DW_OP_deref_size
-                      && DW_BLOCK (attr)->data[1] == cu->header.addr_size))
+                      && DW_BLOCK (attr)->data[1] == type_cu->header.addr_size))
            {
-             fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu);
-             if ((fnp->voffset % cu->header.addr_size) != 0)
+             fnfield.voffset = decode_locdesc (DW_BLOCK (attr), type_cu);
+             if ((fnfield.voffset % type_cu->header.addr_size) != 0)
                dwarf2_complex_location_expr_complaint ();
              else
-               fnp->voffset /= cu->header.addr_size;
-             fnp->voffset += 2;
+               fnfield.voffset /= type_cu->header.addr_size;
+             fnfield.voffset += 2;
            }
          else
            dwarf2_complex_location_expr_complaint ();
 
-         if (!fnp->fcontext)
+         if (!fnfield.fcontext)
            {
              /* If there is no `this' field and no DW_AT_containing_type,
                 we cannot actually find a base class context for the
@@ -13226,11 +13197,11 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
                  complaint (&symfile_complaints,
                             _("cannot determine context for virtual member "
                               "function \"%s\" (offset %d)"),
-                            fieldname, die->offset.sect_off);
+                            fieldname, type_die->offset.sect_off);
                }
              else
                {
-                 fnp->fcontext
+                 fnfield.fcontext
                    = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0));
                }
            }
@@ -13247,18 +13218,81 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     }
   else
     {
-      attr = dwarf2_attr (die, DW_AT_virtuality, cu);
+      attr = dwarf2_attr (type_die, DW_AT_virtuality, type_cu);
       if (attr && DW_UNSND (attr))
        {
          /* GCC does this, as of 2008-08-25; PR debug/37237.  */
          complaint (&symfile_complaints,
                     _("Member function \"%s\" (offset %d) is virtual "
                       "but the vtable offset is not specified"),
-                    fieldname, die->offset.sect_off);
+                    fieldname, type_die->offset.sect_off);
          ALLOCATE_CPLUS_STRUCT_TYPE (type);
          TYPE_CPLUS_DYNAMIC (type) = 1;
        }
     }
+
+  return fnfield;
+}
+
+/* Add a member function to the proper fieldlist.  */
+
+static void
+dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
+                     struct type *type, struct dwarf2_cu *cu)
+{
+  struct fnfieldlist *flp;
+  int i;
+  const char *fieldname, *linkage_name;
+  struct nextfnfield *new_fnfield;
+
+  if (cu->language == language_ada)
+    error (_("unexpected member function in Ada type"));
+
+  /* Get name of member function.  */
+  fieldname = dwarf2_name (die, cu);
+  if (fieldname == NULL)
+    return;
+
+  /* Look up member function name in fieldlist.  */
+  for (i = 0; i < fip->nfnfields; i++)
+    {
+      if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0)
+       break;
+    }
+
+  /* Create new list element if necessary.  */
+  if (i < fip->nfnfields)
+    flp = &fip->fnfieldlists[i];
+  else
+    {
+      if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
+       {
+         fip->fnfieldlists = (struct fnfieldlist *)
+           xrealloc (fip->fnfieldlists,
+                     (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
+                     * sizeof (struct fnfieldlist));
+         if (fip->nfnfields == 0)
+           make_cleanup (free_current_contents, &fip->fnfieldlists);
+       }
+      flp = &fip->fnfieldlists[fip->nfnfields];
+      flp->name = fieldname;
+      flp->length = 0;
+      flp->head = NULL;
+      i = fip->nfnfields++;
+    }
+
+  /* Create a new member function field and chain it to the field list
+     entry.  */
+  new_fnfield = XNEW (struct nextfnfield);
+  make_cleanup (xfree, new_fnfield);
+  memset (new_fnfield, 0, sizeof (struct nextfnfield));
+  new_fnfield->next = flp->head;
+  flp->head = new_fnfield;
+  flp->length++;
+
+  /* Fill in the member function field info.  */
+  new_fnfield->fnfield = new_fn_field (die, cu, NULL, NULL, type, fieldname,
+                                      flp->length - 1, i);
 }
 
 /* Create the vector of member function fields, and attach it to the type.  */