* dwarf2read.c (struct dwarf2_per_cu_data): New field type_hash.

(struct dwarf2_offset_and_type): New.
	(set_die_type, reset_die_and_siblings_types, get_die_type)
	(offset_and_type_hash, offset_and_type_eq): New functions.
	(read_structure_type, read_enumeration_type, read_array_type)
	(read_namespace, read_tag_pointer_type, read_tag_ptr_to_member_type)
	(read_tag_reference_type, read_tag_const_type)
	(read_tag_volatile_type, read_tag_string_type, read_subroutine_type)
	(read_typedef, read_base_type, read_subrange_type): Use
	set_die_type.
This commit is contained in:
Daniel Jacobowitz
2004-09-21 15:04:41 +00:00
parent f1760497bf
commit 1c379e2004
2 changed files with 147 additions and 15 deletions

View File

@ -1,3 +1,16 @@
2004-09-21 Daniel Jacobowitz <dan@debian.org>
* dwarf2read.c (struct dwarf2_per_cu_data): New field type_hash.
(struct dwarf2_offset_and_type): New.
(set_die_type, reset_die_and_siblings_types, get_die_type)
(offset_and_type_hash, offset_and_type_eq): New functions.
(read_structure_type, read_enumeration_type, read_array_type)
(read_namespace, read_tag_pointer_type, read_tag_ptr_to_member_type)
(read_tag_reference_type, read_tag_const_type)
(read_tag_volatile_type, read_tag_string_type, read_subroutine_type)
(read_typedef, read_base_type, read_subrange_type): Use
set_die_type.
2004-09-20 Daniel Jacobowitz <dan@debian.org> 2004-09-20 Daniel Jacobowitz <dan@debian.org>
* Makefile.in (dwarf2read.o): Update dependencies. * Makefile.in (dwarf2read.o): Update dependencies.

View File

@ -353,6 +353,13 @@ struct dwarf2_per_cu_data
/* Set iff currently read in. */ /* Set iff currently read in. */
struct dwarf2_cu *cu; struct dwarf2_cu *cu;
/* If full symbols for this CU have been read in, then this field
holds a map of DIE offsets to types. It isn't always possible
to reconstruct this information later, so we have to preserve
it. */
htab_t type_hash;
}; };
/* The line number information for a compilation unit (found in the /* The line number information for a compilation unit (found in the
@ -1035,6 +1042,14 @@ static void age_cached_comp_units (void);
static void free_one_cached_comp_unit (void *); static void free_one_cached_comp_unit (void *);
static void set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *);
#if 0
static void reset_die_and_siblings_types (struct die_info *,
struct dwarf2_cu *);
#endif
static void create_all_comp_units (struct objfile *); static void create_all_comp_units (struct objfile *);
static void dwarf2_mark (struct dwarf2_cu *); static void dwarf2_mark (struct dwarf2_cu *);
@ -3600,7 +3615,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
/* We need to add the type field to the die immediately so we don't /* We need to add the type field to the die immediately so we don't
infinitely recurse when dealing with pointers to the structure infinitely recurse when dealing with pointers to the structure
type within the structure itself. */ type within the structure itself. */
die->type = type; set_die_type (die, type, cu);
if (die->child != NULL && ! die_is_declaration (die, cu)) if (die->child != NULL && ! die_is_declaration (die, cu))
{ {
@ -3776,7 +3791,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_LENGTH (type) = 0; TYPE_LENGTH (type) = 0;
} }
die->type = type; set_die_type (die, type, cu);
} }
/* Determine the name of the type represented by DIE, which should be /* Determine the name of the type represented by DIE, which should be
@ -3942,7 +3957,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
{ {
index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu); index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
range_type = create_range_type (NULL, index_type, 0, -1); range_type = create_range_type (NULL, index_type, 0, -1);
die->type = create_array_type (NULL, element_type, range_type); set_die_type (die, create_array_type (NULL, element_type, range_type),
cu);
return; return;
} }
@ -4002,7 +4018,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
do_cleanups (back_to); do_cleanups (back_to);
/* Install the type in the die. */ /* Install the type in the die. */
die->type = type; set_die_type (die, type, cu);
} }
static enum dwarf_array_dim_ordering static enum dwarf_array_dim_ordering
@ -4129,7 +4145,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
TYPE_TAG_NAME (type) = TYPE_NAME (type); TYPE_TAG_NAME (type) = TYPE_NAME (type);
new_symbol (die, type, cu); new_symbol (die, type, cu);
die->type = type; set_die_type (die, type, cu);
if (is_anonymous) if (is_anonymous)
cp_add_using_directive (processing_current_prefix, cp_add_using_directive (processing_current_prefix,
@ -4236,7 +4252,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
} }
TYPE_LENGTH (type) = byte_size; TYPE_LENGTH (type) = byte_size;
die->type = type; set_die_type (die, type, cu);
} }
/* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to /* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
@ -4260,7 +4276,7 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
domain = die_containing_type (die, cu); domain = die_containing_type (die, cu);
smash_to_member_type (type, domain, to_type); smash_to_member_type (type, domain, to_type);
die->type = type; set_die_type (die, type, cu);
} }
/* Extract all information from a DW_TAG_reference_type DIE and add to /* Extract all information from a DW_TAG_reference_type DIE and add to
@ -4288,7 +4304,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
{ {
TYPE_LENGTH (type) = cu_header->addr_size; TYPE_LENGTH (type) = cu_header->addr_size;
} }
die->type = type; set_die_type (die, type, cu);
} }
static void static void
@ -4302,7 +4318,8 @@ read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
} }
base_type = die_type (die, cu); base_type = die_type (die, cu);
die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0); set_die_type (die, make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0),
cu);
} }
static void static void
@ -4316,7 +4333,8 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
} }
base_type = die_type (die, cu); base_type = die_type (die, cu);
die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0); set_die_type (die, make_cv_type (TYPE_CONST (base_type), 1, base_type, 0),
cu);
} }
/* Extract all information from a DW_TAG_string_type DIE and add to /* Extract all information from a DW_TAG_string_type DIE and add to
@ -4368,7 +4386,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu); char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
type = create_string_type (char_type, range_type); type = create_string_type (char_type, range_type);
} }
die->type = type; set_die_type (die, type, cu);
} }
/* Handle DIES due to C code like: /* Handle DIES due to C code like:
@ -4450,7 +4468,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
} }
} }
die->type = ftype; set_die_type (die, ftype, cu);
} }
static void static void
@ -4467,7 +4485,9 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{ {
name = DW_STRING (attr); name = DW_STRING (attr);
} }
die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile); set_die_type (die, init_type (TYPE_CODE_TYPEDEF, 0,
TYPE_FLAG_TARGET_STUB, name, objfile),
cu);
TYPE_TARGET_TYPE (die->type) = die_type (die, cu); TYPE_TARGET_TYPE (die->type) = die_type (die, cu);
} }
} }
@ -4555,7 +4575,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
{ {
type = dwarf_base_type (encoding, size, cu); type = dwarf_base_type (encoding, size, cu);
} }
die->type = type; set_die_type (die, type, cu);
} }
/* Read the given DW_AT_subrange DIE. */ /* Read the given DW_AT_subrange DIE. */
@ -4626,7 +4646,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (attr) if (attr)
TYPE_LENGTH (range_type) = DW_UNSND (attr); TYPE_LENGTH (range_type) = DW_UNSND (attr);
die->type = range_type; set_die_type (die, range_type, cu);
} }
@ -9252,6 +9272,105 @@ free_one_cached_comp_unit (void *target_cu)
} }
} }
/* A pair of DIE offset and GDB type pointer. We store these
in a hash table separate from the DIEs, and preserve them
when the DIEs are flushed out of cache. */
struct dwarf2_offset_and_type
{
unsigned int offset;
struct type *type;
};
/* Hash function for a dwarf2_offset_and_type. */
static hashval_t
offset_and_type_hash (const void *item)
{
const struct dwarf2_offset_and_type *ofs = item;
return ofs->offset;
}
/* Equality function for a dwarf2_offset_and_type. */
static int
offset_and_type_eq (const void *item_lhs, const void *item_rhs)
{
const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
return ofs_lhs->offset == ofs_rhs->offset;
}
/* Set the type associated with DIE to TYPE. Save it in CU's hash
table if necessary. */
static void
set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct dwarf2_offset_and_type **slot, ofs;
die->type = type;
if (cu->per_cu == NULL)
return;
if (cu->per_cu->type_hash == NULL)
cu->per_cu->type_hash
= htab_create_alloc_ex (cu->header.length / 24,
offset_and_type_hash,
offset_and_type_eq,
NULL,
&cu->objfile->objfile_obstack,
hashtab_obstack_allocate,
dummy_obstack_deallocate);
ofs.offset = die->offset;
ofs.type = type;
slot = (struct dwarf2_offset_and_type **)
htab_find_slot_with_hash (cu->per_cu->type_hash, &ofs, ofs.offset, INSERT);
*slot = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (**slot));
**slot = ofs;
}
#if 0
/* Find the type for DIE in TYPE_HASH, or return NULL if DIE does not
have a saved type. */
static struct type *
get_die_type (struct die_info *die, htab_t type_hash)
{
struct dwarf2_offset_and_type *slot, ofs;
ofs.offset = die->offset;
slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
if (slot)
return slot->type;
else
return NULL;
}
/* Restore the types of the DIE tree starting at START_DIE from the hash
table saved in CU. */
static void
reset_die_and_siblings_types (struct die_info *start_die, struct dwarf2_cu *cu)
{
struct die_info *die;
if (cu->per_cu->type_hash == NULL)
return;
for (die = start_die; die != NULL; die = die->sibling)
{
die->type = get_die_type (die, cu->per_cu->type_hash);
if (die->child != NULL)
reset_die_and_siblings_types (die->child, cu);
}
}
#endif
/* Set the mark field in CU and in every other compilation unit in the /* Set the mark field in CU and in every other compilation unit in the
cache that we must keep because we are keeping CU. */ cache that we must keep because we are keeping CU. */