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 *);
&& (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),
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
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)
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
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));
}
}
}
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. */