* Makefile.in (SFILES): Add cp-names.y.

(libiberty_h, safe_ctype_h): New.
	(YYFILES): Add cp-names.c.
	(YYOBJ): Add cp-names.o.
	(test-cp-names.o, test-cp-names$(EXEEXT), cp-names.o): New rules.
	(clean): Remove test-cp-names$(EXEEXT).
	(local-maintainer-clean): Remove cp-names.c.
	* cp-names.y: New file.
	* cp-support.c (find_last_component): Delete.
	(d_left, d_right): Define.
	(cp_canonicalize_string, mangled_name_to_comp): New functions.
	(cp_class_name_from_physname, method_name_from_physname): Rewrite
	to use mangled_name_to_comp.
	* cp-support.h (cp_canonicalize_string, cp_demangled_name_to_comp)
	(cp_comp_to_string): New prototypes.
	* config/djgpp/fnchange.lst: Add cp-names.c.
This commit is contained in:
Daniel Jacobowitz
2005-03-11 02:24:23 +00:00
parent 0fa77c953f
commit fb4c6eba43
6 changed files with 2383 additions and 120 deletions

View File

@ -1,6 +1,25 @@
2005-03-10 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (SFILES): Add cp-names.y.
(libiberty_h, safe_ctype_h): New.
(YYFILES): Add cp-names.c.
(YYOBJ): Add cp-names.o.
(test-cp-names.o, test-cp-names$(EXEEXT), cp-names.o): New rules.
(clean): Remove test-cp-names$(EXEEXT).
(local-maintainer-clean): Remove cp-names.c.
* cp-names.y: New file.
* cp-support.c (find_last_component): Delete.
(d_left, d_right): Define.
(cp_canonicalize_string, mangled_name_to_comp): New functions.
(cp_class_name_from_physname, method_name_from_physname): Rewrite
to use mangled_name_to_comp.
* cp-support.h (cp_canonicalize_string, cp_demangled_name_to_comp)
(cp_comp_to_string): New prototypes.
* config/djgpp/fnchange.lst: Add cp-names.c.
2005-03-10 Bob Rossi <bob@brasko.net> 2005-03-10 Bob Rossi <bob@brasko.net>
* main.c(print_gdb_help): remove the --[no]sync help message * main.c (print_gdb_help): Remove the --[no]async help message.
2005-03-10 Mark Kettenis <kettenis@gnu.org> 2005-03-10 Mark Kettenis <kettenis@gnu.org>

View File

@ -519,6 +519,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c \
charset.c cli-out.c coffread.c coff-pe-read.c \ charset.c cli-out.c coffread.c coff-pe-read.c \
complaints.c completer.c corefile.c \ complaints.c completer.c corefile.c \
cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \ cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \
cp-names.y \
dbxread.c demangle.c dictionary.c disasm.c doublest.c dummy-frame.c \ dbxread.c demangle.c dictionary.c disasm.c doublest.c dummy-frame.c \
dwarfread.c dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \ dwarfread.c dwarf2expr.c dwarf2loc.c dwarf2read.c dwarf2-frame.c \
elfread.c environ.c eval.c event-loop.c event-top.c expprint.c \ elfread.c environ.c eval.c event-loop.c event-top.c expprint.c \
@ -579,6 +580,7 @@ elf_arm_h = $(INCLUDE_DIR)/elf/arm.h $(elf_reloc_macros_h)
elf_bfd_h = $(BFD_SRC)/elf-bfd.h elf_bfd_h = $(BFD_SRC)/elf-bfd.h
elf_frv_h = $(INCLUDE_DIR)/elf/frv.h $(elf_reloc_macros_h) elf_frv_h = $(INCLUDE_DIR)/elf/frv.h $(elf_reloc_macros_h)
libaout_h = $(BFD_SRC)/libaout.h libaout_h = $(BFD_SRC)/libaout.h
libiberty_h = $(INCLUDE_DIR)/libiberty.h
libbfd_h = $(BFD_SRC)/libbfd.h libbfd_h = $(BFD_SRC)/libbfd.h
remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.h remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.h
demangle_h = $(INCLUDE_DIR)/demangle.h demangle_h = $(INCLUDE_DIR)/demangle.h
@ -596,6 +598,7 @@ gdb_sim_frv_h = $(INCLUDE_DIR)/gdb/sim-frv.h
gdb_sim_ppc_h = $(INCLUDE_DIR)/gdb/sim-ppc.h gdb_sim_ppc_h = $(INCLUDE_DIR)/gdb/sim-ppc.h
gdb_sim_sh_h = $(INCLUDE_DIR)/gdb/sim-sh.h gdb_sim_sh_h = $(INCLUDE_DIR)/gdb/sim-sh.h
splay_tree_h = $(INCLUDE_DIR)/splay-tree.h splay_tree_h = $(INCLUDE_DIR)/splay-tree.h
safe_ctype_h = $(INCLUDE_DIR)/safe-ctype.h
hashtab_h = $(INCLUDE_DIR)/hashtab.h hashtab_h = $(INCLUDE_DIR)/hashtab.h
# #
@ -944,11 +947,13 @@ SUBDIRS = @subdirs@
# For now, shortcut the "configure GDB for fewer languages" stuff. # For now, shortcut the "configure GDB for fewer languages" stuff.
YYFILES = c-exp.c \ YYFILES = c-exp.c \
cp-names.c \
objc-exp.c \ objc-exp.c \
ada-exp.c \ ada-exp.c \
jv-exp.c \ jv-exp.c \
f-exp.c m2-exp.c p-exp.c f-exp.c m2-exp.c p-exp.c
YYOBJ = c-exp.o \ YYOBJ = c-exp.o \
cp-names.o \
objc-exp.o \ objc-exp.o \
ada-exp.o \ ada-exp.o \
jv-exp.o \ jv-exp.o \
@ -1079,6 +1084,14 @@ uninstall-tui:
rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \ rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \
$(DESTDIR)$(man1dir)/$$transformed_name.1 $(DESTDIR)$(man1dir)/$$transformed_name.1
# The C++ name parser can be built standalone for testing.
test-cp-names.o: cp-names.c $(safe_ctype_h) $(libiberty_h) $(demangle_h)
$(CC) -c $(INTERNAL_CFLAGS) -DTEST_CPNAMES \
-o test-cp-names.o cp-names.c
test-cp-names$(EXEEXT): test-cp-names.o $(LIBIBERTY)
$(CC) -o test-cp-names$(EXEEXT) test-cp-names.o $(LIBIBERTY)
# We do this by grepping through sources. If that turns out to be too slow, # We do this by grepping through sources. If that turns out to be too slow,
# maybe we could just require every .o file to have an initialization routine # maybe we could just require every .o file to have an initialization routine
# of a given name (top.o -> _initialize_top, etc.). # of a given name (top.o -> _initialize_top, etc.).
@ -1233,6 +1246,8 @@ clean mostlyclean: $(CONFIG_CLEAN)
rm -f init.c version.c rm -f init.c version.c
rm -f gdb$(EXEEXT) core make.log rm -f gdb$(EXEEXT) core make.log
rm -f gdb[0-9]$(EXEEXT) rm -f gdb[0-9]$(EXEEXT)
rm -f test-cp-names$(EXEEXT)
.PHONY: clean-tui .PHONY: clean-tui
clean-tui: clean-tui:
rm -f $(TUI)$(EXEEXT) rm -f $(TUI)$(EXEEXT)
@ -1260,6 +1275,7 @@ local-maintainer-clean:
@echo "This command is intended for maintainers to use;" @echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild." @echo "it deletes files that may require special tools to rebuild."
rm -f c-exp.c \ rm -f c-exp.c \
cp-names.c \
ada-lex.c ada-exp.c \ ada-lex.c ada-exp.c \
objc-exp.c \ objc-exp.c \
jv-exp.tab \ jv-exp.tab \
@ -1492,7 +1508,6 @@ v850ice.o: $(srcdir)/v850ice.c
$(GDBTK_CFLAGS) \ $(GDBTK_CFLAGS) \
$(srcdir)/v850ice.c $(srcdir)/v850ice.c
# Message files. Based on code in gcc/Makefile.in. # Message files. Based on code in gcc/Makefile.in.
# Rules for generating translated message descriptions. Disabled by # Rules for generating translated message descriptions. Disabled by
@ -1811,6 +1826,7 @@ core-regset.o: core-regset.c $(defs_h) $(command_h) $(gdbcore_h) \
$(inferior_h) $(target_h) $(gdb_string_h) $(gregset_h) $(inferior_h) $(target_h) $(gdb_string_h) $(gregset_h)
cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) $(gdbcmd_h) \ cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) $(gdbcmd_h) \
$(ui_out_h) $(gdb_string_h) $(ui_out_h) $(gdb_string_h)
cp-names.o: cp-names.c $(safe_ctype_h) $(libiberty_h) $(demangle_h)
cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_h) \ cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_h) \
$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h) $(objfiles_h) \ $(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h) $(objfiles_h) \
$(gdbtypes_h) $(dictionary_h) $(command_h) $(frame_h) $(gdbtypes_h) $(dictionary_h) $(command_h) $(frame_h)

View File

@ -103,6 +103,7 @@
@V@/gdb/config/rs6000/tm-rs6000.h @V@/gdb/config/rs6000/tm-rs6k.h @V@/gdb/config/rs6000/tm-rs6000.h @V@/gdb/config/rs6000/tm-rs6k.h
@V@/gdb/config/rs6000/tm-rs6000ly.h @V@/gdb/config/rs6000/tm-rs6kly.h @V@/gdb/config/rs6000/tm-rs6000ly.h @V@/gdb/config/rs6000/tm-rs6kly.h
@V@/gdb/config/sparc/tm-sparclynx.h @V@/gdb/config/sparc/tm-splynx.h @V@/gdb/config/sparc/tm-sparclynx.h @V@/gdb/config/sparc/tm-splynx.h
@V@/gdb/cp-names.c @V@/gdb/cpnames.c
@V@/gdb/f-exp.tab.c @V@/gdb/f-exp_tab.c @V@/gdb/f-exp.tab.c @V@/gdb/f-exp_tab.c
@V@/gdb/gdbtk/ChangeLog-2001 @V@/gdb/gdbtk/ChangeLog.001 @V@/gdb/gdbtk/ChangeLog-2001 @V@/gdb/gdbtk/ChangeLog.001
@V@/gdb/gdbtk/ChangeLog-2002 @V@/gdb/gdbtk/ChangeLog.002 @V@/gdb/gdbtk/ChangeLog-2002 @V@/gdb/gdbtk/ChangeLog.002

2131
gdb/cp-names.y Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Helper routines for C++ support in GDB. /* Helper routines for C++ support in GDB.
Copyright 2002, 2003 Free Software Foundation, Inc. Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by MontaVista Software. Contributed by MontaVista Software.
@ -35,9 +35,10 @@
#include "complaints.h" #include "complaints.h"
#include "gdbtypes.h" #include "gdbtypes.h"
/* Functions related to demangled name parsing. */ #define d_left(dc) (dc)->u.s_binary.left
#define d_right(dc) (dc)->u.s_binary.right
static const char *find_last_component (const char *name); /* Functions related to demangled name parsing. */
static unsigned int cp_find_first_component_aux (const char *name, static unsigned int cp_find_first_component_aux (const char *name,
int permissive); int permissive);
@ -71,6 +72,204 @@ struct cmd_list_element *maint_cplus_cmd_list = NULL;
static void maint_cplus_command (char *arg, int from_tty); static void maint_cplus_command (char *arg, int from_tty);
static void first_component_command (char *arg, int from_tty); static void first_component_command (char *arg, int from_tty);
/* Return the canonicalized form of STRING, or NULL if STRING can not be
parsed. The return value is allocated via xmalloc.
drow/2005-03-07: Should we also return NULL for things that trivially do
not require any change? e.g. simple identifiers. This could be more
efficient. */
char *
cp_canonicalize_string (const char *string)
{
void *storage;
struct demangle_component *ret_comp;
char *ret;
int len = strlen (string);
len = len + len / 8;
ret_comp = cp_demangled_name_to_comp (string, &storage, NULL);
if (ret_comp == NULL)
return NULL;
ret = cp_comp_to_string (ret_comp, len);
xfree (storage);
return ret;
}
/* Convert a mangled name to a demangle_component tree. *MEMORY is set to the
block of used memory that should be freed when finished with the tree.
DEMANGLED_P is set to the char * that should be freed when finished with
the tree, or NULL if none was needed. OPTIONS will be passed to the
demangler. */
static struct demangle_component *
mangled_name_to_comp (const char *mangled_name, int options,
void **memory, char **demangled_p)
{
struct demangle_component *ret;
char *demangled_name;
int len;
/* If it looks like a v3 mangled name, then try to go directly
to trees. */
if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
{
ret = cplus_demangle_v3_components (mangled_name, options, memory);
if (ret)
{
*demangled_p = NULL;
return ret;
}
}
/* If it doesn't, or if that failed, then try to demangle the name. */
demangled_name = cplus_demangle (mangled_name, options);
if (demangled_name == NULL)
return NULL;
/* If we could demangle the name, parse it to build the component tree. */
ret = cp_demangled_name_to_comp (demangled_name, memory, NULL);
if (ret == NULL)
{
free (demangled_name);
return NULL;
}
*demangled_p = demangled_name;
return ret;
}
/* Return the name of the class containing method PHYSNAME. */
char *
cp_class_name_from_physname (const char *physname)
{
void *storage;
char *demangled_name = NULL, *ret;
struct demangle_component *ret_comp, *prev_comp;
int done;
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage,
&demangled_name);
if (ret_comp == NULL)
return NULL;
done = 0;
prev_comp = NULL;
while (!done)
switch (ret_comp->type)
{
case DEMANGLE_COMPONENT_TYPED_NAME:
prev_comp = NULL;
ret_comp = d_right (ret_comp);
break;
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
prev_comp = ret_comp;
ret_comp = d_right (ret_comp);
break;
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
prev_comp = NULL;
ret_comp = d_left (ret_comp);
break;
case DEMANGLE_COMPONENT_NAME:
case DEMANGLE_COMPONENT_TEMPLATE:
case DEMANGLE_COMPONENT_CTOR:
case DEMANGLE_COMPONENT_DTOR:
case DEMANGLE_COMPONENT_OPERATOR:
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
done = 1;
break;
default:
done = 1;
prev_comp = NULL;
ret_comp = NULL;
break;
}
ret = NULL;
if (prev_comp != NULL)
{
*prev_comp = *d_left (prev_comp);
/* The ten is completely arbitrary; we don't have a good estimate. */
ret = cp_comp_to_string (prev_comp, 10);
}
xfree (storage);
if (demangled_name)
xfree (demangled_name);
return ret;
}
/* Return the name of the method whose linkage name is PHYSNAME. */
char *
method_name_from_physname (const char *physname)
{
void *storage;
char *demangled_name = NULL, *ret;
struct demangle_component *ret_comp;
int done;
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage,
&demangled_name);
if (ret_comp == NULL)
return NULL;
done = 0;
while (!done)
switch (ret_comp->type)
{
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_LOCAL_NAME:
case DEMANGLE_COMPONENT_TYPED_NAME:
ret_comp = d_right (ret_comp);
break;
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
ret_comp = d_left (ret_comp);
break;
case DEMANGLE_COMPONENT_NAME:
case DEMANGLE_COMPONENT_TEMPLATE:
case DEMANGLE_COMPONENT_CTOR:
case DEMANGLE_COMPONENT_DTOR:
case DEMANGLE_COMPONENT_OPERATOR:
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
done = 1;
break;
default:
done = 1;
ret_comp = NULL;
break;
}
ret = NULL;
if (ret_comp != NULL)
/* The ten is completely arbitrary; we don't have a good estimate. */
ret = cp_comp_to_string (ret_comp, 10);
xfree (storage);
if (demangled_name)
xfree (demangled_name);
return ret;
}
/* Here are some random pieces of trivia to keep in mind while trying /* Here are some random pieces of trivia to keep in mind while trying
to take apart demangled names: to take apart demangled names:
@ -97,120 +296,6 @@ static void first_component_command (char *arg, int from_tty);
overlapping functionality; can we combine them? Also, do they overlapping functionality; can we combine them? Also, do they
handle all the above considerations correctly? */ handle all the above considerations correctly? */
/* Find the last component of the demangled C++ name NAME. NAME
must be a method name including arguments, in order to correctly
locate the last component.
This function return a pointer to the first colon before the
last component, or NULL if the name had only one component. */
static const char *
find_last_component (const char *name)
{
const char *p;
int depth;
/* Functions can have local classes, so we need to find the
beginning of the last argument list, not the end of the first
one. */
p = name + strlen (name) - 1;
while (p > name && *p != ')')
p--;
if (p == name)
return NULL;
/* P now points at the `)' at the end of the argument list. Walk
back to the beginning. */
p--;
depth = 1;
while (p > name && depth > 0)
{
if (*p == '<' || *p == '(')
depth--;
else if (*p == '>' || *p == ')')
depth++;
p--;
}
if (p == name)
return NULL;
while (p > name && *p != ':')
p--;
if (p == name || p == name + 1 || p[-1] != ':')
return NULL;
return p - 1;
}
/* Return the name of the class containing method PHYSNAME. */
char *
cp_class_name_from_physname (const char *physname)
{
char *ret = NULL;
const char *end;
int depth = 0;
char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS);
if (demangled_name == NULL)
return NULL;
end = find_last_component (demangled_name);
if (end != NULL)
{
ret = xmalloc (end - demangled_name + 1);
memcpy (ret, demangled_name, end - demangled_name);
ret[end - demangled_name] = '\0';
}
xfree (demangled_name);
return ret;
}
/* Return the name of the method whose linkage name is PHYSNAME. */
char *
method_name_from_physname (const char *physname)
{
char *ret = NULL;
const char *end;
int depth = 0;
char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS);
if (demangled_name == NULL)
return NULL;
end = find_last_component (demangled_name);
if (end != NULL)
{
char *args;
int len;
/* Skip "::". */
end = end + 2;
/* Find the argument list, if any. */
args = strchr (end, '(');
if (args == NULL)
len = strlen (end + 2);
else
{
args --;
while (*args == ' ')
args --;
len = args - end + 1;
}
ret = xmalloc (len + 1);
memcpy (ret, end, len);
ret[len] = 0;
}
xfree (demangled_name);
return ret;
}
/* This returns the length of first component of NAME, which should be /* This returns the length of first component of NAME, which should be
the demangled name of a C++ variable/function/method/etc. the demangled name of a C++ variable/function/method/etc.

View File

@ -1,5 +1,5 @@
/* Helper routines for C++ support in GDB. /* Helper routines for C++ support in GDB.
Copyright 2002, 2003, 2004 Free Software Foundation, Inc. Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by MontaVista Software. Contributed by MontaVista Software.
Namespace support contributed by David Carlton. Namespace support contributed by David Carlton.
@ -35,6 +35,7 @@ struct obstack;
struct block; struct block;
struct objfile; struct objfile;
struct type; struct type;
struct demangle_component;
/* This struct is designed to store data from using directives. It /* This struct is designed to store data from using directives. It
says that names from namespace INNER should be visible within says that names from namespace INNER should be visible within
@ -52,6 +53,8 @@ struct using_direct
/* Functions from cp-support.c. */ /* Functions from cp-support.c. */
extern char *cp_canonicalize_string (const char *string);
extern char *cp_class_name_from_physname (const char *physname); extern char *cp_class_name_from_physname (const char *physname);
extern char *method_name_from_physname (const char *physname); extern char *method_name_from_physname (const char *physname);
@ -113,6 +116,14 @@ extern void cp_check_possible_namespace_symbols (const char *name,
struct type *cp_lookup_transparent_type (const char *name); struct type *cp_lookup_transparent_type (const char *name);
/* Functions from cp-names.y. */
extern struct demangle_component *cp_demangled_name_to_comp
(const char *demangled_name, void **memory_p, const char **errmsg);
extern char *cp_comp_to_string (struct demangle_component *result,
int estimated_len);
/* The list of "maint cplus" commands. */ /* The list of "maint cplus" commands. */
extern struct cmd_list_element *maint_cplus_cmd_list; extern struct cmd_list_element *maint_cplus_cmd_list;