PR symtab/11465:
* dwarf2read.c (struct delayed_method_info): New struct. (struct dwarf2_cu): Add vector method_list. (scan_partial_symbols): Count methods for union, class, structure, and interface types. (add_to_method_list): New function. (free_delayed_list): New function. (compute_delayed_physnames): New function. (process_full_comp_unit): Make a cleanup for the CU's delayed physname list, compute the delayed physnames, and free the the list. (dwarf2_add_member_fn): For C++ and Java, delay the computation of the physname until after the CU is read. * dwarf2read.c (read_structure_type): Check if the current DIE's type was already completed after dwarf2_full_name was called.
This commit is contained in:
parent
c37bf52837
commit
3da10d80f8
|
@ -1,3 +1,22 @@
|
|||
2010-08-20 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
PR symtab/11465:
|
||||
* dwarf2read.c (struct delayed_method_info): New struct.
|
||||
(struct dwarf2_cu): Add vector method_list.
|
||||
(scan_partial_symbols): Count methods for union, class, structure,
|
||||
and interface types.
|
||||
(add_to_method_list): New function.
|
||||
(free_delayed_list): New function.
|
||||
(compute_delayed_physnames): New function.
|
||||
(process_full_comp_unit): Make a cleanup for the CU's delayed
|
||||
physname list, compute the delayed physnames, and free the
|
||||
the list.
|
||||
(dwarf2_add_member_fn): For C++ and Java, delay the computation
|
||||
of the physname until after the CU is read.
|
||||
|
||||
* dwarf2read.c (read_structure_type): Check if the current
|
||||
DIE's type was already completed after dwarf2_full_name
|
||||
was called.
|
||||
2010-08-19 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* NEWS: Mention some additional changes.
|
||||
|
|
120
gdb/dwarf2read.c
120
gdb/dwarf2read.c
|
@ -266,6 +266,29 @@ struct comp_unit_head
|
|||
unsigned int first_die_offset;
|
||||
};
|
||||
|
||||
/* Type used for delaying computation of method physnames.
|
||||
See comments for compute_delayed_physnames. */
|
||||
struct delayed_method_info
|
||||
{
|
||||
/* The type to which the method is attached, i.e., its parent class. */
|
||||
struct type *type;
|
||||
|
||||
/* The index of the method in the type's function fieldlists. */
|
||||
int fnfield_index;
|
||||
|
||||
/* The index of the method in the fieldlist. */
|
||||
int index;
|
||||
|
||||
/* The name of the DIE. */
|
||||
const char *name;
|
||||
|
||||
/* The DIE associated with this method. */
|
||||
struct die_info *die;
|
||||
};
|
||||
|
||||
typedef struct delayed_method_info delayed_method_info;
|
||||
DEF_VEC_O (delayed_method_info);
|
||||
|
||||
/* Internal state when decoding a particular compilation unit. */
|
||||
struct dwarf2_cu
|
||||
{
|
||||
|
@ -344,6 +367,10 @@ struct dwarf2_cu
|
|||
/* Header data from the line table, during full symbol processing. */
|
||||
struct line_header *line_header;
|
||||
|
||||
/* A list of methods which need to have physnames computed
|
||||
after all type information has been read. */
|
||||
VEC (delayed_method_info) *method_list;
|
||||
|
||||
/* Mark used when releasing cached dies. */
|
||||
unsigned int mark : 1;
|
||||
|
||||
|
@ -1289,6 +1316,9 @@ byte_swap (offset_type value)
|
|||
/* The suffix for an index file. */
|
||||
#define INDEX_SUFFIX ".gdb-index"
|
||||
|
||||
static const char *dwarf2_physname (char *name, struct die_info *die,
|
||||
struct dwarf2_cu *cu);
|
||||
|
||||
/* Try to locate the sections we need for DWARF 2 debugging
|
||||
information and return true if we have enough to do something. */
|
||||
|
||||
|
@ -4342,6 +4372,56 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
|
|||
}
|
||||
}
|
||||
|
||||
/* Add a DIE to the delayed physname list. */
|
||||
|
||||
static void
|
||||
add_to_method_list (struct type *type, int fnfield_index, int index,
|
||||
const char *name, struct die_info *die,
|
||||
struct dwarf2_cu *cu)
|
||||
{
|
||||
struct delayed_method_info mi;
|
||||
mi.type = type;
|
||||
mi.fnfield_index = fnfield_index;
|
||||
mi.index = index;
|
||||
mi.name = name;
|
||||
mi.die = die;
|
||||
VEC_safe_push (delayed_method_info, cu->method_list, &mi);
|
||||
}
|
||||
|
||||
/* A cleanup for freeing the delayed method list. */
|
||||
|
||||
static void
|
||||
free_delayed_list (void *ptr)
|
||||
{
|
||||
struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr;
|
||||
if (cu->method_list != NULL)
|
||||
{
|
||||
VEC_free (delayed_method_info, cu->method_list);
|
||||
cu->method_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the physnames of any methods on the CU's method list.
|
||||
|
||||
The computation of method physnames is delayed in order to avoid the
|
||||
(bad) condition that one of the method's formal parameters is of an as yet
|
||||
incomplete type. */
|
||||
|
||||
static void
|
||||
compute_delayed_physnames (struct dwarf2_cu *cu)
|
||||
{
|
||||
int i;
|
||||
struct delayed_method_info *mi;
|
||||
for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
|
||||
{
|
||||
char *physname;
|
||||
struct fn_fieldlist *fn_flp
|
||||
= &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
|
||||
physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
|
||||
fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate full symbol information for PST and CU, whose DIEs have
|
||||
already been loaded into memory. */
|
||||
|
||||
|
@ -4352,13 +4432,14 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
|
|||
struct objfile *objfile = per_cu->objfile;
|
||||
CORE_ADDR lowpc, highpc;
|
||||
struct symtab *symtab;
|
||||
struct cleanup *back_to;
|
||||
struct cleanup *back_to, *delayed_list_cleanup;
|
||||
CORE_ADDR baseaddr;
|
||||
|
||||
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
|
||||
|
||||
buildsym_init ();
|
||||
back_to = make_cleanup (really_free_pendings, NULL);
|
||||
delayed_list_cleanup = make_cleanup (free_delayed_list, cu);
|
||||
|
||||
cu->list_in_scope = &file_symbols;
|
||||
|
||||
|
@ -4367,6 +4448,12 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
|
|||
/* Do line number decoding in read_file_scope () */
|
||||
process_die (cu->dies, cu);
|
||||
|
||||
/* Now that we have processed all the DIEs in the CU, all the types
|
||||
should be complete, and it should now be safe to compute all of the
|
||||
physnames. */
|
||||
compute_delayed_physnames (cu);
|
||||
do_cleanups (delayed_list_cleanup);
|
||||
|
||||
/* Some compilers don't define a DW_AT_high_pc attribute for the
|
||||
compilation unit. If the DW_AT_high_pc is missing, synthesize
|
||||
it, by scanning the DIE's below the compilation unit. */
|
||||
|
@ -6249,7 +6336,6 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
|||
int i;
|
||||
struct fn_field *fnp;
|
||||
char *fieldname;
|
||||
char *physname;
|
||||
struct nextfnfield *new_fnfield;
|
||||
struct type *this_type;
|
||||
|
||||
|
@ -6261,9 +6347,6 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
|||
if (fieldname == NULL)
|
||||
return;
|
||||
|
||||
/* Get the mangled name. */
|
||||
physname = (char *) dwarf2_physname (fieldname, die, cu);
|
||||
|
||||
/* Look up member function name in fieldlist. */
|
||||
for (i = 0; i < fip->nfnfields; i++)
|
||||
{
|
||||
|
@ -6289,7 +6372,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
|||
flp->name = fieldname;
|
||||
flp->length = 0;
|
||||
flp->head = NULL;
|
||||
fip->nfnfields++;
|
||||
i = fip->nfnfields++;
|
||||
}
|
||||
|
||||
/* Create a new member function field and chain it to the field list
|
||||
|
@ -6303,9 +6386,19 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
|||
|
||||
/* Fill in the member function field info. */
|
||||
fnp = &new_fnfield->fnfield;
|
||||
/* The name is already allocated along with this objfile, so we don't
|
||||
need to duplicate it for the type. */
|
||||
|
||||
/* Delay processing of the physname until later. */
|
||||
if (cu->language == language_cplus || cu->language == language_java)
|
||||
{
|
||||
add_to_method_list (type, i, flp->length - 1, fieldname,
|
||||
die, cu);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *physname = (char *) dwarf2_physname (fieldname, die, cu);
|
||||
fnp->physname = physname ? physname : "";
|
||||
}
|
||||
|
||||
fnp->type = alloc_type (objfile);
|
||||
this_type = read_type_die (die, cu);
|
||||
if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
|
||||
|
@ -6331,7 +6424,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
|||
}
|
||||
else
|
||||
complaint (&symfile_complaints, _("member function type missing for '%s'"),
|
||||
physname);
|
||||
dwarf2_full_name (fieldname, die, cu));
|
||||
|
||||
/* Get fcontext from DW_AT_containing_type if present. */
|
||||
if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
|
||||
|
@ -6579,7 +6672,14 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
if (cu->language == language_cplus
|
||||
|| cu->language == language_java)
|
||||
{
|
||||
TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (name, die, cu);
|
||||
char *full_name = (char *) dwarf2_full_name (name, die, cu);
|
||||
|
||||
/* dwarf2_full_name might have already finished building the DIE's
|
||||
type. If so, there is no need to continue. */
|
||||
if (get_die_type (die, cu) != NULL)
|
||||
return get_die_type (die, cu);
|
||||
|
||||
TYPE_TAG_NAME (type) = full_name;
|
||||
if (die->tag == DW_TAG_structure_type
|
||||
|| die->tag == DW_TAG_class_type)
|
||||
TYPE_NAME (type) = TYPE_TAG_NAME (type);
|
||||
|
|
Loading…
Reference in New Issue