scan_for_anonymous_namespaces (struct symbol *symbol)
{
const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
- const char *beginning, *end;
+ const char *beginning = name;
+ const char *end = cp_find_first_component (beginning);
- for (beginning = name, end = cp_find_first_component (name);
- *end == ':';
- /* The "+ 2" is for the "::"-. */
- beginning = end + 2, end = cp_find_first_component (beginning))
+ while (*end == ':')
{
if ((end - beginning) == ANONYMOUS_NAMESPACE_LEN
&& strncmp (beginning, "(anonymous namespace)",
ANONYMOUS_NAMESPACE_LEN) == 0)
- /* We've found a component of the name that's an anonymous
- namespace. So add symbols in it to the namespace given by
- the previous component if there is one, or to the global
- namespace if there isn't. */
- add_using_directive (name,
- beginning == name ? 0 : beginning - name - 2,
- end - name);
+ {
+ /* We've found a component of the name that's an anonymous
+ namespace. So add symbols in it to the namespace given
+ by the previous component if there is one, or to the
+ global namespace if there isn't. */
+ add_using_directive (name,
+ beginning == name ? 0 : beginning - name - 2,
+ end - name);
+ }
+ /* The "+ 2" is for the "::". */
+ beginning = end + 2;
+ end = cp_find_first_component (beginning);
}
}
/* FIXME: carlton/2002-11-14: For members of classes,
with this include the class name as well? I don't
think that's a problem yet, but it will be. */
-
- for (current = name, next = cp_find_first_component (current);
- *next == ':';
- /* The '+ 2' is to skip the '::'. */
- current = next,
- next = cp_find_first_component (current + 2))
- ;
+
+ current = name;
+ next = cp_find_first_component (current);
+ while (*next == ':')
+ {
+ current = next;
+ /* The '+ 2' is to skip the '::'. */
+ next = cp_find_first_component (current + 2);
+ }
if (current == name)
block_set_scope (block, "", &objfile->symbol_obstack);
else
#include "gdb_string.h"
#include "gdb_assert.h"
#include <sys/types.h>
+#include "cp-support.h"
#ifndef DWARF2_REG_TO_REGNUM
#define DWARF2_REG_TO_REGNUM(REG) (REG)
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 *);
+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 char *namespace);
+
static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
static void psymtab_to_symtab_1 (struct partial_symtab *);
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'. */
}
/* 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;
{
info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
- if (pdi.name)
+ /* Anonymous namespaces have no name but are interesting. */
+
+ if (pdi.name != NULL || pdi.tag == DW_TAG_namespace)
{
switch (pdi.tag)
{
add_partial_symbol (&pdi, objfile, cu_header);
break;
case DW_TAG_namespace:
- if (pdi.has_children)
- info_ptr = scan_partial_symbols (info_ptr, objfile,
- lowpc, highpc,
- cu_header);
+ /* 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,
+ namespace);
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, the scan_partial_symbols call has
+ not skip namespaces, the add_partial_namespace call has
already updated info_ptr for us. */
if (pdi.sibling
&& pdi.tag != DW_TAG_enumeration_type
{
info_ptr = pdi.sibling;
}
- else if (pdi.has_children)
+ else if (pdi.has_children && pdi.tag != DW_TAG_namespace)
{
/* Die has children, but either the optional DW_AT_sibling
attribute is missing or we want to look at them. */
}
}
+/* 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 char *namespace)
+{
+ /* Calculate the full name of the namespace that we just entered. */
+
+ const char *new_name = pdi->name;
+ if (new_name == NULL)
+ new_name = "(anonymous namespace)";
+ char *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);
+
+ /* Make sure that there's a symbol associated to that namespace. */
+
+ cp_check_namespace_symbol (full_name, strlen (full_name));
+
+ /* Now scan partial symbols in that namespace. */
+
+ if (pdi->has_children)
+ info_ptr = scan_partial_symbols (info_ptr, objfile,
+ lowpc, highpc,
+ cu_header, full_name);
+
+ return info_ptr;
+}
+
+
/* Expand this partial symbol table into a full symbol table. */
static void