diff options
author | Daniel Jacobowitz <dan@debian.org> | 2004-02-22 06:11:54 +0000 |
---|---|---|
committer | Daniel Jacobowitz <dan@debian.org> | 2004-02-22 06:11:54 +0000 |
commit | 63554b6046e6efa385aec2dd37d60c88f1436c25 (patch) | |
tree | 061a08287be86ef1460847822778769cd6442ea0 | |
parent | e8a0fc5ec49a6c4fe71f5c9fc7337ef8023ff899 (diff) | |
download | gdb-63554b6046e6efa385aec2dd37d60c88f1436c25.tar.gz |
* dwarf2read.c (struct partial_die_info): Add full_name.
(scan_partial_symbols, add_partial_symbol, add_partial_structure)
(add_partial_enumeration): Change namespace argument to
have_namespace_info flag. Move DW_TAG_namespace handling to
add_partial_symbol. Update comments.
(pdi_needs_namespace): Remove namespace argument. Handle
DW_TAG_namespace.
(partial_determine_prefix, partial_determine_prefix_aux): Remove.
(dwarf2_build_psymtabs_hard): Update call to scan_partial_symbols.
(partial_die_full_name): New function.
(load_partial_die): Correct comment formatting. Don't handle
DW_TAG_enumeration_type.
(load_partial_dies): Correct comment formatting.
-rw-r--r-- | gdb/ChangeLog.intercu | 16 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 291 |
2 files changed, 138 insertions, 169 deletions
diff --git a/gdb/ChangeLog.intercu b/gdb/ChangeLog.intercu index 5e845658175..a7cd6a8706c 100644 --- a/gdb/ChangeLog.intercu +++ b/gdb/ChangeLog.intercu @@ -1,5 +1,21 @@ 2004-02-21 Daniel Jacobowitz <drow@mvista.com> + * dwarf2read.c (struct partial_die_info): Add full_name. + (scan_partial_symbols, add_partial_symbol, add_partial_structure) + (add_partial_enumeration): Change namespace argument to + have_namespace_info flag. Move DW_TAG_namespace handling to + add_partial_symbol. Update comments. + (pdi_needs_namespace): Remove namespace argument. Handle + DW_TAG_namespace. + (partial_determine_prefix, partial_determine_prefix_aux): Remove. + (dwarf2_build_psymtabs_hard): Update call to scan_partial_symbols. + (partial_die_full_name): New function. + (load_partial_die): Correct comment formatting. Don't handle + DW_TAG_enumeration_type. + (load_partial_dies): Correct comment formatting. + +2004-02-21 Daniel Jacobowitz <drow@mvista.com> + * dwarf2read.c (load_partial_dies): Check for NULL name before adding types. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f0421a5eca8..a1e4582a4dc 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -404,6 +404,7 @@ struct partial_die_info unsigned int has_specification : 1; unsigned int has_pc_info : 1; char *name; + char *full_name; struct dwarf_block *locdesc; CORE_ADDR lowpc; CORE_ADDR highpc; @@ -647,26 +648,24 @@ static void dwarf2_build_psymtabs_hard (struct objfile *, int); static void scan_partial_symbols (struct partial_die_info *, CORE_ADDR *, CORE_ADDR *, - struct dwarf2_cu *, - const char *namespace); + struct dwarf2_cu *, int); static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *, - const char *namespace); + int have_namespace_info); -static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace); +static int pdi_needs_namespace (enum dwarf_tag tag); static void add_partial_namespace (struct partial_die_info *pdi, CORE_ADDR *lowpc, CORE_ADDR *highpc, - struct dwarf2_cu *cu, - const char *namespace); + struct dwarf2_cu *cu); static void add_partial_structure (struct partial_die_info *struct_pdi, struct dwarf2_cu *cu, - const char *namespace); + int have_namespace_info); static void add_partial_enumeration (struct partial_die_info *enum_pdi, struct dwarf2_cu *cu, - const char *namespace); + int have_namespace_info); static char *locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr, @@ -790,10 +789,6 @@ static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *); -static char *partial_determine_prefix (struct partial_die_info *die, struct dwarf2_cu *); - -static char *partial_determine_prefix_aux (struct partial_die_info *die, struct dwarf2_cu *); - static char *typename_concat (const char *prefix, const char *suffix); static char *class_name (struct die_info *die, struct dwarf2_cu *); @@ -1370,7 +1365,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) first_die = load_partial_dies (abfd, info_ptr, &cu); - scan_partial_symbols (first_die, &lowpc, &highpc, &cu, NULL); + scan_partial_symbols (first_die, &lowpc, &highpc, &cu, 0); cu.partial_dies = NULL; obstack_free (&cu.partial_die_obstack, NULL); @@ -1420,7 +1415,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) static void scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, CORE_ADDR *highpc, struct dwarf2_cu *cu, - const char *namespace) + int have_namespace_info) { struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; @@ -1458,7 +1453,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, } if (!pdi_p->is_declaration) { - add_partial_symbol (pdi_p, cu, namespace); + add_partial_symbol (pdi_p, cu, have_namespace_info); } } break; @@ -1467,89 +1462,112 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, case DW_TAG_union_type: if (!pdi_p->is_declaration) { - add_partial_symbol (pdi_p, cu, namespace); + add_partial_symbol (pdi_p, cu, have_namespace_info); } break; case DW_TAG_class_type: case DW_TAG_structure_type: if (!pdi_p->is_declaration) { - add_partial_structure (pdi_p, cu, namespace); + add_partial_structure (pdi_p, cu, have_namespace_info); } break; case DW_TAG_enumeration_type: if (!pdi_p->is_declaration) - add_partial_enumeration (pdi_p, cu, namespace); + add_partial_enumeration (pdi_p, cu, have_namespace_info); break; case DW_TAG_base_type: case DW_TAG_subrange_type: /* File scope base type definitions are added to the partial symbol table. */ - add_partial_symbol (pdi_p, cu, namespace); + add_partial_symbol (pdi_p, cu, have_namespace_info); break; case DW_TAG_namespace: /* We've hit a DW_TAG_namespace entry, so we know this file has been compiled using a compiler that generates them; update NAMESPACE to reflect that. */ - if (namespace == NULL) - namespace = ""; - add_partial_namespace (pdi_p, lowpc, highpc, cu, namespace); + have_namespace_info = 1; + add_partial_namespace (pdi_p, lowpc, highpc, cu); break; default: break; } } - /* FIXME unnecessary now */ - if (pdi_p->tag == 0) - 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_p->tag but also whether or not pdi_p->name is NULL) that - this seems like the easiest way to handle the issue. */ + /* If the die has a sibling, skip to the sibling. */ pdi_p = pdi_p->die_sibling; - // if (pdi_p) - // fprintf_unfiltered (gdb_stderr, "scan: Advancing to DIE %x\n", pdi_p->offset); } } +static char * +partial_die_full_name (struct partial_die_info *pdi, int allocate, + struct dwarf2_cu *cu) +{ + char *full_name, *parent_name; + struct partial_die_info *real_parent; + + /* Note: this code could be micro-optimized. We could avoid redoing + the hash table lookup, which we've probably already done once, + and we might be able to use real_pdi->full_name if there is a + specification. */ + + if (pdi->has_specification) + real_parent = find_partial_die (pdi->spec_offset, cu)->die_parent; + else + real_parent = pdi->die_parent; + + if (real_parent == NULL) + return NULL; + + parent_name = real_parent->full_name; + if (parent_name == NULL) + parent_name = real_parent->name; + + if (allocate) + full_name = obconcat (&cu->partial_die_obstack, + parent_name, "::", pdi->name); + else + full_name = concat (parent_name, "::", pdi->name, NULL); + + return full_name; +} + static void add_partial_symbol (struct partial_die_info *pdi, - struct dwarf2_cu *cu, const char *namespace) + struct dwarf2_cu *cu, int have_namespace_info) { struct objfile *objfile = cu->objfile; CORE_ADDR addr = 0; - char *actual_name = pdi->name; + char *actual_name; const char *my_prefix; const struct partial_symbol *psym = NULL; CORE_ADDR baseaddr; + int free_actual_name = 0; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - /* If we're not in the global namespace and if the namespace name - isn't encoded in a mangled actual_name, add it. */ - - if (pdi->spec_offset - && pdi_needs_namespace (pdi->tag, "foo")) - my_prefix = partial_determine_prefix (pdi, cu); - else - my_prefix = namespace; - - if (pdi_needs_namespace (pdi->tag, my_prefix)) + if (pdi_needs_namespace (pdi->tag) && pdi->full_name == NULL) { - actual_name = alloca (strlen (pdi->name) + 2 + strlen (my_prefix) + 1); - strcpy (actual_name, my_prefix); - strcat (actual_name, "::"); - strcat (actual_name, pdi->name); + if (pdi->tag == DW_TAG_namespace + || pdi->tag == DW_TAG_class_type + || pdi->tag == DW_TAG_structure_type + || pdi->tag == DW_TAG_union_type) + { + pdi->full_name = partial_die_full_name (pdi, 1, cu); + actual_name = pdi->full_name; + } + else + { + actual_name = partial_die_full_name (pdi, 0, cu); + if (actual_name) + free_actual_name = 1; + } + if (actual_name == NULL) + actual_name = pdi->name; } - - if (my_prefix) - free ((char *) my_prefix); + else + actual_name = pdi->name; switch (pdi->tag) { @@ -1623,6 +1641,12 @@ add_partial_symbol (struct partial_die_info *pdi, &objfile->static_psymbols, 0, (CORE_ADDR) 0, cu->language, objfile); break; + case DW_TAG_namespace: + add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->global_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + break; case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: @@ -1668,25 +1692,26 @@ add_partial_symbol (struct partial_die_info *pdi, mangled name to begin with. */ if (cu->language == language_cplus - && namespace == NULL + && have_namespace_info == 0 && psym != NULL && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym), objfile); + + if (free_actual_name) + xfree (actual_name); } -/* Determine whether a die of type TAG living in the C++ namespace - NAMESPACE needs to have the name of the namespace prepended to the +/* Determine whether a die of type TAG living in a C++ class or + namespace needs to have the name of the scope prepended to the name listed in the die. */ static int -pdi_needs_namespace (enum dwarf_tag tag, const char *namespace) +pdi_needs_namespace (enum dwarf_tag tag) { - if (namespace == NULL || namespace[0] == '\0') - return 0; - switch (tag) { + case DW_TAG_namespace: case DW_TAG_typedef: case DW_TAG_class_type: case DW_TAG_structure_type: @@ -1706,37 +1731,23 @@ pdi_needs_namespace (enum dwarf_tag tag, const char *namespace) static void add_partial_namespace (struct partial_die_info *pdi, CORE_ADDR *lowpc, CORE_ADDR *highpc, - struct dwarf2_cu *cu, const char *namespace) + struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; - const char *new_name = pdi->name; char *full_name; /* Calculate the full name of the namespace that we just entered. */ - if (new_name == NULL) - new_name = "(anonymous namespace)"; - full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1); - strcpy (full_name, namespace); - if (*namespace != '\0') - strcat (full_name, "::"); - strcat (full_name, new_name); - - /* FIXME: carlton/2003-10-07: We can't just replace this by a call - to add_partial_symbol, because we don't have a way to pass in the - full name to that function; that might be a flaw in - add_partial_symbol's interface. */ + if (pdi->name == NULL) + pdi->name = "(anonymous namespace)"; - add_psymbol_to_list (full_name, strlen (full_name), - VAR_DOMAIN, LOC_TYPEDEF, - &objfile->global_psymbols, - 0, 0, cu->language, objfile); + add_partial_symbol (pdi, cu, 1); /* Now scan partial symbols in that namespace. */ if (pdi->has_children) scan_partial_symbols (pdi->die_child, - lowpc, highpc, cu, full_name); + lowpc, highpc, cu, 1); } /* Read a partial die corresponding to a class or structure. */ @@ -1744,14 +1755,16 @@ add_partial_namespace (struct partial_die_info *pdi, static void add_partial_structure (struct partial_die_info *struct_pdi, struct dwarf2_cu *cu, - const char *namespace) + int have_namespace_info) { bfd *abfd = cu->objfile->obfd; - char *actual_class_name = NULL; + char *full_name; + + if (struct_pdi->name == NULL) + struct_pdi->name = "(anonymous class)"; if (cu->language == language_cplus - && namespace == NULL - && struct_pdi->name != NULL + && have_namespace_info == 0 && struct_pdi->has_children) { /* See if we can figure out if the class lives in a namespace @@ -1771,9 +1784,16 @@ add_partial_structure (struct partial_die_info *struct_pdi, { if (child_pdi->tag == DW_TAG_subprogram) { - actual_class_name = class_name_from_physname (child_pdi->name); + char *actual_class_name + = class_name_from_physname (child_pdi->name); if (actual_class_name != NULL) - struct_pdi->name = actual_class_name; + { + struct_pdi->full_name + = obsavestring (actual_class_name, + strlen (actual_class_name), + &cu->partial_die_obstack); + xfree (actual_class_name); + } break; } @@ -1781,22 +1801,21 @@ add_partial_structure (struct partial_die_info *struct_pdi, } } - add_partial_symbol (struct_pdi, cu, namespace); - xfree (actual_class_name); + add_partial_symbol (struct_pdi, cu, have_namespace_info); } /* Read a partial die corresponding to an enumeration type. */ static void add_partial_enumeration (struct partial_die_info *enum_pdi, - struct dwarf2_cu *cu, const char *namespace) + struct dwarf2_cu *cu, int have_namespace_info) { struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; struct partial_die_info *pdi_p; if (enum_pdi->name != NULL) - add_partial_symbol (enum_pdi, cu, namespace); + add_partial_symbol (enum_pdi, cu, have_namespace_info); pdi_p = enum_pdi->die_child; while (pdi_p) @@ -1804,7 +1823,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, if (pdi_p->tag != DW_TAG_enumerator || pdi_p->name == NULL) complaint (&symfile_complaints, "malformed enumerator DIE ignored"); else - add_partial_symbol (pdi_p, cu, namespace); + add_partial_symbol (pdi_p, cu, have_namespace_info); pdi_p = pdi_p->die_sibling; } } @@ -4548,18 +4567,18 @@ load_partial_dies (bfd *abfd, char *info_ptr, struct dwarf2_cu *cu) info_ptr = load_partial_die (part_die, abbrev, bytes_read, abfd, info_ptr, cu); - /* This two-pass algorithm for processing partial symbols has a high - cost in cache pressure. Thus, handle some trivial cases here - which cover the majority of C partial symbols. DIEs which - neither have specification tags in them, nor could have specification - tags elsewhere pointing at them, can simply be processed and - discarded. + /* This two-pass algorithm for processing partial symbols has a + high cost in cache pressure. Thus, handle some simple cases + here which cover the majority of C partial symbols. DIEs + which neither have specification tags in them, nor could have + specification tags elsewhere pointing at them, can simply be + processed and discarded. This segment is also optional; scan_partial_symbols and add_partial_symbol will handle these DIEs if we simply chain them in normally. When compilers which do not emit large - quantities of duplicate debug information are more common, - this code can probably be removed. */ + quantities of duplicate debug information are more common, + this code can probably be removed. */ /* Any complete simple types at the top level (pretty much all of them, for a language without namespaces), can be processed @@ -4569,8 +4588,7 @@ load_partial_dies (bfd *abfd, char *info_ptr, struct dwarf2_cu *cu) && part_die->is_declaration == 0 && (part_die->tag == DW_TAG_typedef || part_die->tag == DW_TAG_base_type - || part_die->tag == DW_TAG_subrange_type - || part_die->tag == DW_TAG_enumeration_type)) + || part_die->tag == DW_TAG_subrange_type)) { if (part_die->name != NULL) add_psymbol_to_list (part_die->name, strlen (part_die->name), @@ -4620,11 +4638,10 @@ load_partial_dies (bfd *abfd, char *info_ptr, struct dwarf2_cu *cu) if (first_die == NULL) first_die = part_die; - /* Maybe add the DIE to the hash table. Not all DIEs need that - we find interesting need to be in the hash table, because we + /* Maybe add the DIE to the hash table. Not all DIEs that we + find interesting need to be in the hash table, because we also have the parent/sibling/child chains; only those that we - might refer to by offset later during partial symbol - reading. + might refer to by offset later during partial symbol reading. For now this means things that might have be the target of a DW_AT_specification, DW_AT_abstract_origin, or @@ -6568,70 +6585,6 @@ determine_prefix_aux (struct die_info *die, struct dwarf2_cu *cu) } } -/* Likewise for partial DIEs. */ - -static char * -partial_determine_prefix (struct partial_die_info *die, struct dwarf2_cu *cu) -{ - char *prefix = partial_determine_prefix_aux (die, cu); - - return prefix ? prefix : xstrdup (""); -} - -/* Return the name of the namespace/class that DIE is defined - within, or NULL if we can't tell. The caller should xfree the - result. */ - -static char * -partial_determine_prefix_aux (struct partial_die_info *die, struct dwarf2_cu *cu) -{ - struct partial_die_info *parent; - - if (cu->language != language_cplus) - return NULL; - - if (die->spec_offset) - die = find_partial_die (die->spec_offset, cu); - - parent = die->die_parent; - - if (parent == NULL) - { - return (processing_has_namespace_info ? xstrdup ("") : NULL); - } - else - { - char *parent_prefix = partial_determine_prefix_aux (parent, cu); - char *retval; - - fixup_partial_die (parent, cu); - - switch (parent->tag) { - case DW_TAG_namespace: - if (parent->name != NULL) - retval = typename_concat (parent_prefix, parent->name); - else - retval = typename_concat (parent_prefix, "(anonymous namespace)"); - break; - case DW_TAG_class_type: - case DW_TAG_structure_type: - if (parent->name != NULL) - retval = typename_concat (parent_prefix, parent->name); - else - retval = typename_concat (parent_prefix, - "<<anonymous class>>"); - break; - default: - retval = parent_prefix; - break; - } - - if (retval != parent_prefix) - xfree (parent_prefix); - return retval; - } -} - /* Return a newly-allocated string formed by concatenating PREFIX, "::", and SUFFIX, except that if PREFIX is NULL or the empty string, just return a copy of SUFFIX. */ |