From: Daniel Jacobowitz Date: Sun, 4 Jan 2004 22:42:41 +0000 (+0000) Subject: * Makefile.in (cp_names_h): Remove. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be01fded5c79b543d9f28974a625fe4b05162a92;p=thirdparty%2Fbinutils-gdb.git * Makefile.in (cp_names_h): Remove. (cp_demangle_h): New. (cp-names.tab.o, cp-names-main.tab.o): Use $(cp_demangle_h) and remove $(cp_names_h). (cp-support.o): Use $(cp_demangle_h). * cp-names.y: Don't include cp-names.h. (cp_comp_to_string): Export. (cp_canonicalize_string): Move to cp-support.c. (demangled_name_to_comp, mangled_name_to_comp): New functions. * cp-support.c: Include "cp-demangle.h". (cp_canonicalize_string): New function, moved from cp-names.y and updated. (class_name_from_physname, method_name_from_physname): Rewritten. (find_last_component): Removed. * cp-support.h: Add new opaque types and prototypes. * dwarf2read.c: Don't include cp-names.h. * cp-names.h: Remove file. --- diff --git a/gdb/ChangeLog.cplus b/gdb/ChangeLog.cplus index 17c816ef9e5..21de7a1d8de 100644 --- a/gdb/ChangeLog.cplus +++ b/gdb/ChangeLog.cplus @@ -1,3 +1,23 @@ +2003-01-04 Daniel Jacobowitz + + * Makefile.in (cp_names_h): Remove. + (cp_demangle_h): New. + (cp-names.tab.o, cp-names-main.tab.o): Use $(cp_demangle_h) and + remove $(cp_names_h). + (cp-support.o): Use $(cp_demangle_h). + * cp-names.y: Don't include cp-names.h. + (cp_comp_to_string): Export. + (cp_canonicalize_string): Move to cp-support.c. + (demangled_name_to_comp, mangled_name_to_comp): New functions. + * cp-support.c: Include "cp-demangle.h". + (cp_canonicalize_string): New function, moved from cp-names.y and + updated. + (class_name_from_physname, method_name_from_physname): Rewritten. + (find_last_component): Removed. + * cp-support.h: Add new opaque types and prototypes. + * dwarf2read.c: Don't include cp-names.h. + * cp-names.h: Remove file. + 2004-01-04 Daniel Jacobowitz * Makefile.in (cp-names.tab.o, cp-names-main.tab.o, test-cpnames): diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ad1bb3ae85d..4fccb9caffd 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -579,6 +579,7 @@ coff_sym_h = $(INCLUDE_DIR)/coff/sym.h coff_symconst_h = $(INCLUDE_DIR)/coff/symconst.h coff_ecoff_h = $(INCLUDE_DIR)/coff/ecoff.h coff_internal_h = $(INCLUDE_DIR)/coff/internal.h +cp_demangle_h = $(INCLUDE_DIR)/cp-demangle.h dis_asm_h = $(INCLUDE_DIR)/dis-asm.h $(bfd_h) elf_reloc_macros_h = $(INCLUDE_DIR)/elf/reloc-macros.h elf_sh_h = $(INCLUDE_DIR)/elf/sh.h @@ -654,7 +655,6 @@ command_h = command.h complaints_h = complaints.h completer_h = completer.h cp_abi_h = cp-abi.h -cp_names_h = cp-names.h cp_support_h = cp-support.h $(symtab_h) dcache_h = dcache.h defs_h = defs.h $(config_h) $(ansidecl_h) $(gdb_locale_h) $(gdb_signals_h) \ @@ -1439,11 +1439,9 @@ c-exp.tab.c: c-exp.y -rm c-exp.tmp mv c-exp.new ./c-exp.tab.c -cp-names.tab.o: cp-names.tab.c $(safe_ctype_h) $(cp_names_h) \ - $(srcdir)/../include/cp-demangle.h +cp-names.tab.o: cp-names.tab.c $(safe_ctype_h) $(cp_demangle_h) -cp-names-main.tab.o: cp-names.tab.c $(safe_ctype_h) $(cp_names_h) \ - $(srcdir)/../include/cp-demangle.h +cp-names-main.tab.o: cp-names.tab.c $(safe_ctype_h) $(cp_demangle_h) $(CC) -c $(INTERNAL_CFLAGS) -DTEST_CPNAMES \ -o cp-names-main.tab.o cp-names.tab.c test-cpnames: cp-names-main.tab.o $(LIBIBERTY) @@ -1708,7 +1706,8 @@ cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_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) + $(objfiles_h) $(frame_h) $(symtab_h) $(block_h) $(complaints_h) \ + $(cp_demangle_h) cpu32bug-rom.o: cpu32bug-rom.c $(defs_h) $(gdbcore_h) $(target_h) \ $(monitor_h) $(serial_h) $(regcache_h) $(m68k_tdep_h) cp-valprint.o: cp-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \ diff --git a/gdb/cp-names.h b/gdb/cp-names.h deleted file mode 100644 index a716f34f1b5..00000000000 --- a/gdb/cp-names.h +++ /dev/null @@ -1,24 +0,0 @@ -/* YACC parser for C++ names, for GDB. - - Copyright 2003 - Free Software Foundation, Inc. - -This file is part of GDB. - -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 -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Return the canonicalized form of STRING, or NULL if STRING can not be - parsed. */ -char *cp_canonicalize_string (const char *string); diff --git a/gdb/cp-names.y b/gdb/cp-names.y index e685fc86816..6661893b2b4 100644 --- a/gdb/cp-names.y +++ b/gdb/cp-names.y @@ -43,8 +43,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define IN_GDB #include "cp-demangle.h" -#include "cp-names.h" - static const char *lexptr, *prev_lexptr; static struct d_comp *d_qualify (struct d_comp *, int, int); @@ -2005,7 +2003,7 @@ symbol_end (const char *lexptr) return p; } -static char * +char * cp_comp_to_string (struct d_comp *result, int estimated_len) { char *str, *prefix = NULL, *buf; @@ -2036,26 +2034,57 @@ cp_comp_to_string (struct d_comp *result, int estimated_len) return (buf); } -/* Return the canonicalized form of STRING, or NULL if STRING can not be - parsed. */ +/* Convert a demangled name to a d_comp tree. *DI_P is set to the + struct d_info that should be freed when finished with the tree. */ -char * -cp_canonicalize_string (const char *string) +struct d_comp * +demangled_name_to_comp (const char *demangled_name, struct d_info **di_p) { - int len = strlen (string); - char *ret; + int len = strlen (demangled_name); len = len + len / 8; + lexptr = demangled_name; - lexptr = string; di = cp_v3_d_init_info_alloc (NULL, DMGL_PARAMS | DMGL_ANSI, len); + if (yyparse () || result == NULL) - return NULL; + { + cp_v3_d_free_info (di); + return NULL; + } - ret = cp_comp_to_string (result, len); + *di_p = di; + return result; +} + +/* Convert a mangled name to a d_comp tree. *DI_P is set to the + struct d_info 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. OPTIONS will be passed to the demangler. + + This could be done much more efficiently for v3 mangled names by exposing + d_demangle from the demangler. */ + +struct d_comp * +mangled_name_to_comp (const char *mangled_name, int options, + struct d_info **di_p, char **demangled_p) +{ + char *demangled_name = cplus_demangle (mangled_name, options); + int len; + struct d_comp *ret; - cp_v3_d_free_info (di); + if (demangled_name == NULL) + return NULL; + + ret = demangled_name_to_comp (demangled_name, di_p); + + if (ret == NULL) + { + free (demangled_name); + return NULL; + } + *demangled_p = demangled_name; return ret; } diff --git a/gdb/cp-support.c b/gdb/cp-support.c index bd76fae1851..e37945d8f48 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -1,5 +1,5 @@ /* Helper routines for C++ support in GDB. - Copyright 2002, 2003 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by MontaVista Software. @@ -35,6 +35,9 @@ #include "complaints.h" #include "gdbtypes.h" +#define IN_GDB +#include "cp-demangle.h" + /* Functions related to demangled name parsing. */ static const char *find_last_component (const char *name); @@ -63,78 +66,31 @@ 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); -/* Here are some random pieces of trivia to keep in mind while trying - to take apart demangled names: - - - Names can contain function arguments or templates, so the process - has to be, to some extent recursive: maybe keep track of your - depth based on encountering <> and (). - - - Parentheses don't just have to happen at the end of a name: they - can occur even if the name in question isn't a function, because - a template argument might be a type that's a function. - - - Conversely, even if you're trying to deal with a function, its - demangled name might not end with ')': it could be a const or - volatile class method, in which case it ends with "const" or - "volatile". - - - Parentheses are also used in anonymous namespaces: a variable - 'foo' in an anonymous namespace gets demangled as "(anonymous - namespace)::foo". - - - And operator names can contain parentheses or angle brackets. */ - -/* FIXME: carlton/2003-03-13: We have several functions here with - 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. +/* Return the canonicalized form of STRING, or NULL if STRING can not be + parsed. */ - This function return a pointer to the first colon before the - last component, or NULL if the name had only one component. */ +/* FIXME: Should we also return NULL for things that trivially do not require + any change? i.e. alphanumeric strings. */ -static const char * -find_last_component (const char *name) +char * +cp_canonicalize_string (const char *string) { - const char *p; - int depth; + struct d_info *di; + struct d_comp *ret_comp; + char *ret; + int len = strlen (string); - /* 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--; + len = len + len / 8; - if (p == name) + ret_comp = demangled_name_to_comp (string, &di); + if (ret_comp == NULL) 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; + ret = cp_comp_to_string (ret_comp, len); - while (p > name && *p != ':') - p--; + cp_v3_d_free_info (di); - if (p == name || p == name + 1 || p[-1] != ':') - return NULL; - - return p - 1; + return ret; } /* Return the name of the class containing method PHYSNAME. */ @@ -142,22 +98,63 @@ find_last_component (const char *name) char * 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); + struct d_info *di; + char *demangled_name, *ret; + struct d_comp *ret_comp, *prev_comp; + int done; - if (demangled_name == NULL) + ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &di, &demangled_name); + if (ret_comp == NULL) return NULL; - end = find_last_component (demangled_name); - if (end != NULL) + done = 0; + prev_comp = NULL; + while (!done) + switch (ret_comp->type) + { + case D_COMP_TYPED_NAME: + prev_comp = NULL; + ret_comp = d_right (ret_comp); + break; + case D_COMP_QUAL_NAME: + case D_COMP_LOCAL_NAME: + prev_comp = ret_comp; + ret_comp = d_right (ret_comp); + break; + case D_COMP_CONST: + case D_COMP_RESTRICT: + case D_COMP_VOLATILE: + case D_COMP_CONST_THIS: + case D_COMP_RESTRICT_THIS: + case D_COMP_VOLATILE_THIS: + case D_COMP_VENDOR_TYPE_QUAL: + prev_comp = NULL; + ret_comp = d_left (ret_comp); + break; + case D_COMP_NAME: + case D_COMP_TEMPLATE: + case D_COMP_CTOR: + case D_COMP_DTOR: + case D_COMP_OPERATOR: + case D_COMP_EXTENDED_OPERATOR: + done = 1; + break; + default: + done = 1; + prev_comp = NULL; + ret_comp = NULL; + break; + } + + ret = NULL; + if (prev_comp != NULL) { - ret = xmalloc (end - demangled_name + 1); - memcpy (ret, demangled_name, end - demangled_name); - ret[end - demangled_name] = '\0'; + *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); } + cp_v3_d_free_info (di); xfree (demangled_name); return ret; } @@ -167,43 +164,84 @@ class_name_from_physname (const char *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); + struct d_info *di; + char *demangled_name, *ret; + struct d_comp *ret_comp; + int done; - if (demangled_name == NULL) + ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &di, &demangled_name); + if (ret_comp == NULL) return NULL; - end = find_last_component (demangled_name); - if (end != NULL) - { - char *args; - int len; + done = 0; + while (!done) + switch (ret_comp->type) + { + case D_COMP_QUAL_NAME: + case D_COMP_LOCAL_NAME: + case D_COMP_TYPED_NAME: + ret_comp = d_right (ret_comp); + break; + case D_COMP_CONST: + case D_COMP_RESTRICT: + case D_COMP_VOLATILE: + case D_COMP_CONST_THIS: + case D_COMP_RESTRICT_THIS: + case D_COMP_VOLATILE_THIS: + case D_COMP_VENDOR_TYPE_QUAL: + ret_comp = d_left (ret_comp); + break; + case D_COMP_NAME: + case D_COMP_TEMPLATE: + case D_COMP_CTOR: + case D_COMP_DTOR: + case D_COMP_OPERATOR: + case D_COMP_EXTENDED_OPERATOR: + done = 1; + break; + default: + done = 1; + ret_comp = NULL; + break; + } - /* 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; - } + 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); + cp_v3_d_free_info (di); xfree (demangled_name); return ret; } +/* Here are some random pieces of trivia to keep in mind while trying + to take apart demangled names: + + - Names can contain function arguments or templates, so the process + has to be, to some extent recursive: maybe keep track of your + depth based on encountering <> and (). + + - Parentheses don't just have to happen at the end of a name: they + can occur even if the name in question isn't a function, because + a template argument might be a type that's a function. + + - Conversely, even if you're trying to deal with a function, its + demangled name might not end with ')': it could be a const or + volatile class method, in which case it ends with "const" or + "volatile". + + - Parentheses are also used in anonymous namespaces: a variable + 'foo' in an anonymous namespace gets demangled as "(anonymous + namespace)::foo". + + - And operator names can contain parentheses or angle brackets. */ + +/* FIXME: carlton/2003-03-13: We have several functions here with + overlapping functionality; can we combine them? Also, do they + handle all the above considerations correctly? */ + + /* This returns the length of first component of NAME, which should be the demangled name of a C++ variable/function/method/etc. Specifically, it returns the index of the first colon forming the diff --git a/gdb/cp-support.h b/gdb/cp-support.h index c08efe1539c..0e33c14c940 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -1,5 +1,5 @@ /* Helper routines for C++ support in GDB. - Copyright 2002, 2003 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by MontaVista Software. Namespace support contributed by David Carlton. @@ -35,6 +35,8 @@ struct obstack; struct block; struct objfile; struct type; +struct d_comp; +struct d_info; /* This struct is designed to store data from using directives. It says that names from namespace INNER should be visible within @@ -52,6 +54,8 @@ struct using_direct /* Functions from cp-support.c. */ +extern char *cp_canonicalize_string (const char *string); + extern char *class_name_from_physname (const char *physname); extern char *method_name_from_physname (const char *physname); @@ -108,6 +112,18 @@ extern struct type *cp_lookup_nested_type (struct type *parent_type, extern void cp_check_possible_namespace_symbols (const char *name, struct objfile *objfile); +/* Functions from cp-names.y. */ + +extern struct d_comp *demangled_name_to_comp (const char *demangled_name, + struct d_info **di_p); + +extern struct d_comp *mangled_name_to_comp (const char *mangled_name, + int options, + struct d_info **di_p, + char **demangled_p); + +extern char *cp_comp_to_string (struct d_comp *result, int estimated_len); + /* The list of "maint cplus" commands. */ extern struct cmd_list_element *maint_cplus_cmd_list; diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0616a35d8e5..94951cbaa3d 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,5 +1,5 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -44,7 +44,6 @@ #include "dwarf2expr.h" #include "dwarf2loc.h" #include "cp-support.h" -#include "cp-names.h" #include #include "gdb_string.h"