aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2004-09-21 15:04:41 +0000
committerDaniel Jacobowitz <drow@false.org>2004-09-21 15:04:41 +0000
commit1c379e20045b531fc5f5feb8ccc6441cd52c79a1 (patch)
treeb0dff92e84d1710bf4316f8da1715e9839ab870d /gdb/dwarf2read.c
parentf1760497bfb3b18b80912efb9227865371c6a316 (diff)
downloadgdb-1c379e20045b531fc5f5feb8ccc6441cd52c79a1.zip
gdb-1c379e20045b531fc5f5feb8ccc6441cd52c79a1.tar.gz
gdb-1c379e20045b531fc5f5feb8ccc6441cd52c79a1.tar.bz2
* 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.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c149
1 files changed, 134 insertions, 15 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index f31038b..e2caefe 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -353,6 +353,13 @@ struct dwarf2_per_cu_data
/* Set iff currently read in. */
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
@@ -1035,6 +1042,14 @@ static void age_cached_comp_units (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 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
infinitely recurse when dealing with pointers to the structure
type within the structure itself. */
- die->type = type;
+ set_die_type (die, type, 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;
}
- die->type = type;
+ set_die_type (die, type, cu);
}
/* 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);
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;
}
@@ -4002,7 +4018,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
do_cleanups (back_to);
/* Install the type in the die. */
- die->type = type;
+ set_die_type (die, type, cu);
}
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);
new_symbol (die, type, cu);
- die->type = type;
+ set_die_type (die, type, cu);
if (is_anonymous)
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;
- die->type = type;
+ set_die_type (die, type, cu);
}
/* 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);
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
@@ -4288,7 +4304,7 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
{
TYPE_LENGTH (type) = cu_header->addr_size;
}
- die->type = type;
+ set_die_type (die, type, cu);
}
static void
@@ -4302,7 +4318,8 @@ read_tag_const_type (struct die_info *die, struct dwarf2_cu *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
@@ -4316,7 +4333,8 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *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
@@ -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);
type = create_string_type (char_type, range_type);
}
- die->type = type;
+ set_die_type (die, type, cu);
}
/* 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
@@ -4467,7 +4485,9 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{
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);
}
}
@@ -4555,7 +4575,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
{
type = dwarf_base_type (encoding, size, cu);
}
- die->type = type;
+ set_die_type (die, type, cu);
}
/* Read the given DW_AT_subrange DIE. */
@@ -4626,7 +4646,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (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
cache that we must keep because we are keeping CU. */