aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c172
1 files changed, 128 insertions, 44 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 18b67a6..b432f12 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -672,21 +672,25 @@ static void dwarf2_build_psymtabs_hard (struct objfile *, int);
static char *scan_partial_symbols (char *, struct objfile *,
CORE_ADDR *, CORE_ADDR *,
- const struct comp_unit_head *);
+ const struct comp_unit_head *,
+ const char *namespace);
static void add_partial_symbol (struct partial_die_info *, struct objfile *,
- const struct comp_unit_head *);
+ const struct comp_unit_head *,
+ const char *namespace);
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);
+ const struct comp_unit_head *cu_header,
+ const char *namespace);
static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
char *info_ptr,
struct objfile *objfile,
- const struct comp_unit_head *cu_header);
+ const struct comp_unit_head *cu_header,
+ const char *namespace);
static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
char *info_ptr,
@@ -1341,7 +1345,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
highpc = ((CORE_ADDR) 0);
info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
- &cu_header);
+ &cu_header, NULL);
/* If we didn't find a lowpc, set it to highpc to avoid
complaints from `maint check'. */
@@ -1377,12 +1381,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
}
/* Read in all interesting dies to the end of the compilation unit or
- to the end of the current namespace. */
+ to the end of the current namespace. NAMESPACE is NULL if we
+ haven't yet encountered any DW_TAG_namespace entries; otherwise,
+ it's the name of the current namespace. In particular, it's the
+ empty string if we're currently in the global namespace but have
+ previously encountered a DW_TAG_namespace. */
static char *
scan_partial_symbols (char *info_ptr, struct objfile *objfile,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
- const struct comp_unit_head *cu_header)
+ const struct comp_unit_head *cu_header,
+ const char *namespace)
{
bfd *abfd = objfile->obfd;
struct partial_die_info pdi;
@@ -1421,7 +1430,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
}
if (!pdi.is_declaration)
{
- add_partial_symbol (&pdi, objfile, cu_header);
+ add_partial_symbol (&pdi, objfile, cu_header, namespace);
}
}
break;
@@ -1432,25 +1441,32 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
case DW_TAG_structure_type:
if (!pdi.is_declaration)
{
- add_partial_symbol (&pdi, objfile, cu_header);
+ add_partial_symbol (&pdi, objfile, cu_header, namespace);
}
break;
case DW_TAG_enumeration_type:
if (!pdi.is_declaration)
{
info_ptr = add_partial_enumeration (&pdi, info_ptr,
- objfile, cu_header);
+ objfile, cu_header,
+ namespace);
info_ptr_updated = 1;
}
break;
case DW_TAG_base_type:
/* File scope base type definitions are added to the partial
symbol table. */
- add_partial_symbol (&pdi, objfile, cu_header);
+ add_partial_symbol (&pdi, objfile, cu_header, namespace);
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 = "";
info_ptr = add_partial_namespace (&pdi, info_ptr, objfile,
- lowpc, highpc, cu_header);
+ lowpc, highpc, cu_header,
+ namespace);
info_ptr_updated = 1;
break;
default:
@@ -1478,9 +1494,11 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
static void
add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
- const struct comp_unit_head *cu_header)
+ const struct comp_unit_head *cu_header,
+ const char *namespace)
{
CORE_ADDR addr = 0;
+ const struct partial_symbol *psym = NULL;
switch (pdi->tag)
{
@@ -1489,19 +1507,21 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
{
/*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
mst_text, objfile); */
- add_psymbol_to_list (pdi->name, strlen (pdi->name),
- VAR_DOMAIN, LOC_BLOCK,
- &objfile->global_psymbols,
- 0, pdi->lowpc + baseaddr, cu_language, objfile);
+ psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_DOMAIN, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, pdi->lowpc + baseaddr,
+ cu_language, objfile);
}
else
{
/*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
mst_file_text, objfile); */
- add_psymbol_to_list (pdi->name, strlen (pdi->name),
- VAR_DOMAIN, LOC_BLOCK,
- &objfile->static_psymbols,
- 0, pdi->lowpc + baseaddr, cu_language, objfile);
+ psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_DOMAIN, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, pdi->lowpc + baseaddr,
+ cu_language, objfile);
}
break;
case DW_TAG_variable:
@@ -1523,10 +1543,11 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
if (pdi->locdesc)
addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
if (pdi->locdesc || pdi->has_type)
- add_psymbol_to_list (pdi->name, strlen (pdi->name),
- VAR_DOMAIN, LOC_STATIC,
- &objfile->global_psymbols,
- 0, addr + baseaddr, cu_language, objfile);
+ psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_DOMAIN, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, addr + baseaddr,
+ cu_language, objfile);
}
else
{
@@ -1536,10 +1557,11 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
/*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
mst_file_data, objfile); */
- add_psymbol_to_list (pdi->name, strlen (pdi->name),
- VAR_DOMAIN, LOC_STATIC,
- &objfile->static_psymbols,
- 0, addr + baseaddr, cu_language, objfile);
+ psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
+ VAR_DOMAIN, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, addr + baseaddr,
+ cu_language, objfile);
}
break;
case DW_TAG_typedef:
@@ -1580,22 +1602,60 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
default:
break;
}
+
+ /* Check to see if we should scan the name for possible namespace
+ info. Only do this if this is C++, if we don't have namespace
+ debugging info in the file, if the psym is of an appropriate type
+ (otherwise we'll have psym == NULL), and if we actually had a
+ mangled name to begin with. */
+
+ if (cu_language == language_cplus
+ && namespace == NULL
+ && psym != NULL
+ && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
+ cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
+ 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. */
+/* Read a partial die corresponding to a namespace; also, add a symbol
+ corresponding to that namespace to the symbol table. NAMESPACE is
+ the name of the enclosing namespace. */
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)
+ const struct comp_unit_head *cu_header,
+ const char *namespace)
{
+ /* Calculate the full name of the namespace that we just entered. */
+
+ const char *new_name = pdi->name;
+ char *full_name;
+
+ 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-06-27: Once we build qualified names for more
+ symbols than just namespaces, we should replace this by a call to
+ add_partial_symbol. */
+
+ add_psymbol_to_list (full_name, strlen (full_name),
+ VAR_DOMAIN, LOC_TYPEDEF,
+ &objfile->global_psymbols,
+ 0, 0, cu_language, objfile);
+
+ /* Now scan partial symbols in that namespace. */
+
if (pdi->has_children)
info_ptr = scan_partial_symbols (info_ptr, objfile,
lowpc, highpc,
- cu_header);
+ cu_header, full_name);
return info_ptr;
}
@@ -1605,13 +1665,14 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
static char *
add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
struct objfile *objfile,
- const struct comp_unit_head *cu_header)
+ const struct comp_unit_head *cu_header,
+ const char *namespace)
{
bfd *abfd = objfile->obfd;
struct partial_die_info pdi;
if (enum_pdi->name != NULL)
- add_partial_symbol (enum_pdi, objfile, cu_header);
+ add_partial_symbol (enum_pdi, objfile, cu_header, namespace);
while (1)
{
@@ -1621,7 +1682,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL)
complaint (&symfile_complaints, "malformed enumerator DIE ignored");
else
- add_partial_symbol (&pdi, objfile, cu_header);
+ add_partial_symbol (&pdi, objfile, cu_header, namespace);
}
return info_ptr;
@@ -3314,13 +3375,28 @@ read_namespace (struct die_info *die, struct objfile *objfile,
processing_current_namespace = temp_name;
}
- /* If it's an anonymous namespace that we're seeing for the first
- time, add a using directive. */
+ /* Add a symbol associated to this if we haven't seen the namespace
+ before. Also, add a using directive if it's an anonymous
+ namespace. */
- if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
- cp_add_using_directive (processing_current_namespace,
- strlen (previous_namespace),
- strlen (processing_current_namespace));
+ if (dwarf2_extension (die) == NULL)
+ {
+ struct type *type;
+
+ /* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
+ this cast will hopefully become unnecessary. */
+ type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
+ (char *) processing_current_namespace,
+ objfile);
+ TYPE_TAG_NAME (type) = TYPE_NAME (type);
+
+ new_symbol (die, type, objfile, cu_header);
+
+ if (is_anonymous)
+ cp_add_using_directive (processing_current_namespace,
+ strlen (previous_namespace),
+ strlen (processing_current_namespace));
+ }
if (die->has_children)
{
@@ -5175,7 +5251,11 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
struct attribute *attr2 = NULL;
CORE_ADDR addr = 0;
- name = dwarf2_linkage_name (die);
+ if (die->tag != DW_TAG_namespace)
+ name = dwarf2_linkage_name (die);
+ else
+ name = TYPE_NAME (type);
+
if (name)
{
sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
@@ -5332,6 +5412,10 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
}
add_symbol_to_list (sym, list_in_scope);
break;
+ case DW_TAG_namespace:
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ add_symbol_to_list (sym, &global_symbols);
+ break;
default:
/* Not a tag we recognize. Hopefully we aren't processing
trash data, but since we must specifically ignore things