diff options
author | David Carlton <carlton@bactrian.org> | 2003-09-09 23:23:05 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2003-09-09 23:23:05 +0000 |
commit | 91c24f0ad8427e4516d78e79977335d313d58f14 (patch) | |
tree | c8d3b5d4f3efd6f6c9c926b4a60f3f29e6f1b8e2 | |
parent | 962d6d933651e62669808c0ba27b7b94de60ba5f (diff) | |
download | gdb-91c24f0ad8427e4516d78e79977335d313d58f14.zip gdb-91c24f0ad8427e4516d78e79977335d313d58f14.tar.gz gdb-91c24f0ad8427e4516d78e79977335d313d58f14.tar.bz2 |
2003-09-09 David Carlton <carlton@kealia.com>
* dwarf2read.c (dwarf2_build_psymtabs_hard): Move lowpc and
highpc initialization here out of scan_partial_symbols.
(scan_partial_symbols): Restructure into a recursive version,
calling add_partial_namespace and add_partial_enumeration when
appropriate.
(add_partial_namespace): New.
(add_partial_enumeration, locate_pdi_sibling): Ditto.
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 222 |
2 files changed, 155 insertions, 77 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3ed38b7..9ce2e00 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2003-09-09 David Carlton <carlton@kealia.com> + + * dwarf2read.c (dwarf2_build_psymtabs_hard): Move lowpc and + highpc initialization here out of scan_partial_symbols. + (scan_partial_symbols): Restructure into a recursive version, + calling add_partial_namespace and add_partial_enumeration when + appropriate. + (add_partial_namespace): New. + (add_partial_enumeration, locate_pdi_sibling): Ditto. + 2003-09-09 Andrew Cagney <cagney@redhat.com> * rs6000-tdep.c (ppc_push_return_address): Delete function. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a8c3ca3..18b67a6 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -677,6 +677,22 @@ static char *scan_partial_symbols (char *, struct objfile *, static void add_partial_symbol (struct partial_die_info *, struct objfile *, const struct comp_unit_head *); +static char *add_partial_namespace (struct partial_die_info *pdi, + char *info_ptr, + struct objfile *objfile, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + const struct comp_unit_head *cu_header); + +static char *add_partial_enumeration (struct partial_die_info *enum_pdi, + char *info_ptr, + struct objfile *objfile, + const struct comp_unit_head *cu_header); + +static char *locate_pdi_sibling (struct partial_die_info *orig_pdi, + char *info_ptr, + bfd *abfd, + const struct comp_unit_head *cu_header); + static void dwarf2_psymtab_to_symtab (struct partial_symtab *); static void psymtab_to_symtab_1 (struct partial_symtab *); @@ -1321,9 +1337,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) If not, there's no more debug_info for this comp unit. */ if (comp_unit_die.has_children) { + lowpc = ((CORE_ADDR) -1); + highpc = ((CORE_ADDR) 0); + info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc, &cu_header); + /* If we didn't find a lowpc, set it to highpc to avoid + complaints from `maint check'. */ + if (lowpc == ((CORE_ADDR) -1)) + lowpc = highpc; + /* If the compilation unit didn't have an explicit address range, then use the information extracted from its child dies. */ if (! comp_unit_die.has_pc_info) @@ -1352,7 +1376,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) do_cleanups (back_to); } -/* Read in all interesting dies to the end of the compilation unit. */ +/* Read in all interesting dies to the end of the compilation unit or + to the end of the current namespace. */ static char * scan_partial_symbols (char *info_ptr, struct objfile *objfile, @@ -1362,35 +1387,24 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, bfd *abfd = objfile->obfd; struct partial_die_info pdi; - /* This function is called after we've read in the comp_unit_die in - order to read its children. We start the nesting level at 1 since - we have pushed 1 level down in order to read the comp unit's children. - The comp unit itself is at level 0, so we stop reading when we pop - back to that level. */ - - int nesting_level = 1; - - /* We only want to read in symbols corresponding to variables or - other similar objects that are global or static. Normally, these - are all children of the DW_TAG_compile_unit die, so are all at - level 1. But C++ namespaces give ries to DW_TAG_namespace dies - whose children are global objects. So we keep track of what - level we currently think of as referring to file scope; this - should always equal 1 plus the number of namespaces that we are - currently nested within. */ - - int file_scope_level = 1; + /* Now, march along the PDI's, descending into ones which have + interesting children but skipping the children of the other ones, + until we reach the end of the compilation unit. */ - *lowpc = ((CORE_ADDR) -1); - *highpc = ((CORE_ADDR) 0); - - while (nesting_level) + while (1) { + /* This flag tells whether or not info_ptr has gotten updated + inside the loop. */ + int info_ptr_updated = 0; + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); - /* Anonymous namespaces have no name but are interesting. */ + /* Anonymous namespaces have no name but have interesting + children, so we need to look at them. Ditto for anonymous + enums. */ - if (pdi.name != NULL || pdi.tag == DW_TAG_namespace) + if (pdi.name != NULL || pdi.tag == DW_TAG_namespace + || pdi.tag == DW_TAG_enumeration_type) { switch (pdi.tag) { @@ -1405,8 +1419,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, { *highpc = pdi.highpc; } - if ((pdi.is_external || nesting_level == file_scope_level) - && !pdi.is_declaration) + if (!pdi.is_declaration) { add_partial_symbol (&pdi, objfile, cu_header); } @@ -1414,76 +1427,52 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, break; case DW_TAG_variable: case DW_TAG_typedef: + case DW_TAG_union_type: case DW_TAG_class_type: case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - if ((pdi.is_external || nesting_level == file_scope_level) - && !pdi.is_declaration) + if (!pdi.is_declaration) { add_partial_symbol (&pdi, objfile, cu_header); } break; - case DW_TAG_enumerator: - /* File scope enumerators are added to the partial - symbol table. They're children of the enumeration - type die, so they occur at a level one higher than we - normally look for. */ - if (nesting_level == file_scope_level + 1) - add_partial_symbol (&pdi, objfile, cu_header); + case DW_TAG_enumeration_type: + if (!pdi.is_declaration) + { + info_ptr = add_partial_enumeration (&pdi, info_ptr, + objfile, cu_header); + info_ptr_updated = 1; + } break; case DW_TAG_base_type: /* File scope base type definitions are added to the partial symbol table. */ - if (nesting_level == file_scope_level) - add_partial_symbol (&pdi, objfile, cu_header); + add_partial_symbol (&pdi, objfile, cu_header); break; case DW_TAG_namespace: - /* FIXME: carlton/2002-10-16: we're not yet doing - anything useful with this, but for now make sure that - these tags at least don't cause us to miss any - important symbols. */ - if (pdi.has_children) - file_scope_level++; + info_ptr = add_partial_namespace (&pdi, info_ptr, objfile, + lowpc, highpc, cu_header); + info_ptr_updated = 1; + break; default: break; } } - /* If the die has a sibling, skip to the sibling. Do not skip - enumeration types, we want to record their enumerators. Do - not skip namespaces, we want to record symbols inside - them. */ - if (pdi.sibling - && pdi.tag != DW_TAG_enumeration_type - && pdi.tag != DW_TAG_namespace) - { - info_ptr = pdi.sibling; - } - else if (pdi.has_children) - { - /* Die has children, but either the optional DW_AT_sibling - attribute is missing or we want to look at them. */ - nesting_level++; - } - if (pdi.tag == 0) - { - nesting_level--; - /* If this is the end of a DW_TAG_namespace entry, then - decrease the file_scope_level, too. */ - if (nesting_level < file_scope_level) - { - file_scope_level--; - gdb_assert (nesting_level == file_scope_level); - } - } + break; + + /* If the die has a sibling, skip to the sibling, unless another + function has already updated info_ptr for us. */ + + /* NOTE: carlton/2003-06-16: This is a bit hackish, but whether + or not we want to update this depends on enough stuff (not + only pdi.tag but also whether or not pdi.name is NULL) that + this seems like the easiest way to handle the issue. */ + + if (!info_ptr_updated) + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header); } - /* If we didn't find a lowpc, set it to highpc to avoid complaints - from `maint check'. */ - if (*lowpc == ((CORE_ADDR) -1)) - *lowpc = *highpc; return info_ptr; } @@ -1593,6 +1582,85 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, } } +/* Read a partial die corresponding to a namespace. For now, we don't + do anything with the fact that we're in a namespace; we just read + the symbols inside of it. */ + +static char * +add_partial_namespace (struct partial_die_info *pdi, char *info_ptr, + struct objfile *objfile, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + const struct comp_unit_head *cu_header) +{ + if (pdi->has_children) + info_ptr = scan_partial_symbols (info_ptr, objfile, + lowpc, highpc, + cu_header); + + return info_ptr; +} + +/* Read a partial die corresponding to an enumeration type. */ + +static char * +add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr, + struct objfile *objfile, + const struct comp_unit_head *cu_header) +{ + bfd *abfd = objfile->obfd; + struct partial_die_info pdi; + + if (enum_pdi->name != NULL) + add_partial_symbol (enum_pdi, objfile, cu_header); + + while (1) + { + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + if (pdi.tag == 0) + break; + if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL) + complaint (&symfile_complaints, "malformed enumerator DIE ignored"); + else + add_partial_symbol (&pdi, objfile, cu_header); + } + + return info_ptr; +} + +/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE + after ORIG_PDI. */ + +static char * +locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr, + bfd *abfd, const struct comp_unit_head *cu_header) +{ + /* Do we know the sibling already? */ + + if (orig_pdi->sibling) + return orig_pdi->sibling; + + /* Are there any children to deal with? */ + + if (!orig_pdi->has_children) + return info_ptr; + + /* Okay, we don't know the sibling, but we have children that we + want to skip. So read children until we run into one without a + tag; return whatever follows it. */ + + while (1) + { + struct partial_die_info pdi; + + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + + if (pdi.tag == 0) + return info_ptr; + else + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header); + } +} + /* Expand this partial symbol table into a full symbol table. */ static void |