* 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>
* 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>

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 \
complaints.c completer.c corefile.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 \
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 \
@ -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_frv_h = $(INCLUDE_DIR)/elf/frv.h $(elf_reloc_macros_h)
libaout_h = $(BFD_SRC)/libaout.h
libiberty_h = $(INCLUDE_DIR)/libiberty.h
libbfd_h = $(BFD_SRC)/libbfd.h
remote_sim_h = $(INCLUDE_DIR)/gdb/remote-sim.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_sh_h = $(INCLUDE_DIR)/gdb/sim-sh.h
splay_tree_h = $(INCLUDE_DIR)/splay-tree.h
safe_ctype_h = $(INCLUDE_DIR)/safe-ctype.h
hashtab_h = $(INCLUDE_DIR)/hashtab.h
#
@ -944,11 +947,13 @@ SUBDIRS = @subdirs@
# For now, shortcut the "configure GDB for fewer languages" stuff.
YYFILES = c-exp.c \
cp-names.c \
objc-exp.c \
ada-exp.c \
jv-exp.c \
f-exp.c m2-exp.c p-exp.c
YYOBJ = c-exp.o \
cp-names.o \
objc-exp.o \
ada-exp.o \
jv-exp.o \
@ -1079,6 +1084,14 @@ uninstall-tui:
rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \
$(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,
# maybe we could just require every .o file to have an initialization routine
# 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 gdb$(EXEEXT) core make.log
rm -f gdb[0-9]$(EXEEXT)
rm -f test-cp-names$(EXEEXT)
.PHONY: clean-tui
clean-tui:
rm -f $(TUI)$(EXEEXT)
@ -1260,6 +1275,7 @@ local-maintainer-clean:
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
rm -f c-exp.c \
cp-names.c \
ada-lex.c ada-exp.c \
objc-exp.c \
jv-exp.tab \
@ -1492,7 +1508,6 @@ v850ice.o: $(srcdir)/v850ice.c
$(GDBTK_CFLAGS) \
$(srcdir)/v850ice.c
# Message files. Based on code in gcc/Makefile.in.
# 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)
cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) $(gdbcmd_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) \
$(symtab_h) $(symfile_h) $(gdb_assert_h) $(block_h) $(objfiles_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-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/cp-names.c @V@/gdb/cpnames.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-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.
Copyright 2002, 2003 Free Software Foundation, Inc.
Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by MontaVista Software.
@ -35,9 +35,10 @@
#include "complaints.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,
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 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
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
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
the demangled name of a C++ variable/function/method/etc.

View File

@ -1,5 +1,5 @@
/* 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.
Namespace support contributed by David Carlton.
@ -35,6 +35,7 @@ struct obstack;
struct block;
struct objfile;
struct type;
struct demangle_component;
/* This struct is designed to store data from using directives. It
says that names from namespace INNER should be visible within
@ -52,6 +53,8 @@ struct using_direct
/* 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 *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);
/* 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. */
extern struct cmd_list_element *maint_cplus_cmd_list;