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:
parent
a51dab8874
commit
63d06c5c42
@ -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>
|
2004-01-12 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
* mips-tdep.c (mips_convert_register_p): Handle both raw and
|
* mips-tdep.c (mips_convert_register_p): Handle both raw and
|
||||||
|
15
gdb/c-exp.y
15
gdb/c-exp.y
@ -1,6 +1,6 @@
|
|||||||
/* YACC parser for C expressions, for GDB.
|
/* YACC parser for C expressions, for GDB.
|
||||||
Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||||
1998, 1999, 2000, 2003
|
1998, 1999, 2000, 2003, 2004
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
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
|
decode_line_1), but I'm not holding my breath waiting for somebody
|
||||||
to get around to cleaning this up... */
|
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
|
qualified_type: typebase COLONCOLON name
|
||||||
{
|
{
|
||||||
struct type *type = $1;
|
struct type *type = $1;
|
||||||
@ -953,14 +948,16 @@ qualified_type: typebase COLONCOLON name
|
|||||||
memcpy (ncopy, $3.ptr, $3.length);
|
memcpy (ncopy, $3.ptr, $3.length);
|
||||||
ncopy[$3.length] = '\0';
|
ncopy[$3.length] = '\0';
|
||||||
|
|
||||||
if (TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
|
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
||||||
error ("`%s' is not defined as a namespace.",
|
&& TYPE_CODE (type) != TYPE_CODE_UNION
|
||||||
|
&& TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
|
||||||
|
error ("`%s' is not defined as an aggregate type.",
|
||||||
TYPE_NAME (type));
|
TYPE_NAME (type));
|
||||||
|
|
||||||
new_type = cp_lookup_nested_type (type, ncopy,
|
new_type = cp_lookup_nested_type (type, ncopy,
|
||||||
expression_context_block);
|
expression_context_block);
|
||||||
if (new_type == NULL)
|
if (new_type == NULL)
|
||||||
error ("No type \"%s\" in namespace \"%s\".",
|
error ("No type \"%s\" within class or namespace \"%s\".",
|
||||||
ncopy, TYPE_NAME (type));
|
ncopy, TYPE_NAME (type));
|
||||||
|
|
||||||
$$ = new_type;
|
$$ = new_type;
|
||||||
|
@ -32,9 +32,12 @@
|
|||||||
#include "dictionary.h"
|
#include "dictionary.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
/* When set, the file that we're processing seems to have debugging
|
/* When set, the file that we're processing is known to have debugging
|
||||||
info for C++ namespaces, so cp-namespace.c shouldn't try to guess
|
info for C++ namespaces. */
|
||||||
namespace info itself. */
|
|
||||||
|
/* 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;
|
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 (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)
|
if (processing_has_namespace_info)
|
||||||
{
|
{
|
||||||
block_set_scope
|
block_set_scope
|
||||||
@ -237,7 +234,6 @@ cp_set_block_scope (const struct symbol *symbol,
|
|||||||
obstack);
|
obstack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/* Try to figure out the appropriate namespace from the
|
/* Try to figure out the appropriate namespace from the
|
||||||
demangled name. */
|
demangled name. */
|
||||||
@ -520,10 +516,6 @@ lookup_symbol_file (const char *name,
|
|||||||
class or namespace given by PARENT_TYPE, from within the context
|
class or namespace given by PARENT_TYPE, from within the context
|
||||||
given by BLOCK. Return NULL if there is no such nested type. */
|
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 *
|
struct type *
|
||||||
cp_lookup_nested_type (struct type *parent_type,
|
cp_lookup_nested_type (struct type *parent_type,
|
||||||
const char *nested_name,
|
const char *nested_name,
|
||||||
@ -531,8 +523,16 @@ cp_lookup_nested_type (struct type *parent_type,
|
|||||||
{
|
{
|
||||||
switch (TYPE_CODE (parent_type))
|
switch (TYPE_CODE (parent_type))
|
||||||
{
|
{
|
||||||
|
case TYPE_CODE_STRUCT:
|
||||||
case TYPE_CODE_NAMESPACE:
|
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);
|
const char *parent_name = TYPE_TAG_NAME (parent_type);
|
||||||
struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
|
struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
|
||||||
nested_name,
|
nested_name,
|
||||||
@ -547,7 +547,7 @@ cp_lookup_nested_type (struct type *parent_type,
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
internal_error (__FILE__, __LINE__,
|
internal_error (__FILE__, __LINE__,
|
||||||
"cp_lookup_nested_type called on a non-namespace.");
|
"cp_lookup_nested_type called on a non-aggregate type.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
481
gdb/dwarf2read.c
481
gdb/dwarf2read.c
@ -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 *,
|
static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *,
|
||||||
const char *namespace);
|
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,
|
static char *add_partial_namespace (struct partial_die_info *pdi,
|
||||||
char *info_ptr,
|
char *info_ptr,
|
||||||
CORE_ADDR *lowpc, CORE_ADDR *highpc,
|
CORE_ADDR *lowpc, CORE_ADDR *highpc,
|
||||||
struct dwarf2_cu *cu,
|
struct dwarf2_cu *cu,
|
||||||
const char *namespace);
|
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,
|
static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
|
||||||
char *info_ptr,
|
char *info_ptr,
|
||||||
struct dwarf2_cu *cu,
|
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 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 void free_line_header (struct line_header *lh);
|
||||||
|
|
||||||
static struct line_header *(dwarf_decode_line_header
|
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 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_typedef (struct die_info *, struct dwarf2_cu *);
|
||||||
|
|
||||||
static void read_base_type (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_variable:
|
||||||
case DW_TAG_typedef:
|
case DW_TAG_typedef:
|
||||||
case DW_TAG_union_type:
|
case DW_TAG_union_type:
|
||||||
|
if (!pdi.is_declaration)
|
||||||
|
{
|
||||||
|
add_partial_symbol (&pdi, cu, namespace);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DW_TAG_class_type:
|
case DW_TAG_class_type:
|
||||||
case DW_TAG_structure_type:
|
case DW_TAG_structure_type:
|
||||||
if (!pdi.is_declaration)
|
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;
|
break;
|
||||||
case DW_TAG_enumeration_type:
|
case DW_TAG_enumeration_type:
|
||||||
@ -1430,6 +1452,17 @@ add_partial_symbol (struct partial_die_info *pdi,
|
|||||||
char *actual_name = pdi->name;
|
char *actual_name = pdi->name;
|
||||||
const struct partial_symbol *psym = NULL;
|
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)
|
switch (pdi->tag)
|
||||||
{
|
{
|
||||||
case DW_TAG_subprogram:
|
case DW_TAG_subprogram:
|
||||||
@ -1507,11 +1540,15 @@ add_partial_symbol (struct partial_die_info *pdi,
|
|||||||
case DW_TAG_enumeration_type:
|
case DW_TAG_enumeration_type:
|
||||||
/* Skip aggregate types without children, these are external
|
/* Skip aggregate types without children, these are external
|
||||||
references. */
|
references. */
|
||||||
|
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
|
||||||
|
static vs. global. */
|
||||||
if (pdi->has_children == 0)
|
if (pdi->has_children == 0)
|
||||||
return;
|
return;
|
||||||
add_psymbol_to_list (actual_name, strlen (actual_name),
|
add_psymbol_to_list (actual_name, strlen (actual_name),
|
||||||
STRUCT_DOMAIN, LOC_TYPEDEF,
|
STRUCT_DOMAIN, LOC_TYPEDEF,
|
||||||
&objfile->static_psymbols,
|
cu_language == language_cplus
|
||||||
|
? &objfile->global_psymbols
|
||||||
|
: &objfile->static_psymbols,
|
||||||
0, (CORE_ADDR) 0, cu_language, objfile);
|
0, (CORE_ADDR) 0, cu_language, objfile);
|
||||||
|
|
||||||
if (cu_language == language_cplus)
|
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. */
|
/* For C++, these implicitly act as typedefs as well. */
|
||||||
add_psymbol_to_list (actual_name, strlen (actual_name),
|
add_psymbol_to_list (actual_name, strlen (actual_name),
|
||||||
VAR_DOMAIN, LOC_TYPEDEF,
|
VAR_DOMAIN, LOC_TYPEDEF,
|
||||||
&objfile->static_psymbols,
|
&objfile->global_psymbols,
|
||||||
0, (CORE_ADDR) 0, cu_language, objfile);
|
0, (CORE_ADDR) 0, cu_language, objfile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DW_TAG_enumerator:
|
case DW_TAG_enumerator:
|
||||||
add_psymbol_to_list (actual_name, strlen (actual_name),
|
add_psymbol_to_list (actual_name, strlen (actual_name),
|
||||||
VAR_DOMAIN, LOC_CONST,
|
VAR_DOMAIN, LOC_CONST,
|
||||||
&objfile->static_psymbols,
|
cu_language == language_cplus
|
||||||
|
? &objfile->static_psymbols
|
||||||
|
: &objfile->global_psymbols,
|
||||||
0, (CORE_ADDR) 0, cu_language, objfile);
|
0, (CORE_ADDR) 0, cu_language, objfile);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1547,6 +1586,30 @@ add_partial_symbol (struct partial_die_info *pdi,
|
|||||||
objfile);
|
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
|
/* Read a partial die corresponding to a namespace; also, add a symbol
|
||||||
corresponding to that namespace to the symbol table. NAMESPACE is
|
corresponding to that namespace to the symbol table. NAMESPACE is
|
||||||
the name of the enclosing namespace. */
|
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, "::");
|
||||||
strcat (full_name, new_name);
|
strcat (full_name, new_name);
|
||||||
|
|
||||||
/* FIXME: carlton/2003-06-27: Once we build qualified names for more
|
/* FIXME: carlton/2003-10-07: We can't just replace this by a call
|
||||||
symbols than just namespaces, we should replace this by a call to
|
to add_partial_symbol, because we don't have a way to pass in the
|
||||||
add_partial_symbol. */
|
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),
|
add_psymbol_to_list (full_name, strlen (full_name),
|
||||||
VAR_DOMAIN, LOC_TYPEDEF,
|
VAR_DOMAIN, LOC_TYPEDEF,
|
||||||
@ -1587,6 +1651,63 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
|
|||||||
return 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. */
|
/* Read a partial die corresponding to an enumeration type. */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@ -1711,6 +1832,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
|
|||||||
cu_header_offset = offset;
|
cu_header_offset = offset;
|
||||||
info_ptr = dwarf_info_buffer + offset;
|
info_ptr = dwarf_info_buffer + offset;
|
||||||
|
|
||||||
|
/* We're in the global namespace. */
|
||||||
|
processing_current_prefix = "";
|
||||||
|
|
||||||
obstack_init (&dwarf2_tmp_obstack);
|
obstack_init (&dwarf2_tmp_obstack);
|
||||||
back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
|
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:
|
case DW_TAG_common_inclusion:
|
||||||
break;
|
break;
|
||||||
case DW_TAG_namespace:
|
case DW_TAG_namespace:
|
||||||
if (!processing_has_namespace_info)
|
processing_has_namespace_info = 1;
|
||||||
{
|
|
||||||
processing_has_namespace_info = 1;
|
|
||||||
processing_current_prefix = "";
|
|
||||||
}
|
|
||||||
read_namespace (die, cu);
|
read_namespace (die, cu);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_imported_declaration:
|
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
|
shouldn't in the C++ case, but conceivably could in the
|
||||||
Fortran case, so we'll have to replace this gdb_assert if
|
Fortran case, so we'll have to replace this gdb_assert if
|
||||||
Fortran compilers start generating that info. */
|
Fortran compilers start generating that info. */
|
||||||
if (!processing_has_namespace_info)
|
processing_has_namespace_info = 1;
|
||||||
{
|
|
||||||
processing_has_namespace_info = 1;
|
|
||||||
processing_current_prefix = "";
|
|
||||||
}
|
|
||||||
gdb_assert (die->child == NULL);
|
gdb_assert (die->child == NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2777,6 +2893,13 @@ read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
struct objfile *objfile = cu->objfile;
|
struct objfile *objfile = cu->objfile;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
struct attribute *attr;
|
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);
|
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);
|
attr = dwarf_attr (die, DW_AT_name);
|
||||||
if (attr && DW_STRING (attr))
|
if (attr && DW_STRING (attr))
|
||||||
{
|
{
|
||||||
TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
|
name = DW_STRING (attr);
|
||||||
strlen (DW_STRING (attr)),
|
|
||||||
&objfile->type_obstack);
|
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)
|
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. */
|
/* C++ member function. */
|
||||||
process_die (child_die, cu);
|
process_die (child_die, cu);
|
||||||
dwarf2_add_member_fn (&fi, child_die, type, 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)
|
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. */
|
/* No children, must be stub. */
|
||||||
TYPE_FLAGS (type) |= TYPE_FLAG_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
|
/* 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);
|
attr = dwarf_attr (die, DW_AT_name);
|
||||||
if (attr && DW_STRING (attr))
|
if (attr && DW_STRING (attr))
|
||||||
{
|
{
|
||||||
TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
|
const char *name = DW_STRING (attr);
|
||||||
strlen (DW_STRING (attr)),
|
|
||||||
&objfile->type_obstack);
|
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);
|
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;
|
struct objfile *objfile = cu->objfile;
|
||||||
const char *previous_prefix = processing_current_prefix;
|
const char *previous_prefix = processing_current_prefix;
|
||||||
const char *name = NULL;
|
const char *name;
|
||||||
int is_anonymous;
|
int is_anonymous;
|
||||||
struct die_info *current_die;
|
struct die_info *current_die;
|
||||||
|
|
||||||
@ -4679,6 +4885,19 @@ die_is_declaration (struct die_info *die)
|
|||||||
&& ! dwarf_attr (die, DW_AT_specification));
|
&& ! 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
|
/* Free the line_header structure *LH, and any arrays and strings it
|
||||||
refers to. */
|
refers to. */
|
||||||
@ -5322,39 +5541,108 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
|
|||||||
case DW_TAG_enumeration_type:
|
case DW_TAG_enumeration_type:
|
||||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||||
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
|
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
|
||||||
add_symbol_to_list (sym, list_in_scope);
|
|
||||||
|
|
||||||
/* The semantics of C++ state that "struct foo { ... }" also
|
/* Make sure that the symbol includes appropriate enclosing
|
||||||
defines a typedef for "foo". Synthesize a typedef symbol so
|
classes/namespaces in its name. These are calculated in
|
||||||
that "ptype foo" works as expected. */
|
read_structure_scope, and the correct name is saved in
|
||||||
|
the type. */
|
||||||
|
|
||||||
if (cu_language == language_cplus)
|
if (cu_language == language_cplus)
|
||||||
{
|
{
|
||||||
struct symbol *typedef_sym = (struct symbol *)
|
struct type *type = SYMBOL_TYPE (sym);
|
||||||
obstack_alloc (&objfile->symbol_obstack,
|
|
||||||
sizeof (struct symbol));
|
if (TYPE_TAG_NAME (type) != NULL)
|
||||||
*typedef_sym = *sym;
|
{
|
||||||
SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
|
/* FIXME: carlton/2003-11-10: Should this use
|
||||||
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
|
SYMBOL_SET_NAMES instead? (The same problem also
|
||||||
TYPE_NAME (SYMBOL_TYPE (sym)) =
|
arises a further down in the function.) */
|
||||||
obsavestring (DEPRECATED_SYMBOL_NAME (sym),
|
SYMBOL_LINKAGE_NAME (sym)
|
||||||
strlen (DEPRECATED_SYMBOL_NAME (sym)),
|
= obsavestring (TYPE_TAG_NAME (type),
|
||||||
&objfile->type_obstack);
|
strlen (TYPE_TAG_NAME (type)),
|
||||||
add_symbol_to_list (typedef_sym, list_in_scope);
|
&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;
|
break;
|
||||||
case DW_TAG_typedef:
|
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:
|
case DW_TAG_base_type:
|
||||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||||
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
||||||
add_symbol_to_list (sym, list_in_scope);
|
add_symbol_to_list (sym, list_in_scope);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_enumerator:
|
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);
|
attr = dwarf_attr (die, DW_AT_const_value);
|
||||||
if (attr)
|
if (attr)
|
||||||
{
|
{
|
||||||
dwarf2_const_value (attr, sym, cu);
|
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;
|
break;
|
||||||
case DW_TAG_namespace:
|
case DW_TAG_namespace:
|
||||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||||
@ -5588,6 +5876,11 @@ tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||||||
static void
|
static void
|
||||||
read_type_die (struct die_info *die, struct dwarf2_cu *cu)
|
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)
|
switch (die->tag)
|
||||||
{
|
{
|
||||||
case DW_TAG_class_type:
|
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));
|
dwarf_tag_name (die->tag));
|
||||||
break;
|
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 *
|
static struct type *
|
||||||
|
@ -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>
|
2004-01-14 Elena Zannoni <ezannoni@redhat.com>
|
||||||
|
|
||||||
* gdb.base/sepdebug.exp: Bail out of the test if we don't know
|
* gdb.base/sepdebug.exp: Bail out of the test if we don't know
|
||||||
|
@ -88,6 +88,15 @@ namespace C
|
|||||||
int c = 1;
|
int c = 1;
|
||||||
int shadow = 12;
|
int shadow = 12;
|
||||||
|
|
||||||
|
class CClass {
|
||||||
|
public:
|
||||||
|
int x;
|
||||||
|
class NestedClass {
|
||||||
|
public:
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
int cX = 6;
|
int cX = 6;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
# Note: The original tests were geared to the HP aCC compiler,
|
# Note: The original tests were geared to the HP aCC compiler,
|
||||||
# which has an idiosyncratic way of emitting debug info
|
# which has an idiosyncratic way of emitting debug info
|
||||||
# for namespaces.
|
# 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 {
|
if $tracelevel then {
|
||||||
@ -83,7 +83,7 @@ if ![runto 'marker1'] then {
|
|||||||
gdb_test "up" ".*main.*" "up from marker1"
|
gdb_test "up" ".*main.*" "up from marker1"
|
||||||
|
|
||||||
# Access a data item inside a namespace using colons and
|
# 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
|
# NOTE: carlton/2003-09-24: the quotes are becoming less necessary (or
|
||||||
# even desirable.) For tests where it should still work with quotes,
|
# even desirable.) For tests where it should still work with quotes,
|
||||||
@ -215,6 +215,15 @@ gdb_expect {
|
|||||||
timeout { fail "(timeout) print 'BBB::Class::xyzq'" }
|
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
|
# Break on a function in a class in a namespace
|
||||||
|
|
||||||
send_gdb "break BBB::Class::xyzq\n"
|
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 C::cc" "\\$\[0-9\].* = 2"
|
gdb_test "print C::cc" "\\$\[0-9\].* = 2"
|
||||||
gdb_test "print cd" "\\$\[0-9\].* = 3"
|
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 E::cde" "\\$\[0-9\].* = 5"
|
gdb_test "print E::cde" "\\$\[0-9\].* = 5"
|
||||||
gdb_test "print shadow" "\\$\[0-9\].* = 13"
|
gdb_test "print shadow" "\\$\[0-9\].* = 13"
|
||||||
gdb_test "print E::ce" "No symbol \"ce\" in namespace \"C::D::E\"."
|
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 C" "type = namespace C::C"
|
||||||
gdb_test "ptype E" "type = namespace C::D::E"
|
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.
|
# Some anonymous namespace tests.
|
||||||
|
|
||||||
gdb_test "print cX" "\\$\[0-9\].* = 6"
|
gdb_test "print cX" "\\$\[0-9\].* = 6"
|
||||||
|
@ -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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -19,6 +19,11 @@
|
|||||||
|
|
||||||
namespace C
|
namespace C
|
||||||
{
|
{
|
||||||
|
class OtherFileClass {
|
||||||
|
public:
|
||||||
|
int z;
|
||||||
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int cXOtherFile = 29;
|
int cXOtherFile = 29;
|
||||||
};
|
};
|
||||||
|
75
gdb/valops.c
75
gdb/valops.c
@ -1,6 +1,6 @@
|
|||||||
/* Perform non-arithmetic operations on values, for GDB.
|
/* Perform non-arithmetic operations on values, for GDB.
|
||||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
|
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.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
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 int check_field_in (struct type *, const char *);
|
||||||
|
|
||||||
|
|
||||||
static struct value *value_struct_elt_for_reference (struct type *domain,
|
static struct value *value_struct_elt_for_reference (struct type *domain,
|
||||||
int offset,
|
int offset,
|
||||||
struct type *curtype,
|
struct type *curtype,
|
||||||
char *name,
|
char *name,
|
||||||
struct type *intype);
|
struct type *intype,
|
||||||
|
enum noside noside);
|
||||||
|
|
||||||
static struct value *value_namespace_elt (const struct type *curtype,
|
static struct value *value_namespace_elt (const struct type *curtype,
|
||||||
const char *name,
|
char *name,
|
||||||
enum noside noside);
|
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 CORE_ADDR allocate_space_in_inferior (int);
|
||||||
|
|
||||||
static struct value *cast_into_complex (struct type *, struct value *);
|
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_STRUCT:
|
||||||
case TYPE_CODE_UNION:
|
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:
|
case TYPE_CODE_NAMESPACE:
|
||||||
return value_namespace_elt (curtype, name, noside);
|
return value_namespace_elt (curtype, name, noside);
|
||||||
default:
|
default:
|
||||||
@ -2250,10 +2255,11 @@ value_aggregate_elt (struct type *curtype,
|
|||||||
"pointers to member functions". This function is used
|
"pointers to member functions". This function is used
|
||||||
to resolve user expressions of the form "DOMAIN::NAME". */
|
to resolve user expressions of the form "DOMAIN::NAME". */
|
||||||
|
|
||||||
struct value *
|
static struct value *
|
||||||
value_struct_elt_for_reference (struct type *domain, int offset,
|
value_struct_elt_for_reference (struct type *domain, int offset,
|
||||||
struct type *curtype, char *name,
|
struct type *curtype, char *name,
|
||||||
struct type *intype)
|
struct type *intype,
|
||||||
|
enum noside noside)
|
||||||
{
|
{
|
||||||
struct type *t = curtype;
|
struct type *t = curtype;
|
||||||
int i;
|
int i;
|
||||||
@ -2376,11 +2382,17 @@ value_struct_elt_for_reference (struct type *domain, int offset,
|
|||||||
offset + base_offset,
|
offset + base_offset,
|
||||||
TYPE_BASECLASS (t, i),
|
TYPE_BASECLASS (t, i),
|
||||||
name,
|
name,
|
||||||
intype);
|
intype,
|
||||||
|
noside);
|
||||||
if (v)
|
if (v)
|
||||||
return 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
|
/* 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 *
|
static struct value *
|
||||||
value_namespace_elt (const struct type *curtype,
|
value_namespace_elt (const struct type *curtype,
|
||||||
const char *name,
|
char *name,
|
||||||
enum noside noside)
|
enum noside noside)
|
||||||
{
|
{
|
||||||
const char *namespace_name = TYPE_TAG_NAME (curtype);
|
struct value *retval = value_maybe_namespace_elt (curtype, name,
|
||||||
struct symbol *sym;
|
noside);
|
||||||
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));
|
|
||||||
|
|
||||||
if (retval == NULL)
|
if (retval == NULL)
|
||||||
error ("No symbol \"%s\" in namespace \"%s\".", name,
|
error ("No symbol \"%s\" in namespace \"%s\".", name,
|
||||||
@ -2414,6 +2413,32 @@ value_namespace_elt (const struct type *curtype,
|
|||||||
return retval;
|
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
|
/* Given a pointer value V, find the real (RTTI) type
|
||||||
of the object it points to.
|
of the object it points to.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user