2004-01-14 David Carlton <carlton@kealia.com>

Change symbols for C++ nested types to contain the fully qualified
	name, if possible.  (At least in the DWARF-2 case.)  Partial fix
	for PR's c++/57, c++/488, c++/539, c++/573, c++/609, c++/832,
	c++/895.
	* c-exp.y: Update copyright:
	(qualified_type): Handle types nested within classes.
	* cp-namespace.c: Update comments.
	(cp_set_block_scope): Delete #if 0.
	(cp_lookup_nested_type): Handle types nested within classes.
	* dwarf2read.c: (scan_partial_symbols): Call add_partial_structure
	when appropriate.
	(add_partial_symbol): Add the name of the enclosing namespace to
	types.
	(pdi_needs_namespace): New.
	(add_partial_namespace): Tweak comment.
	(add_partial_structure): New.
	(psymtab_to_symtab_1): Initialize processing_current_prefix
	here...
	(process_die): instead of here.
	(read_structure_scope): Try to figure out the name of the class or
	namespace that the structure might be defined within.
	(read_enumeration): Generate fully-qualified names, if possible.
	(read_namespace): Don't set name to NULL.
	(die_specification): New.
	(new_symbol): Generate fully-qualified names for types.
	(read_type_die): Determine appropriate prefix.
	(determine_prefix): New.
	(typename_concat): New.
	(class_name): New.
	* valops.c: Update copyright.
	(value_aggregate_elt): Pass NOSIDE to
	value_struct_elt_for_reference.
	(value_struct_elt_for_reference): Make static, add NOSIDE
	parameter, call value_maybe_namespace_elt as a last resort.
	(value_namespace_elt): Break out code into
	value_maybe_namespace_elt.
	(value_maybe_namespace_elt): New.

2004-01-14  David Carlton  <carlton@kealia.com>

	* gdb.cp/namespace.exp: Add tests involving classes defined within
	namespaces.
	* gdb.cp/namespace.cc (C::CClass): New.
	* gdb.cp/namespace1.cc: Update copyright.
	(C::OtherFileClass): New.
This commit is contained in:
David Carlton
2004-01-14 16:54:43 +00:00
parent a51dab8874
commit 63d06c5c42
9 changed files with 605 additions and 94 deletions

View File

@@ -666,12 +666,19 @@ static char *scan_partial_symbols (char *, CORE_ADDR *, CORE_ADDR *,
static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *,
const char *namespace);
static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace);
static char *add_partial_namespace (struct partial_die_info *pdi,
char *info_ptr,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
struct dwarf2_cu *cu,
const char *namespace);
static char *add_partial_structure (struct partial_die_info *struct_pdi,
char *info_ptr,
struct dwarf2_cu *cu,
const char *namespace);
static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
char *info_ptr,
struct dwarf2_cu *cu,
@@ -743,6 +750,8 @@ static struct attribute *dwarf_attr (struct die_info *, unsigned int);
static int die_is_declaration (struct die_info *);
static struct die_info *die_specification (struct die_info *die);
static void free_line_header (struct line_header *lh);
static struct line_header *(dwarf_decode_line_header
@@ -777,6 +786,12 @@ static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
static void read_type_die (struct die_info *, struct dwarf2_cu *);
static char *determine_prefix (struct die_info *die);
static char *typename_concat (const char *prefix, const char *suffix);
static char *class_name (struct die_info *die);
static void read_typedef (struct die_info *, struct dwarf2_cu *);
static void read_base_type (struct die_info *, struct dwarf2_cu *);
@@ -1368,11 +1383,18 @@ scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc,
case DW_TAG_variable:
case DW_TAG_typedef:
case DW_TAG_union_type:
if (!pdi.is_declaration)
{
add_partial_symbol (&pdi, cu, namespace);
}
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
if (!pdi.is_declaration)
{
add_partial_symbol (&pdi, cu, namespace);
info_ptr = add_partial_structure (&pdi, info_ptr, cu,
namespace);
info_ptr_updated = 1;
}
break;
case DW_TAG_enumeration_type:
@@ -1430,6 +1452,17 @@ add_partial_symbol (struct partial_die_info *pdi,
char *actual_name = pdi->name;
const struct partial_symbol *psym = NULL;
/* 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_needs_namespace (pdi->tag, namespace))
{
actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1);
strcpy (actual_name, namespace);
strcat (actual_name, "::");
strcat (actual_name, pdi->name);
}
switch (pdi->tag)
{
case DW_TAG_subprogram:
@@ -1507,11 +1540,15 @@ add_partial_symbol (struct partial_die_info *pdi,
case DW_TAG_enumeration_type:
/* Skip aggregate types without children, these are external
references. */
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
if (pdi->has_children == 0)
return;
add_psymbol_to_list (actual_name, strlen (actual_name),
STRUCT_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
cu_language == language_cplus
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu_language, objfile);
if (cu_language == language_cplus)
@@ -1519,14 +1556,16 @@ add_partial_symbol (struct partial_die_info *pdi,
/* For C++, these implicitly act as typedefs as well. */
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
&objfile->global_psymbols,
0, (CORE_ADDR) 0, cu_language, objfile);
}
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_CONST,
&objfile->static_psymbols,
cu_language == language_cplus
? &objfile->static_psymbols
: &objfile->global_psymbols,
0, (CORE_ADDR) 0, cu_language, objfile);
break;
default:
@@ -1547,6 +1586,30 @@ add_partial_symbol (struct partial_die_info *pdi,
objfile);
}
/* Determine whether a die of type TAG living in the C++ namespace
NAMESPACE needs to have the name of the namespace prepended to the
name listed in the die. */
static int
pdi_needs_namespace (enum dwarf_tag tag, const char *namespace)
{
if (namespace == NULL || namespace[0] == '\0')
return 0;
switch (tag)
{
case DW_TAG_typedef:
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_enumeration_type:
case DW_TAG_enumerator:
return 1;
default:
return 0;
}
}
/* 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. */
@@ -1570,9 +1633,10 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
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. */
/* 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. */
add_psymbol_to_list (full_name, strlen (full_name),
VAR_DOMAIN, LOC_TYPEDEF,
@@ -1587,6 +1651,63 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
return info_ptr;
}
/* Read a partial die corresponding to a class or structure. */
static char *
add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
struct dwarf2_cu *cu,
const char *namespace)
{
bfd *abfd = cu->objfile->obfd;
char *actual_class_name = NULL;
if (cu_language == language_cplus
&& namespace == NULL
&& struct_pdi->name != NULL
&& struct_pdi->has_children)
{
/* We don't have namespace debugging information, so see if we
can figure out if this structure lives in a namespace. Look
for a member function; its demangled name will contain
namespace info, if there is any. */
/* NOTE: carlton/2003-10-07: Getting the info this way changes
what template types look like, because the demangler
frequently doesn't give the same name as the debug info. We
could fix this by only using the demangled name to get the
prefix (but see comment in read_structure_scope). */
char *next_child = info_ptr;
while (1)
{
struct partial_die_info child_pdi;
next_child = read_partial_die (&child_pdi, abfd, next_child,
cu);
if (!child_pdi.tag)
break;
if (child_pdi.tag == DW_TAG_subprogram)
{
actual_class_name = class_name_from_physname (child_pdi.name);
if (actual_class_name != NULL)
struct_pdi->name = actual_class_name;
break;
}
else
{
next_child = locate_pdi_sibling (&child_pdi, next_child,
abfd, cu);
}
}
}
add_partial_symbol (struct_pdi, cu, namespace);
xfree(actual_class_name);
return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
}
/* Read a partial die corresponding to an enumeration type. */
static char *
@@ -1711,6 +1832,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
cu_header_offset = offset;
info_ptr = dwarf_info_buffer + offset;
/* We're in the global namespace. */
processing_current_prefix = "";
obstack_init (&dwarf2_tmp_obstack);
back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -1864,11 +1988,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_common_inclusion:
break;
case DW_TAG_namespace:
if (!processing_has_namespace_info)
{
processing_has_namespace_info = 1;
processing_current_prefix = "";
}
processing_has_namespace_info = 1;
read_namespace (die, cu);
break;
case DW_TAG_imported_declaration:
@@ -1879,11 +1999,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
shouldn't in the C++ case, but conceivably could in the
Fortran case, so we'll have to replace this gdb_assert if
Fortran compilers start generating that info. */
if (!processing_has_namespace_info)
{
processing_has_namespace_info = 1;
processing_current_prefix = "";
}
processing_has_namespace_info = 1;
gdb_assert (die->child == NULL);
break;
default:
@@ -2777,6 +2893,13 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
const char *name = NULL;
const char *previous_prefix = processing_current_prefix;
struct cleanup *back_to = NULL;
/* This says whether or not we want to try to update the structure's
name to include enclosing namespace/class information, if
any. */
int need_to_update_name = 0;
type = alloc_type (objfile);
@@ -2784,9 +2907,41 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf_attr (die, DW_AT_name);
if (attr && DW_STRING (attr))
{
TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
strlen (DW_STRING (attr)),
&objfile->type_obstack);
name = DW_STRING (attr);
if (cu_language == language_cplus)
{
struct die_info *spec_die = die_specification (die);
if (spec_die != NULL)
{
char *specification_prefix = determine_prefix (spec_die);
processing_current_prefix = specification_prefix;
back_to = make_cleanup (xfree, specification_prefix);
}
}
if (processing_has_namespace_info)
{
/* FIXME: carlton/2003-11-10: This variable exists only for
const-correctness reasons. When I tried to change
TYPE_TAG_NAME to be a const char *, I ran into a cascade
of changes which would have forced decode_line_1 to take
a const char **. */
char *new_prefix = obconcat (&objfile->type_obstack,
processing_current_prefix,
processing_current_prefix[0] == '\0'
? "" : "::",
name);
TYPE_TAG_NAME (type) = new_prefix;
processing_current_prefix = new_prefix;
}
else
{
TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
&objfile->type_obstack);
need_to_update_name = (cu_language == language_cplus);
}
}
if (die->tag == DW_TAG_structure_type)
@@ -2846,6 +3001,41 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
/* C++ member function. */
process_die (child_die, cu);
dwarf2_add_member_fn (&fi, child_die, type, cu);
if (need_to_update_name)
{
/* The demangled names of member functions contain
information about enclosing namespaces/classes,
if any. */
/* FIXME: carlton/2003-11-10: The excessive
demangling here is a bit wasteful, as is the
memory usage for names. */
/* NOTE: carlton/2003-11-10: As commented in
add_partial_structure, the demangler sometimes
prints the type info in a different form from the
debug info. We could solve this by using the
demangled name to get the prefix; if doing so,
however, we'd need to be careful when reading a
class that's nested inside a template class.
That would also cause problems when trying to
determine RTTI information, since we use the
demangler to determine the appropriate class
name. */
char *actual_class_name
= class_name_from_physname (dwarf2_linkage_name
(child_die));
if (actual_class_name != NULL
&& strcmp (actual_class_name, name) != 0)
{
TYPE_TAG_NAME (type)
= obsavestring (actual_class_name,
strlen (actual_class_name),
&objfile->type_obstack);
}
xfree (actual_class_name);
need_to_update_name = 0;
}
}
else if (child_die->tag == DW_TAG_inheritance)
{
@@ -2921,6 +3111,10 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
/* No children, must be stub. */
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
}
processing_current_prefix = previous_prefix;
if (back_to != NULL)
do_cleanups (back_to);
}
/* Given a pointer to a die which begins an enumeration, process all
@@ -2950,9 +3144,21 @@ read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf_attr (die, DW_AT_name);
if (attr && DW_STRING (attr))
{
TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
strlen (DW_STRING (attr)),
&objfile->type_obstack);
const char *name = DW_STRING (attr);
if (processing_has_namespace_info)
{
TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
processing_current_prefix,
processing_current_prefix[0] == '\0'
? "" : "::",
name);
}
else
{
TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
&objfile->type_obstack);
}
}
attr = dwarf_attr (die, DW_AT_byte_size);
@@ -3223,7 +3429,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
const char *previous_prefix = processing_current_prefix;
const char *name = NULL;
const char *name;
int is_anonymous;
struct die_info *current_die;
@@ -4679,6 +4885,19 @@ die_is_declaration (struct die_info *die)
&& ! dwarf_attr (die, DW_AT_specification));
}
/* Return the die giving the specification for DIE, if there is
one. */
static struct die_info *
die_specification (struct die_info *die)
{
struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
if (spec_attr == NULL)
return NULL;
else
return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
}
/* Free the line_header structure *LH, and any arrays and strings it
refers to. */
@@ -5322,39 +5541,108 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
case DW_TAG_enumeration_type:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
add_symbol_to_list (sym, list_in_scope);
/* The semantics of C++ state that "struct foo { ... }" also
defines a typedef for "foo". Synthesize a typedef symbol so
that "ptype foo" works as expected. */
/* Make sure that the symbol includes appropriate enclosing
classes/namespaces in its name. These are calculated in
read_structure_scope, and the correct name is saved in
the type. */
if (cu_language == language_cplus)
{
struct symbol *typedef_sym = (struct symbol *)
obstack_alloc (&objfile->symbol_obstack,
sizeof (struct symbol));
*typedef_sym = *sym;
SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
TYPE_NAME (SYMBOL_TYPE (sym)) =
obsavestring (DEPRECATED_SYMBOL_NAME (sym),
strlen (DEPRECATED_SYMBOL_NAME (sym)),
&objfile->type_obstack);
add_symbol_to_list (typedef_sym, list_in_scope);
struct type *type = SYMBOL_TYPE (sym);
if (TYPE_TAG_NAME (type) != NULL)
{
/* FIXME: carlton/2003-11-10: Should this use
SYMBOL_SET_NAMES instead? (The same problem also
arises a further down in the function.) */
SYMBOL_LINKAGE_NAME (sym)
= obsavestring (TYPE_TAG_NAME (type),
strlen (TYPE_TAG_NAME (type)),
&objfile->symbol_obstack);
}
}
{
/* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
really ever be static objects: otherwise, if you try
to, say, break of a class's method and you're in a file
which doesn't mention that class, it won't work unless
the check for all static symbols in lookup_symbol_aux
saves you. See the OtherFileClass tests in
gdb.c++/namespace.exp. */
struct pending **list_to_add;
list_to_add = (list_in_scope == &file_symbols
&& cu_language == language_cplus
? &global_symbols : list_in_scope);
add_symbol_to_list (sym, list_to_add);
/* The semantics of C++ state that "struct foo { ... }" also
defines a typedef for "foo". Synthesize a typedef symbol so
that "ptype foo" works as expected. */
if (cu_language == language_cplus)
{
struct symbol *typedef_sym = (struct symbol *)
obstack_alloc (&objfile->symbol_obstack,
sizeof (struct symbol));
*typedef_sym = *sym;
SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
TYPE_NAME (SYMBOL_TYPE (sym)) =
obsavestring (SYMBOL_NATURAL_NAME (sym),
strlen (SYMBOL_NATURAL_NAME (sym)),
&objfile->type_obstack);
add_symbol_to_list (typedef_sym, list_to_add);
}
}
break;
case DW_TAG_typedef:
if (processing_has_namespace_info
&& processing_current_prefix[0] != '\0')
{
SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
processing_current_prefix,
"::",
name);
}
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, list_in_scope);
break;
case DW_TAG_base_type:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, list_in_scope);
break;
case DW_TAG_enumerator:
if (processing_has_namespace_info
&& processing_current_prefix[0] != '\0')
{
SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
processing_current_prefix,
"::",
name);
}
attr = dwarf_attr (die, DW_AT_const_value);
if (attr)
{
dwarf2_const_value (attr, sym, cu);
}
add_symbol_to_list (sym, list_in_scope);
{
/* NOTE: carlton/2003-11-10: See comment above in the
DW_TAG_class_type, etc. block. */
struct pending **list_to_add;
list_to_add = (list_in_scope == &file_symbols
&& cu_language == language_cplus
? &global_symbols : list_in_scope);
add_symbol_to_list (sym, list_to_add);
}
break;
case DW_TAG_namespace:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -5588,6 +5876,11 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
static void
read_type_die (struct die_info *die, struct dwarf2_cu *cu)
{
char *prefix = determine_prefix (die);
const char *old_prefix = processing_current_prefix;
struct cleanup *back_to = make_cleanup (xfree, prefix);
processing_current_prefix = prefix;
switch (die->tag)
{
case DW_TAG_class_type:
@@ -5634,6 +5927,114 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu)
dwarf_tag_name (die->tag));
break;
}
processing_current_prefix = old_prefix;
do_cleanups (back_to);
}
/* 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 *
determine_prefix (struct die_info *die)
{
struct die_info *parent;
if (cu_language != language_cplus)
return NULL;
parent = die->parent;
if (parent == NULL)
{
return (processing_has_namespace_info ? xstrdup ("") : NULL);
}
else
{
char *parent_prefix = determine_prefix (parent);
char *retval;
switch (parent->tag) {
case DW_TAG_namespace:
{
int dummy;
retval = typename_concat (parent_prefix,
namespace_name (parent, &dummy));
}
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
{
if (parent_prefix != NULL)
{
const char *parent_name = dwarf2_name (parent);
if (parent_name != NULL)
retval = typename_concat (parent_prefix, dwarf2_name (parent));
else
/* FIXME: carlton/2003-11-10: I'm not sure what the
best thing to do here is. */
retval = typename_concat (parent_prefix,
"<<anonymous class>>");
}
else
retval = class_name (parent);
}
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. */
static char *
typename_concat (const char *prefix, const char *suffix)
{
if (prefix == NULL || prefix[0] == '\0')
return xstrdup (suffix);
else
{
char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
strcpy (retval, prefix);
strcat (retval, "::");
strcat (retval, suffix);
return retval;
}
}
/* Return a newly-allocated string giving the name of the class given
by DIE. */
static char *
class_name (struct die_info *die)
{
struct die_info *child;
const char *name;
for (child = die->child; child != NULL; child = sibling_die (child))
{
if (child->tag == DW_TAG_subprogram)
return class_name_from_physname (dwarf2_linkage_name (child));
}
name = dwarf2_name (die);
if (name != NULL)
return xstrdup (name);
else
return xstrdup ("");
}
static struct type *