2003-09-11 David Carlton <carlton@kealia.com>
* gdbtypes.h: Add TYPE_CODE_NAMESPACE. * gdbtypes.c (init_type): Handle TYPE_CODE_NAMESPACE. (recursive_dump_type): Ditto. * printcmd.c (print_formatted): Ditto. * typeprint.c (print_type_scalar): Ditto. * c-typeprint.c (c_type_print_varspec_prefix): Ditto. (c_type_print_varspec_suffix, c_type_print_base): Ditto. * cp-support.h: Declare cp_check_possible_namespace_symbols, maint_cplus_cmd_list. * cp-support.c: Make maint_cplus_cmd_list extern. * cp-namespace.c: Include objfiles.h, gdbtypes.h, dictionary.h, command.h. (lookup_symbol_file): Look in possible namespace blocks when appropriate. (initialize_namespace_symtab): New. (get_possible_namespace_block, free_namespace_block) (check_possible_namespace_symbols) (check_possible_namespace_symbols_loop) (check_one_possible_namespace_symbol) (lookup_possible_namespace_symbol, maintenance_cplus_namespace) (_initialize_cp_namespace): Ditto. * block.h: Declare allocate_block. * block.c (allocate_block): New. * jv-lang.c (get_java_class_symtab): Allocate blocks via allocate_block. * symfile.h: Update declaration of add_psymbol_to_list. * symfile.c (add_psymbol_to_list): Return the partial symbol in question. * dwarf2read.c (dwarf2_build_psymtabs_hard): Add argument to scan_partial_symbols_call. (scan_partial_symbols): Add NAMESPACE argument; update calls to helper functions. (add_partial_symbol): If necessary, scan mangled names for names of namespaces. (add_partial_namespace): Add NAMESPACE argument; generate partial symbols associated to namespaces. (add_partial_enumeration): Add NAMESPACE argument. (new_symbol): Allow namespace syms. (read_namespace): Generate namespace syms. * objfiles.h: Add opaque declaration of struct symtab. (struct objfile): Add cp_namespace_symtab member. * objfiles.c (allocate_objfile): Set objfile->cp_namespace_symtab. * Makefile.in (cp-namespace.o): Depend on objfiles_h, gdbtypes_h, dictionary_h, command_h. 2003-09-11 David Carlton <carlton@kealia.com> * gdb.c++/namespace.exp: Add tests for namespace types. * gdb.c++/maint.exp (test_help): Test 'help maint cp namespace'. (test_namespace): New.
This commit is contained in:
parent
33a7c2fc4d
commit
5c4e30cabe
21 changed files with 589 additions and 79 deletions
|
@ -1,3 +1,51 @@
|
|||
2003-09-11 David Carlton <carlton@kealia.com>
|
||||
|
||||
* gdbtypes.h: Add TYPE_CODE_NAMESPACE.
|
||||
* gdbtypes.c (init_type): Handle TYPE_CODE_NAMESPACE.
|
||||
(recursive_dump_type): Ditto.
|
||||
* printcmd.c (print_formatted): Ditto.
|
||||
* typeprint.c (print_type_scalar): Ditto.
|
||||
* c-typeprint.c (c_type_print_varspec_prefix): Ditto.
|
||||
(c_type_print_varspec_suffix, c_type_print_base): Ditto.
|
||||
* cp-support.h: Declare cp_check_possible_namespace_symbols,
|
||||
maint_cplus_cmd_list.
|
||||
* cp-support.c: Make maint_cplus_cmd_list extern.
|
||||
* cp-namespace.c: Include objfiles.h, gdbtypes.h, dictionary.h,
|
||||
command.h.
|
||||
(lookup_symbol_file): Look in possible namespace blocks when
|
||||
appropriate.
|
||||
(initialize_namespace_symtab): New.
|
||||
(get_possible_namespace_block, free_namespace_block)
|
||||
(check_possible_namespace_symbols)
|
||||
(check_possible_namespace_symbols_loop)
|
||||
(check_one_possible_namespace_symbol)
|
||||
(lookup_possible_namespace_symbol, maintenance_cplus_namespace)
|
||||
(_initialize_cp_namespace): Ditto.
|
||||
* block.h: Declare allocate_block.
|
||||
* block.c (allocate_block): New.
|
||||
* jv-lang.c (get_java_class_symtab): Allocate blocks via
|
||||
allocate_block.
|
||||
* symfile.h: Update declaration of add_psymbol_to_list.
|
||||
* symfile.c (add_psymbol_to_list): Return the partial symbol in
|
||||
question.
|
||||
* dwarf2read.c (dwarf2_build_psymtabs_hard): Add argument to
|
||||
scan_partial_symbols_call.
|
||||
(scan_partial_symbols): Add NAMESPACE argument; update calls to
|
||||
helper functions.
|
||||
(add_partial_symbol): If necessary, scan mangled names for names
|
||||
of namespaces.
|
||||
(add_partial_namespace): Add NAMESPACE argument; generate partial
|
||||
symbols associated to namespaces.
|
||||
(add_partial_enumeration): Add NAMESPACE argument.
|
||||
(new_symbol): Allow namespace syms.
|
||||
(read_namespace): Generate namespace syms.
|
||||
* objfiles.h: Add opaque declaration of struct symtab.
|
||||
(struct objfile): Add cp_namespace_symtab member.
|
||||
* objfiles.c (allocate_objfile): Set
|
||||
objfile->cp_namespace_symtab.
|
||||
* Makefile.in (cp-namespace.o): Depend on objfiles_h, gdbtypes_h,
|
||||
dictionary_h, command_h.
|
||||
|
||||
2003-09-11 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* rs6000-tdep.c (rs6000_push_dummy_call): Use
|
||||
|
|
|
@ -1657,7 +1657,8 @@ core-sol2.o: core-sol2.c $(defs_h) $(gdb_string_h) $(regcache_h) \
|
|||
cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) $(gdbcmd_h) \
|
||||
$(ui_out_h) $(gdb_string_h)
|
||||
cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_h) \
|
||||
$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h)
|
||||
$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h) $(objfiles_h) \
|
||||
$(gdbtypes_h) $(dictionary_h) $(command_h)
|
||||
cp-support.o: cp-support.c $(defs_h) $(cp_support_h) $(gdb_string_h) \
|
||||
$(demangle_h) $(gdb_assert_h) $(gdbcmd_h) $(dictionary_h) \
|
||||
$(objfiles_h) $(frame_h) $(symtab_h) $(block_h) $(complaints_h)
|
||||
|
|
25
gdb/block.c
25
gdb/block.c
|
@ -268,3 +268,28 @@ block_global_block (const struct block *block)
|
|||
|
||||
return block;
|
||||
}
|
||||
|
||||
/* Allocate a block on OBSTACK, and initialize its elements to
|
||||
zero/NULL. This is useful for creating "dummy" blocks that don't
|
||||
correspond to actual source files.
|
||||
|
||||
Warning: it sets the block's BLOCK_DICT to NULL, which isn't a
|
||||
valid value. If you really don't want the block to have a
|
||||
dictionary, then you should subsequently set its BLOCK_DICT to
|
||||
dict_create_linear (obstack, NULL). */
|
||||
|
||||
struct block *
|
||||
allocate_block (struct obstack *obstack)
|
||||
{
|
||||
struct block *bl = obstack_alloc (obstack, sizeof (struct block));
|
||||
|
||||
BLOCK_START (bl) = 0;
|
||||
BLOCK_END (bl) = 0;
|
||||
BLOCK_FUNCTION (bl) = NULL;
|
||||
BLOCK_SUPERBLOCK (bl) = NULL;
|
||||
BLOCK_DICT (bl) = NULL;
|
||||
BLOCK_NAMESPACE (bl) = NULL;
|
||||
BLOCK_GCC_COMPILED (bl) = 0;
|
||||
|
||||
return bl;
|
||||
}
|
||||
|
|
|
@ -171,4 +171,6 @@ extern const struct block *block_static_block (const struct block *block);
|
|||
|
||||
extern const struct block *block_global_block (const struct block *block);
|
||||
|
||||
extern struct block *allocate_block (struct obstack *obstack);
|
||||
|
||||
#endif /* BLOCK_H */
|
||||
|
|
|
@ -284,6 +284,7 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
|
|||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TEMPLATE:
|
||||
case TYPE_CODE_NAMESPACE:
|
||||
/* These types need no prefix. They are listed here so that
|
||||
gcc -Wall will reveal any types that haven't been handled. */
|
||||
break;
|
||||
|
@ -624,6 +625,7 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
|
|||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TEMPLATE:
|
||||
case TYPE_CODE_NAMESPACE:
|
||||
/* These types do not need a suffix. They are listed so that
|
||||
gcc -Wall will report types that may not have been considered. */
|
||||
break;
|
||||
|
@ -1182,6 +1184,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
|||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_NAMESPACE:
|
||||
fputs_filtered ("namespace ", stream);
|
||||
fputs_filtered (TYPE_TAG_NAME (type), stream);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Handle types not explicitly handled by the other cases,
|
||||
such as fundamental types. For these, just print whatever
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#include "symfile.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "block.h"
|
||||
#include "objfiles.h"
|
||||
#include "gdbtypes.h"
|
||||
#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
|
||||
|
@ -70,6 +74,26 @@ static struct symbol *lookup_symbol_file (const char *name,
|
|||
struct symtab **symtab,
|
||||
int anonymous_namespace);
|
||||
|
||||
static void initialize_namespace_symtab (struct objfile *objfile);
|
||||
|
||||
static struct block *get_possible_namespace_block (struct objfile *objfile);
|
||||
|
||||
static void free_namespace_block (struct symtab *symtab);
|
||||
|
||||
static int check_possible_namespace_symbols_loop (const char *name,
|
||||
int len,
|
||||
struct objfile *objfile);
|
||||
|
||||
static int check_one_possible_namespace_symbol (const char *name,
|
||||
int len,
|
||||
struct objfile *objfile);
|
||||
|
||||
static
|
||||
struct symbol *lookup_possible_namespace_symbol (const char *name,
|
||||
struct symtab **symtab);
|
||||
|
||||
static void maintenance_cplus_namespace (char *args, int from_tty);
|
||||
|
||||
/* Set up support for dealing with C++ namespace info in the current
|
||||
symtab. */
|
||||
|
||||
|
@ -453,13 +477,277 @@ lookup_symbol_file (const char *name,
|
|||
const struct block *global_block = block_global_block (block);
|
||||
|
||||
if (global_block != NULL)
|
||||
return lookup_symbol_aux_block (name, linkage_name, global_block,
|
||||
sym = lookup_symbol_aux_block (name, linkage_name, global_block,
|
||||
domain, symtab);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lookup_symbol_global (name, linkage_name, domain, symtab);
|
||||
sym = lookup_symbol_global (name, linkage_name, domain, symtab);
|
||||
}
|
||||
|
||||
if (sym != NULL)
|
||||
return sym;
|
||||
|
||||
/* Now call "lookup_possible_namespace_symbol". Symbols in here
|
||||
claim to be associated to namespaces, but this claim might be
|
||||
incorrect: the names in question might actually correspond to
|
||||
classes instead of namespaces. But if they correspond to
|
||||
classes, then we should have found a match for them above. So if
|
||||
we find them now, they should be genuine. */
|
||||
|
||||
/* FIXME: carlton/2003-06-12: This is a hack and should eventually
|
||||
be deleted: see comments below. */
|
||||
|
||||
if (domain == VAR_DOMAIN)
|
||||
{
|
||||
sym = lookup_possible_namespace_symbol (name, symtab);
|
||||
if (sym != NULL)
|
||||
return sym;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now come functions for dealing with symbols associated to
|
||||
namespaces. (They're used to store the namespaces themselves, not
|
||||
objects that live in the namespaces.) These symbols come in two
|
||||
varieties: if we run into a DW_TAG_namespace DIE, then we know that
|
||||
we have a namespace, so dwarf2read.c creates a symbol for it just
|
||||
like normal. But, unfortunately, versions of GCC through at least
|
||||
3.3 don't generate those DIE's. Our solution is to try to guess
|
||||
their existence by looking at demangled names. This might cause us
|
||||
to misidentify classes as namespaces, however. So we put those
|
||||
symbols in a special block (one per objfile), and we only search
|
||||
that block as a last resort. */
|
||||
|
||||
/* FIXME: carlton/2003-06-12: Once versions of GCC that generate
|
||||
DW_TAG_namespace have been out for a year or two, we should get rid
|
||||
of all of this "possible namespace" nonsense. */
|
||||
|
||||
/* Allocate everything necessary for the possible namespace block
|
||||
associated to OBJFILE. */
|
||||
|
||||
static void
|
||||
initialize_namespace_symtab (struct objfile *objfile)
|
||||
{
|
||||
struct symtab *namespace_symtab;
|
||||
struct blockvector *bv;
|
||||
struct block *bl;
|
||||
|
||||
namespace_symtab = allocate_symtab ("<<C++-namespaces>>", objfile);
|
||||
namespace_symtab->language = language_cplus;
|
||||
namespace_symtab->free_code = free_nothing;
|
||||
namespace_symtab->dirname = NULL;
|
||||
|
||||
bv = obstack_alloc (&objfile->symbol_obstack,
|
||||
sizeof (struct blockvector)
|
||||
+ FIRST_LOCAL_BLOCK * sizeof (struct block *));
|
||||
BLOCKVECTOR_NBLOCKS (bv) = FIRST_LOCAL_BLOCK + 1;
|
||||
BLOCKVECTOR (namespace_symtab) = bv;
|
||||
|
||||
/* Allocate empty GLOBAL_BLOCK and STATIC_BLOCK. */
|
||||
|
||||
bl = allocate_block (&objfile->symbol_obstack);
|
||||
BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
|
||||
NULL);
|
||||
BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
|
||||
bl = allocate_block (&objfile->symbol_obstack);
|
||||
BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
|
||||
NULL);
|
||||
BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
|
||||
|
||||
/* Allocate the possible namespace block; we put it where the first
|
||||
local block will live, though I don't think there's any need to
|
||||
pretend that it's actually a local block (e.g. by setting
|
||||
BLOCK_SUPERBLOCK appropriately). We don't use the global or
|
||||
static block because we don't want it searched during the normal
|
||||
search of all global/static blocks in lookup_symbol: we only want
|
||||
it used as a last resort. */
|
||||
|
||||
/* NOTE: carlton/2003-09-11: I considered not associating the fake
|
||||
symbols to a block/symtab at all. But that would cause problems
|
||||
with lookup_symbol's SYMTAB argument and with block_found, so
|
||||
having a symtab/block for this purpose seems like the best
|
||||
solution for now. */
|
||||
|
||||
bl = allocate_block (&objfile->symbol_obstack);
|
||||
BLOCK_DICT (bl) = dict_create_hashed_expandable ();
|
||||
BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK) = bl;
|
||||
|
||||
namespace_symtab->free_func = free_namespace_block;
|
||||
|
||||
objfile->cp_namespace_symtab = namespace_symtab;
|
||||
}
|
||||
|
||||
/* Locate the possible namespace block associated to OBJFILE,
|
||||
allocating it if necessary. */
|
||||
|
||||
static struct block *
|
||||
get_possible_namespace_block (struct objfile *objfile)
|
||||
{
|
||||
if (objfile->cp_namespace_symtab == NULL)
|
||||
initialize_namespace_symtab (objfile);
|
||||
|
||||
return BLOCKVECTOR_BLOCK (BLOCKVECTOR (objfile->cp_namespace_symtab),
|
||||
FIRST_LOCAL_BLOCK);
|
||||
}
|
||||
|
||||
/* Free the dictionary associated to the possible namespace block. */
|
||||
|
||||
static void
|
||||
free_namespace_block (struct symtab *symtab)
|
||||
{
|
||||
struct block *possible_namespace_block;
|
||||
|
||||
possible_namespace_block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
|
||||
FIRST_LOCAL_BLOCK);
|
||||
gdb_assert (possible_namespace_block != NULL);
|
||||
dict_free (BLOCK_DICT (possible_namespace_block));
|
||||
}
|
||||
|
||||
/* Ensure that there are symbols in the possible namespace block
|
||||
associated to OBJFILE for all initial substrings of NAME that look
|
||||
like namespaces or classes. NAME should end in a member variable:
|
||||
it shouldn't consist solely of namespaces. */
|
||||
|
||||
void
|
||||
cp_check_possible_namespace_symbols (const char *name, struct objfile *objfile)
|
||||
{
|
||||
check_possible_namespace_symbols_loop (name,
|
||||
cp_find_first_component (name),
|
||||
objfile);
|
||||
}
|
||||
|
||||
/* This is a helper loop for cp_check_possible_namespace_symbols; it
|
||||
ensures that there are symbols in the possible namespace block
|
||||
associated to OBJFILE for all namespaces that are initial
|
||||
substrings of NAME of length at least LEN. It returns 1 if a
|
||||
previous loop had already created the shortest such symbol and 0
|
||||
otherwise.
|
||||
|
||||
This function assumes that if there is already a symbol associated
|
||||
to a substring of NAME of a given length, then there are already
|
||||
symbols associated to all substrings of NAME whose length is less
|
||||
than that length. So if cp_check_possible_namespace_symbols has
|
||||
been called once with argument "A::B::C::member", then that will
|
||||
create symbols "A", "A::B", and "A::B::C". If it is then later
|
||||
called with argument "A::B::D::member", then the new call will
|
||||
generate a new symbol for "A::B::D", but once it sees that "A::B"
|
||||
has already been created, it doesn't bother checking to see if "A"
|
||||
has also been created. */
|
||||
|
||||
static int
|
||||
check_possible_namespace_symbols_loop (const char *name, int len,
|
||||
struct objfile *objfile)
|
||||
{
|
||||
if (name[len] == ':')
|
||||
{
|
||||
int done;
|
||||
int next_len = len + 2;
|
||||
|
||||
next_len += cp_find_first_component (name + next_len);
|
||||
done = check_possible_namespace_symbols_loop (name, next_len,
|
||||
objfile);
|
||||
|
||||
if (!done)
|
||||
done = check_one_possible_namespace_symbol (name, len, objfile);
|
||||
|
||||
return done;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check to see if there's already a possible namespace symbol in
|
||||
OBJFILE whose name is the initial substring of NAME of length LEN.
|
||||
If not, create one and return 0; otherwise, return 1. */
|
||||
|
||||
static int
|
||||
check_one_possible_namespace_symbol (const char *name, int len,
|
||||
struct objfile *objfile)
|
||||
{
|
||||
struct block *block = get_possible_namespace_block (objfile);
|
||||
char *name_copy = obsavestring (name, len, &objfile->symbol_obstack);
|
||||
struct symbol *sym = lookup_block_symbol (block, name_copy, NULL,
|
||||
VAR_DOMAIN);
|
||||
|
||||
if (sym == NULL)
|
||||
{
|
||||
struct type *type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
|
||||
name_copy, objfile);
|
||||
TYPE_TAG_NAME (type) = TYPE_NAME (type);
|
||||
|
||||
sym = obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
|
||||
memset (sym, 0, sizeof (struct symbol));
|
||||
SYMBOL_LANGUAGE (sym) = language_cplus;
|
||||
SYMBOL_SET_NAMES (sym, name_copy, len, objfile);
|
||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||
SYMBOL_TYPE (sym) = type;
|
||||
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
||||
|
||||
dict_add_symbol (BLOCK_DICT (block), sym);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
obstack_free (&objfile->symbol_obstack, name_copy);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for a symbol named NAME in all the possible namespace blocks.
|
||||
If one is found, return it; if SYMTAB is non-NULL, set *SYMTAB to
|
||||
equal the symtab where it was found. */
|
||||
|
||||
static struct symbol *
|
||||
lookup_possible_namespace_symbol (const char *name, struct symtab **symtab)
|
||||
{
|
||||
struct objfile *objfile;
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
struct symbol *sym;
|
||||
|
||||
sym = lookup_block_symbol (get_possible_namespace_block (objfile),
|
||||
name, NULL, VAR_DOMAIN);
|
||||
|
||||
if (sym != NULL)
|
||||
{
|
||||
if (symtab != NULL)
|
||||
*symtab = objfile->cp_namespace_symtab;
|
||||
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Print out all the possible namespace symbols. */
|
||||
|
||||
static void
|
||||
maintenance_cplus_namespace (char *args, int from_tty)
|
||||
{
|
||||
struct objfile *objfile;
|
||||
printf_unfiltered ("Possible namespaces:\n");
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
struct dict_iterator iter;
|
||||
struct symbol *sym;
|
||||
|
||||
ALL_BLOCK_SYMBOLS (get_possible_namespace_block (objfile), iter, sym)
|
||||
{
|
||||
printf_unfiltered ("%s\n", SYMBOL_PRINT_NAME (sym));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_cp_namespace (void)
|
||||
{
|
||||
add_cmd ("namespace", class_maintenance, maintenance_cplus_namespace,
|
||||
"Print the list of possible C++ namespaces.",
|
||||
&maint_cplus_cmd_list);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
|
|||
|
||||
/* The list of "maint cplus" commands. */
|
||||
|
||||
static struct cmd_list_element *maint_cplus_cmd_list = NULL;
|
||||
struct cmd_list_element *maint_cplus_cmd_list = NULL;
|
||||
|
||||
/* The actual commands. */
|
||||
|
||||
|
|
|
@ -96,4 +96,11 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
|
|||
const domain_enum domain,
|
||||
struct symtab **symtab);
|
||||
|
||||
extern void cp_check_possible_namespace_symbols (const char *name,
|
||||
struct objfile *objfile);
|
||||
|
||||
/* The list of "maint cplus" commands. */
|
||||
|
||||
extern struct cmd_list_element *maint_cplus_cmd_list;
|
||||
|
||||
#endif /* CP_SUPPORT_H */
|
||||
|
|
148
gdb/dwarf2read.c
148
gdb/dwarf2read.c
|
@ -672,21 +672,25 @@ static void dwarf2_build_psymtabs_hard (struct objfile *, int);
|
|||
|
||||
static char *scan_partial_symbols (char *, struct objfile *,
|
||||
CORE_ADDR *, CORE_ADDR *,
|
||||
const struct comp_unit_head *);
|
||||
const struct comp_unit_head *,
|
||||
const char *namespace);
|
||||
|
||||
static void add_partial_symbol (struct partial_die_info *, struct objfile *,
|
||||
const struct comp_unit_head *);
|
||||
const struct comp_unit_head *,
|
||||
const char *namespace);
|
||||
|
||||
static char *add_partial_namespace (struct partial_die_info *pdi,
|
||||
char *info_ptr,
|
||||
struct objfile *objfile,
|
||||
CORE_ADDR *lowpc, CORE_ADDR *highpc,
|
||||
const struct comp_unit_head *cu_header);
|
||||
const struct comp_unit_head *cu_header,
|
||||
const char *namespace);
|
||||
|
||||
static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
|
||||
char *info_ptr,
|
||||
struct objfile *objfile,
|
||||
const struct comp_unit_head *cu_header);
|
||||
const struct comp_unit_head *cu_header,
|
||||
const char *namespace);
|
||||
|
||||
static char *locate_pdi_sibling (struct partial_die_info *orig_pdi,
|
||||
char *info_ptr,
|
||||
|
@ -1341,7 +1345,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
|
|||
highpc = ((CORE_ADDR) 0);
|
||||
|
||||
info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc,
|
||||
&cu_header);
|
||||
&cu_header, NULL);
|
||||
|
||||
/* If we didn't find a lowpc, set it to highpc to avoid
|
||||
complaints from `maint check'. */
|
||||
|
@ -1377,12 +1381,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
|
|||
}
|
||||
|
||||
/* Read in all interesting dies to the end of the compilation unit or
|
||||
to the end of the current namespace. */
|
||||
to the end of the current namespace. NAMESPACE is NULL if we
|
||||
haven't yet encountered any DW_TAG_namespace entries; otherwise,
|
||||
it's the name of the current namespace. In particular, it's the
|
||||
empty string if we're currently in the global namespace but have
|
||||
previously encountered a DW_TAG_namespace. */
|
||||
|
||||
static char *
|
||||
scan_partial_symbols (char *info_ptr, struct objfile *objfile,
|
||||
CORE_ADDR *lowpc, CORE_ADDR *highpc,
|
||||
const struct comp_unit_head *cu_header)
|
||||
const struct comp_unit_head *cu_header,
|
||||
const char *namespace)
|
||||
{
|
||||
bfd *abfd = objfile->obfd;
|
||||
struct partial_die_info pdi;
|
||||
|
@ -1421,7 +1430,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
|
|||
}
|
||||
if (!pdi.is_declaration)
|
||||
{
|
||||
add_partial_symbol (&pdi, objfile, cu_header);
|
||||
add_partial_symbol (&pdi, objfile, cu_header, namespace);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1432,25 +1441,32 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
|
|||
case DW_TAG_structure_type:
|
||||
if (!pdi.is_declaration)
|
||||
{
|
||||
add_partial_symbol (&pdi, objfile, cu_header);
|
||||
add_partial_symbol (&pdi, objfile, cu_header, namespace);
|
||||
}
|
||||
break;
|
||||
case DW_TAG_enumeration_type:
|
||||
if (!pdi.is_declaration)
|
||||
{
|
||||
info_ptr = add_partial_enumeration (&pdi, info_ptr,
|
||||
objfile, cu_header);
|
||||
objfile, cu_header,
|
||||
namespace);
|
||||
info_ptr_updated = 1;
|
||||
}
|
||||
break;
|
||||
case DW_TAG_base_type:
|
||||
/* File scope base type definitions are added to the partial
|
||||
symbol table. */
|
||||
add_partial_symbol (&pdi, objfile, cu_header);
|
||||
add_partial_symbol (&pdi, objfile, cu_header, namespace);
|
||||
break;
|
||||
case DW_TAG_namespace:
|
||||
/* We've hit a DW_TAG_namespace entry, so we know this
|
||||
file has been compiled using a compiler that
|
||||
generates them; update NAMESPACE to reflect that. */
|
||||
if (namespace == NULL)
|
||||
namespace = "";
|
||||
info_ptr = add_partial_namespace (&pdi, info_ptr, objfile,
|
||||
lowpc, highpc, cu_header);
|
||||
lowpc, highpc, cu_header,
|
||||
namespace);
|
||||
info_ptr_updated = 1;
|
||||
break;
|
||||
default:
|
||||
|
@ -1478,9 +1494,11 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
|
|||
|
||||
static void
|
||||
add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
|
||||
const struct comp_unit_head *cu_header)
|
||||
const struct comp_unit_head *cu_header,
|
||||
const char *namespace)
|
||||
{
|
||||
CORE_ADDR addr = 0;
|
||||
const struct partial_symbol *psym = NULL;
|
||||
|
||||
switch (pdi->tag)
|
||||
{
|
||||
|
@ -1489,19 +1507,21 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
|
|||
{
|
||||
/*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
|
||||
mst_text, objfile); */
|
||||
add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
VAR_DOMAIN, LOC_BLOCK,
|
||||
&objfile->global_psymbols,
|
||||
0, pdi->lowpc + baseaddr, cu_language, objfile);
|
||||
0, pdi->lowpc + baseaddr,
|
||||
cu_language, objfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
|
||||
mst_file_text, objfile); */
|
||||
add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
VAR_DOMAIN, LOC_BLOCK,
|
||||
&objfile->static_psymbols,
|
||||
0, pdi->lowpc + baseaddr, cu_language, objfile);
|
||||
0, pdi->lowpc + baseaddr,
|
||||
cu_language, objfile);
|
||||
}
|
||||
break;
|
||||
case DW_TAG_variable:
|
||||
|
@ -1523,10 +1543,11 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
|
|||
if (pdi->locdesc)
|
||||
addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
|
||||
if (pdi->locdesc || pdi->has_type)
|
||||
add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
VAR_DOMAIN, LOC_STATIC,
|
||||
&objfile->global_psymbols,
|
||||
0, addr + baseaddr, cu_language, objfile);
|
||||
0, addr + baseaddr,
|
||||
cu_language, objfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1536,10 +1557,11 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
|
|||
addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
|
||||
/*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
|
||||
mst_file_data, objfile); */
|
||||
add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
psym = add_psymbol_to_list (pdi->name, strlen (pdi->name),
|
||||
VAR_DOMAIN, LOC_STATIC,
|
||||
&objfile->static_psymbols,
|
||||
0, addr + baseaddr, cu_language, objfile);
|
||||
0, addr + baseaddr,
|
||||
cu_language, objfile);
|
||||
}
|
||||
break;
|
||||
case DW_TAG_typedef:
|
||||
|
@ -1580,22 +1602,60 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check to see if we should scan the name for possible namespace
|
||||
info. Only do this if this is C++, if we don't have namespace
|
||||
debugging info in the file, if the psym is of an appropriate type
|
||||
(otherwise we'll have psym == NULL), and if we actually had a
|
||||
mangled name to begin with. */
|
||||
|
||||
if (cu_language == language_cplus
|
||||
&& namespace == NULL
|
||||
&& psym != NULL
|
||||
&& SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
|
||||
cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
|
||||
objfile);
|
||||
}
|
||||
|
||||
/* Read a partial die corresponding to a namespace. For now, we don't
|
||||
do anything with the fact that we're in a namespace; we just read
|
||||
the symbols inside of it. */
|
||||
/* Read a partial die corresponding to a namespace; also, add a symbol
|
||||
corresponding to that namespace to the symbol table. NAMESPACE is
|
||||
the name of the enclosing namespace. */
|
||||
|
||||
static char *
|
||||
add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
|
||||
struct objfile *objfile,
|
||||
CORE_ADDR *lowpc, CORE_ADDR *highpc,
|
||||
const struct comp_unit_head *cu_header)
|
||||
const struct comp_unit_head *cu_header,
|
||||
const char *namespace)
|
||||
{
|
||||
/* Calculate the full name of the namespace that we just entered. */
|
||||
|
||||
const char *new_name = pdi->name;
|
||||
char *full_name;
|
||||
|
||||
if (new_name == NULL)
|
||||
new_name = "(anonymous namespace)";
|
||||
full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1);
|
||||
strcpy (full_name, namespace);
|
||||
if (*namespace != '\0')
|
||||
strcat (full_name, "::");
|
||||
strcat (full_name, new_name);
|
||||
|
||||
/* FIXME: carlton/2003-06-27: Once we build qualified names for more
|
||||
symbols than just namespaces, we should replace this by a call to
|
||||
add_partial_symbol. */
|
||||
|
||||
add_psymbol_to_list (full_name, strlen (full_name),
|
||||
VAR_DOMAIN, LOC_TYPEDEF,
|
||||
&objfile->global_psymbols,
|
||||
0, 0, cu_language, objfile);
|
||||
|
||||
/* Now scan partial symbols in that namespace. */
|
||||
|
||||
if (pdi->has_children)
|
||||
info_ptr = scan_partial_symbols (info_ptr, objfile,
|
||||
lowpc, highpc,
|
||||
cu_header);
|
||||
cu_header, full_name);
|
||||
|
||||
return info_ptr;
|
||||
}
|
||||
|
@ -1605,13 +1665,14 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr,
|
|||
static char *
|
||||
add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
|
||||
struct objfile *objfile,
|
||||
const struct comp_unit_head *cu_header)
|
||||
const struct comp_unit_head *cu_header,
|
||||
const char *namespace)
|
||||
{
|
||||
bfd *abfd = objfile->obfd;
|
||||
struct partial_die_info pdi;
|
||||
|
||||
if (enum_pdi->name != NULL)
|
||||
add_partial_symbol (enum_pdi, objfile, cu_header);
|
||||
add_partial_symbol (enum_pdi, objfile, cu_header, namespace);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -1621,7 +1682,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr,
|
|||
if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL)
|
||||
complaint (&symfile_complaints, "malformed enumerator DIE ignored");
|
||||
else
|
||||
add_partial_symbol (&pdi, objfile, cu_header);
|
||||
add_partial_symbol (&pdi, objfile, cu_header, namespace);
|
||||
}
|
||||
|
||||
return info_ptr;
|
||||
|
@ -3314,13 +3375,28 @@ read_namespace (struct die_info *die, struct objfile *objfile,
|
|||
processing_current_namespace = temp_name;
|
||||
}
|
||||
|
||||
/* If it's an anonymous namespace that we're seeing for the first
|
||||
time, add a using directive. */
|
||||
/* Add a symbol associated to this if we haven't seen the namespace
|
||||
before. Also, add a using directive if it's an anonymous
|
||||
namespace. */
|
||||
|
||||
if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
|
||||
if (dwarf2_extension (die) == NULL)
|
||||
{
|
||||
struct type *type;
|
||||
|
||||
/* FIXME: carlton/2003-06-27: Once GDB is more const-correct,
|
||||
this cast will hopefully become unnecessary. */
|
||||
type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
|
||||
(char *) processing_current_namespace,
|
||||
objfile);
|
||||
TYPE_TAG_NAME (type) = TYPE_NAME (type);
|
||||
|
||||
new_symbol (die, type, objfile, cu_header);
|
||||
|
||||
if (is_anonymous)
|
||||
cp_add_using_directive (processing_current_namespace,
|
||||
strlen (previous_namespace),
|
||||
strlen (processing_current_namespace));
|
||||
}
|
||||
|
||||
if (die->has_children)
|
||||
{
|
||||
|
@ -5175,7 +5251,11 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
|
|||
struct attribute *attr2 = NULL;
|
||||
CORE_ADDR addr = 0;
|
||||
|
||||
if (die->tag != DW_TAG_namespace)
|
||||
name = dwarf2_linkage_name (die);
|
||||
else
|
||||
name = TYPE_NAME (type);
|
||||
|
||||
if (name)
|
||||
{
|
||||
sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
|
||||
|
@ -5332,6 +5412,10 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
|
|||
}
|
||||
add_symbol_to_list (sym, list_in_scope);
|
||||
break;
|
||||
case DW_TAG_namespace:
|
||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||
add_symbol_to_list (sym, &global_symbols);
|
||||
break;
|
||||
default:
|
||||
/* Not a tag we recognize. Hopefully we aren't processing
|
||||
trash data, but since we must specifically ignore things
|
||||
|
|
|
@ -1897,7 +1897,8 @@ init_type (enum type_code code, int length, int flags, char *name,
|
|||
if (name && strcmp (name, "char") == 0)
|
||||
TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN;
|
||||
|
||||
if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
|
||||
if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION
|
||||
|| code == TYPE_CODE_NAMESPACE)
|
||||
{
|
||||
INIT_CPLUS_SPECIFIC (type);
|
||||
}
|
||||
|
@ -3145,6 +3146,9 @@ recursive_dump_type (struct type *type, int spaces)
|
|||
case TYPE_CODE_TEMPLATE_ARG:
|
||||
printf_filtered ("(TYPE_CODE_TEMPLATE_ARG)");
|
||||
break;
|
||||
case TYPE_CODE_NAMESPACE:
|
||||
printf_filtered ("(TYPE_CODE_NAMESPACE)");
|
||||
break;
|
||||
default:
|
||||
printf_filtered ("(UNKNOWN TYPE CODE)");
|
||||
break;
|
||||
|
|
|
@ -134,8 +134,9 @@ enum type_code
|
|||
|
||||
TYPE_CODE_TYPEDEF,
|
||||
TYPE_CODE_TEMPLATE, /* C++ template */
|
||||
TYPE_CODE_TEMPLATE_ARG /* C++ template arg */
|
||||
TYPE_CODE_TEMPLATE_ARG, /* C++ template arg */
|
||||
|
||||
TYPE_CODE_NAMESPACE, /* C++ namespace. */
|
||||
};
|
||||
|
||||
/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
|
||||
|
|
|
@ -111,22 +111,13 @@ get_java_class_symtab (void)
|
|||
BLOCKVECTOR (class_symtab) = bv;
|
||||
|
||||
/* Allocate dummy STATIC_BLOCK. */
|
||||
bl = (struct block *)
|
||||
obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
|
||||
bl = allocate_block (&objfile->symbol_obstack);
|
||||
BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
|
||||
NULL);
|
||||
BLOCK_START (bl) = 0;
|
||||
BLOCK_END (bl) = 0;
|
||||
BLOCK_FUNCTION (bl) = NULL;
|
||||
BLOCK_SUPERBLOCK (bl) = NULL;
|
||||
BLOCK_NAMESPACE (bl) = NULL;
|
||||
BLOCK_GCC_COMPILED (bl) = 0;
|
||||
BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
|
||||
|
||||
/* Allocate GLOBAL_BLOCK. This has to be relocatable. */
|
||||
bl = (struct block *)
|
||||
obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
|
||||
*bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
|
||||
/* Allocate GLOBAL_BLOCK. */
|
||||
bl = allocate_block (&objfile->symbol_obstack);
|
||||
BLOCK_DICT (bl) = dict_create_hashed_expandable ();
|
||||
BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
|
||||
class_symtab->free_func = free_class_block;
|
||||
|
|
|
@ -343,6 +343,10 @@ allocate_objfile (bfd *abfd, int flags)
|
|||
objfile->sect_index_bss = -1;
|
||||
objfile->sect_index_rodata = -1;
|
||||
|
||||
/* We don't yet have a C++-specific namespace symtab. */
|
||||
|
||||
objfile->cp_namespace_symtab = NULL;
|
||||
|
||||
/* Add this file onto the tail of the linked list of other such files. */
|
||||
|
||||
objfile->next = NULL;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
struct bcache;
|
||||
struct htab;
|
||||
struct symtab;
|
||||
|
||||
/* This structure maintains information on a per-objfile basis about the
|
||||
"entry point" of the objfile, and the scope within which the entry point
|
||||
|
@ -443,6 +444,13 @@ struct objfile
|
|||
|
||||
/* Place to stash various statistics about this objfile */
|
||||
OBJSTATS;
|
||||
|
||||
/* A symtab that the C++ code uses to stash special symbols
|
||||
associated to namespaces. */
|
||||
|
||||
/* FIXME/carlton-2003-06-27: Delete this in a few years once
|
||||
"possible namespace symbols" go away. */
|
||||
struct symtab *cp_namespace_symtab;
|
||||
};
|
||||
|
||||
/* Defines for the objfile flag word. */
|
||||
|
|
|
@ -315,7 +315,8 @@ print_formatted (struct value *val, register int format, int size,
|
|||
|| TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
|| TYPE_CODE (type) == TYPE_CODE_STRING
|
||||
|| TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (type) == TYPE_CODE_UNION)
|
||||
|| TYPE_CODE (type) == TYPE_CODE_UNION
|
||||
|| TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
|
||||
/* If format is 0, use the 'natural' format for
|
||||
* that type of value. If the type is non-scalar,
|
||||
* we have to use language rules to print it as
|
||||
|
|
|
@ -2632,9 +2632,21 @@ start_psymtab_common (struct objfile *objfile,
|
|||
}
|
||||
|
||||
/* Add a symbol with a long value to a psymtab.
|
||||
Since one arg is a struct, we pass in a ptr and deref it (sigh). */
|
||||
Since one arg is a struct, we pass in a ptr and deref it (sigh).
|
||||
Return the partial symbol that has been added. */
|
||||
|
||||
void
|
||||
/* NOTE: carlton/2003-09-11: The reason why we return the partial
|
||||
symbol is so that callers can get access to the symbol's demangled
|
||||
name, which they don't have any cheap way to determine otherwise.
|
||||
(Currenly, dwarf2read.c is the only file who uses that information,
|
||||
though it's possible that other readers might in the future.)
|
||||
Elena wasn't thrilled about that, and I don't blame her, but we
|
||||
couldn't come up with a better way to get that information. If
|
||||
it's needed in other situations, we could consider breaking up
|
||||
SYMBOL_SET_NAMES to provide access to the demangled name lookup
|
||||
cache. */
|
||||
|
||||
const struct partial_symbol *
|
||||
add_psymbol_to_list (char *name, int namelength, domain_enum domain,
|
||||
enum address_class class,
|
||||
struct psymbol_allocation_list *list, long val, /* Value as a long */
|
||||
|
@ -2677,6 +2689,8 @@ add_psymbol_to_list (char *name, int namelength, domain_enum domain,
|
|||
}
|
||||
*list->next++ = psym;
|
||||
OBJSTAT (objfile, n_psyms++);
|
||||
|
||||
return psym;
|
||||
}
|
||||
|
||||
/* Add a symbol with a long value to a psymtab. This differs from
|
||||
|
|
|
@ -152,9 +152,12 @@ extern void extend_psymbol_list (struct psymbol_allocation_list *,
|
|||
|
||||
/* #include "demangle.h" */
|
||||
|
||||
extern void add_psymbol_to_list (char *, int, domain_enum, enum address_class,
|
||||
struct psymbol_allocation_list *, long,
|
||||
CORE_ADDR, enum language, struct objfile *);
|
||||
extern const
|
||||
struct partial_symbol *add_psymbol_to_list (char *, int, domain_enum,
|
||||
enum address_class,
|
||||
struct psymbol_allocation_list *,
|
||||
long, CORE_ADDR,
|
||||
enum language, struct objfile *);
|
||||
|
||||
extern void add_psymbol_with_dem_name_to_list (char *, int, char *, int,
|
||||
domain_enum,
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2003-09-11 David Carlton <carlton@kealia.com>
|
||||
|
||||
* gdb.c++/namespace.exp: Add tests for namespace types.
|
||||
* gdb.c++/maint.exp (test_help): Test 'help maint cp namespace'.
|
||||
(test_namespace): New.
|
||||
|
||||
2003-09-11 Elena Zannoni <ezannoni@redhat.com>
|
||||
|
||||
* gdb.base/relocate.exp: Handle new gdb output at startup.
|
||||
|
|
|
@ -29,13 +29,19 @@ if $tracelevel then {
|
|||
# Test the help messages.
|
||||
|
||||
proc test_help {} {
|
||||
gdb_test "help maintenance cplus" "C\\+\\+ maintenance commands.\r\n\r\nList of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- Print the first class/namespace component of NAME\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
|
||||
set first_component_help "Print the first class/namespace component of NAME"
|
||||
set namespace_help "Print the list of possible C\\+\\+ namespaces"
|
||||
|
||||
gdb_test "help maint cp" "C\\+\\+ maintenance commands.\r\n\r\nList of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- Print the first class/namespace component of NAME\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
|
||||
set multiple_help_body "List of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- ${first_component_help}\r\nmaintenance cplus namespace -- ${namespace_help}\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
|
||||
|
||||
gdb_test "maint cp" "\"maintenance cplus\" must be followed by the name of a command.\r\nList of maintenance cplus subcommands:\r\n\r\nmaintenance cplus first_component -- Print the first class/namespace component of NAME\r\n\r\nType \"help maintenance cplus\" followed by maintenance cplus subcommand name for full documentation.\r\nCommand name abbreviations are allowed if unambiguous."
|
||||
set help_maint_cp "C\\+\\+ maintenance commands.\r\n\r\n${multiple_help_body}"
|
||||
|
||||
gdb_test "help maint cp first_component" "Print the first class/namespace component of NAME."
|
||||
gdb_test "help maintenance cplus" "${help_maint_cp}"
|
||||
gdb_test "help maint cp" "${help_maint_cp}"
|
||||
gdb_test "maint cp" "\"maintenance cplus\" must be followed by the name of a command.\r\n${multiple_help_body}"
|
||||
|
||||
gdb_test "help maint cp first_component" "${first_component_help}."
|
||||
gdb_test "help maint cp namespace" "${namespace_help}."
|
||||
}
|
||||
|
||||
# This is used when NAME should contain only a single component. Be
|
||||
|
@ -103,11 +109,18 @@ proc test_first_component {} {
|
|||
test_invalid_name "bool operator<<char>"
|
||||
}
|
||||
|
||||
proc test_namespace {} {
|
||||
# There's not a lot we can do to test this.
|
||||
|
||||
gdb_test "maint cp namespace" "Possible namespaces:"
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
|
||||
test_help
|
||||
test_first_component
|
||||
test_namespace
|
||||
|
||||
gdb_exit
|
||||
return 0
|
||||
|
|
|
@ -208,6 +208,8 @@ gdb_test "print cd" "\\$\[0-9\].* = 3"
|
|||
gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
|
||||
gdb_test "print shadow" "\\$\[0-9\].* = 13"
|
||||
gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
|
||||
gdb_test "ptype C" "type = namespace C::C"
|
||||
gdb_test "ptype E" "type = namespace C::D::E"
|
||||
|
||||
# Some anonymous namespace tests.
|
||||
|
||||
|
|
|
@ -307,6 +307,7 @@ print_type_scalar (struct type *type, LONGEST val, struct ui_file *stream)
|
|||
case TYPE_CODE_MEMBER:
|
||||
case TYPE_CODE_METHOD:
|
||||
case TYPE_CODE_REF:
|
||||
case TYPE_CODE_NAMESPACE:
|
||||
error ("internal error: unhandled type in print_type_scalar");
|
||||
break;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue