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

@ -1,3 +1,41 @@
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 (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 (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-12 Andrew Cagney <cagney@redhat.com>
* mips-tdep.c (mips_convert_register_p): Handle both raw and

View File

@ -1,6 +1,6 @@
/* YACC parser for C expressions, for GDB.
Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2003
1998, 1999, 2000, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
@ -939,11 +939,6 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
decode_line_1), but I'm not holding my breath waiting for somebody
to get around to cleaning this up... */
/* FIXME: carlton/2003-09-25: Currently, the only qualified type
symbols that we generate are nested namespaces. Next on my TODO
list is to generate all nested type names properly (or at least as
well as possible, assuming that we're using DWARF-2). */
qualified_type: typebase COLONCOLON name
{
struct type *type = $1;
@ -953,14 +948,16 @@ qualified_type: typebase COLONCOLON name
memcpy (ncopy, $3.ptr, $3.length);
ncopy[$3.length] = '\0';
if (TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
error ("`%s' is not defined as a namespace.",
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION
&& TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
new_type = cp_lookup_nested_type (type, ncopy,
expression_context_block);
if (new_type == NULL)
error ("No type \"%s\" in namespace \"%s\".",
error ("No type \"%s\" within class or namespace \"%s\".",
ncopy, TYPE_NAME (type));
$$ = new_type;

View File

@ -32,9 +32,12 @@
#include "dictionary.h"
#include "command.h"
/* When set, the file that we're processing seems to have debugging
info for C++ namespaces, so cp-namespace.c shouldn't try to guess
namespace info itself. */
/* When set, the file that we're processing is known to have debugging
info for C++ namespaces. */
/* NOTE: carlton/2004-01-13: No currently released version of GCC (the
latest of which is 3.3.x at the time of this writing) produces this
debug info. GCC 3.4 should, however. */
unsigned char processing_has_namespace_info;
@ -222,12 +225,6 @@ cp_set_block_scope (const struct symbol *symbol,
if (SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
{
#if 0
/* FIXME: carlton/2003-06-12: As mentioned above,
'processing_has_namespace_info' currently isn't entirely
reliable, so let's always use demangled names to get this
information for now. */
if (processing_has_namespace_info)
{
block_set_scope
@ -237,7 +234,6 @@ cp_set_block_scope (const struct symbol *symbol,
obstack);
}
else
#endif
{
/* Try to figure out the appropriate namespace from the
demangled name. */
@ -520,10 +516,6 @@ lookup_symbol_file (const char *name,
class or namespace given by PARENT_TYPE, from within the context
given by BLOCK. Return NULL if there is no such nested type. */
/* FIXME: carlton/2003-09-24: For now, this only works for nested
namespaces; the patch to make this work on other sorts of nested
types is next on my TODO list. */
struct type *
cp_lookup_nested_type (struct type *parent_type,
const char *nested_name,
@ -531,8 +523,16 @@ cp_lookup_nested_type (struct type *parent_type,
{
switch (TYPE_CODE (parent_type))
{
case TYPE_CODE_STRUCT:
case TYPE_CODE_NAMESPACE:
{
/* NOTE: carlton/2003-11-10: We don't treat C++ class members
of classes like, say, data or function members. Instead,
they're just represented by symbols whose names are
qualified by the name of the surrounding class. This is
just like members of namespaces; in particular,
lookup_symbol_namespace works when looking them up. */
const char *parent_name = TYPE_TAG_NAME (parent_type);
struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
nested_name,
@ -547,7 +547,7 @@ cp_lookup_nested_type (struct type *parent_type,
}
default:
internal_error (__FILE__, __LINE__,
"cp_lookup_nested_type called on a non-namespace.");
"cp_lookup_nested_type called on a non-aggregate type.");
}
}

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 *

View File

@ -1,3 +1,10 @@
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 (C::OtherFileClass): New.
2004-01-14 Elena Zannoni <ezannoni@redhat.com>
* gdb.base/sepdebug.exp: Bail out of the test if we don't know

View File

@ -88,6 +88,15 @@ namespace C
int c = 1;
int shadow = 12;
class CClass {
public:
int x;
class NestedClass {
public:
int y;
};
};
namespace
{
int cX = 6;

View File

@ -26,7 +26,7 @@
# Note: The original tests were geared to the HP aCC compiler,
# which has an idiosyncratic way of emitting debug info
# for namespaces.
# Note: As of 2000-06-03, these pass under g++ - djb
# Note: As of 2000-06-03, they passed under g++ - djb
if $tracelevel then {
@ -83,7 +83,7 @@ if ![runto 'marker1'] then {
gdb_test "up" ".*main.*" "up from marker1"
# Access a data item inside a namespace using colons and
# single quotes :-(
# single quotes. :-(
# NOTE: carlton/2003-09-24: the quotes are becoming less necessary (or
# even desirable.) For tests where it should still work with quotes,
@ -215,6 +215,15 @@ gdb_expect {
timeout { fail "(timeout) print 'BBB::Class::xyzq'" }
}
send_gdb "print BBB::Class::xyzq\n"
gdb_expect {
-re "\\$\[0-9\]* = \{char \\((BBB::|)Class \\*( const|), (char|int)\\)\} $hex <BBB::Class::xyzq\\(char\\)>\r\n$gdb_prompt $" {
pass "print BBB::Class::xyzq"
}
-re ".*$gdb_prompt $" { fail "print BBB::Class::xyzq" }
timeout { fail "(timeout) print BBB::Class::xyzq" }
}
# Break on a function in a class in a namespace
send_gdb "break BBB::Class::xyzq\n"
@ -240,15 +249,35 @@ gdb_test "print cc" "No symbol \"cc\" in current context."
gdb_test "print 'C::cc'" "\\$\[0-9\].* = 2"
gdb_test "print C::cc" "\\$\[0-9\].* = 2"
gdb_test "print cd" "\\$\[0-9\].* = 3"
gdb_test "print C::D::cd" "No type \"D\" in namespace \"C::C\"."
gdb_test "print C::D::cd" "No type \"D\" within class or namespace \"C::C\"."
gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
gdb_test "print E::cde" "\\$\[0-9\].* = 5"
gdb_test "print shadow" "\\$\[0-9\].* = 13"
gdb_test "print E::ce" "No symbol \"ce\" in namespace \"C::D::E\"."
gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
gdb_test "ptype C" "type = namespace C::C"
gdb_test "ptype E" "type = namespace C::D::E"
gdb_test "ptype CClass" "type = class C::CClass \{\r\n public:\r\n int x;\r\n\}"
gdb_test "ptype CClass::NestedClass" "type = class C::CClass::NestedClass \{\r\n public:\r\n int y;\r\n\}"
gdb_test "ptype NestedClass" "No symbol \"NestedClass\" in current context."
setup_kfail "gdb/1448" "*-*-*"
gdb_test "ptype ::C::CClass" "type = class C::CClass \{\r\n public:\r\n int x;\r\n\}"
setup_kfail "gdb/1448" "*-*-*"
gdb_test "ptype ::C::CClass::NestedClass" "type = class C::CClass::NestedClass \{\r\n public:\r\n int y;\r\n\}"
setup_kfail "gdb/1448" "*-*-*"
gdb_test "ptype ::C::NestedClass" "No symbol \"NestedClass\" in namespace \"C\"."
gdb_test "ptype C::CClass" "No symbol \"CClass\" in namespace \"C::C\"."
gdb_test "ptype C::CClass::NestedClass" "No type \"CClass\" within class or namespace \"C::C\"."
gdb_test "ptype C::NestedClass" "No symbol \"NestedClass\" in namespace \"C::C\"."
# Tests involving multiple files
gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
gdb_test "ptype OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n\}"
setup_kfail "gdb/1448" "*-*-*"
gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n\}"
gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"."
# Some anonymous namespace tests.
gdb_test "print cX" "\\$\[0-9\].* = 6"

View File

@ -1,4 +1,4 @@
/* Copyright 2003 Free Software Foundation, Inc.
/* Copyright 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -19,6 +19,11 @@
namespace C
{
class OtherFileClass {
public:
int z;
};
namespace {
int cXOtherFile = 29;
};

View File

@ -1,6 +1,6 @@
/* Perform non-arithmetic operations on values, for GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
@ -64,17 +64,21 @@ static struct value *search_struct_method (char *, struct value **,
static int check_field_in (struct type *, const char *);
static struct value *value_struct_elt_for_reference (struct type *domain,
int offset,
struct type *curtype,
char *name,
struct type *intype);
struct type *intype,
enum noside noside);
static struct value *value_namespace_elt (const struct type *curtype,
const char *name,
char *name,
enum noside noside);
static struct value *value_maybe_namespace_elt (const struct type *curtype,
char *name,
enum noside noside);
static CORE_ADDR allocate_space_in_inferior (int);
static struct value *cast_into_complex (struct type *, struct value *);
@ -2234,7 +2238,8 @@ value_aggregate_elt (struct type *curtype,
{
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL);
return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL,
noside);
case TYPE_CODE_NAMESPACE:
return value_namespace_elt (curtype, name, noside);
default:
@ -2250,10 +2255,11 @@ value_aggregate_elt (struct type *curtype,
"pointers to member functions". This function is used
to resolve user expressions of the form "DOMAIN::NAME". */
struct value *
static struct value *
value_struct_elt_for_reference (struct type *domain, int offset,
struct type *curtype, char *name,
struct type *intype)
struct type *intype,
enum noside noside)
{
struct type *t = curtype;
int i;
@ -2376,11 +2382,17 @@ value_struct_elt_for_reference (struct type *domain, int offset,
offset + base_offset,
TYPE_BASECLASS (t, i),
name,
intype);
intype,
noside);
if (v)
return v;
}
return 0;
/* As a last chance, pretend that CURTYPE is a namespace, and look
it up that way; this (frequently) works for types nested inside
classes. */
return value_maybe_namespace_elt (curtype, name, noside);
}
/* C++: Return the member NAME of the namespace given by the type
@ -2388,24 +2400,11 @@ value_struct_elt_for_reference (struct type *domain, int offset,
static struct value *
value_namespace_elt (const struct type *curtype,
const char *name,
char *name,
enum noside noside)
{
const char *namespace_name = TYPE_TAG_NAME (curtype);
struct symbol *sym;
struct value *retval;
sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
get_selected_block (0), VAR_DOMAIN,
NULL);
if (sym == NULL)
retval = NULL;
else if ((noside == EVAL_AVOID_SIDE_EFFECTS)
&& (SYMBOL_CLASS (sym) == LOC_TYPEDEF))
retval = allocate_value (SYMBOL_TYPE (sym));
else
retval = value_of_variable (sym, get_selected_block (0));
struct value *retval = value_maybe_namespace_elt (curtype, name,
noside);
if (retval == NULL)
error ("No symbol \"%s\" in namespace \"%s\".", name,
@ -2414,6 +2413,32 @@ value_namespace_elt (const struct type *curtype,
return retval;
}
/* A helper function used by value_namespace_elt and
value_struct_elt_for_reference. It looks up NAME inside the
context CURTYPE; this works if CURTYPE is a namespace or if CURTYPE
is a class and NAME refers to a type in CURTYPE itself (as opposed
to, say, some base class of CURTYPE). */
static struct value *
value_maybe_namespace_elt (const struct type *curtype,
char *name,
enum noside noside)
{
const char *namespace_name = TYPE_TAG_NAME (curtype);
struct symbol *sym;
sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
get_selected_block (0), VAR_DOMAIN,
NULL);
if (sym == NULL)
return NULL;
else if ((noside == EVAL_AVOID_SIDE_EFFECTS)
&& (SYMBOL_CLASS (sym) == LOC_TYPEDEF))
return allocate_value (SYMBOL_TYPE (sym));
else
return value_of_variable (sym, get_selected_block (0));
}
/* Given a pointer value V, find the real (RTTI) type
of the object it points to.