diff options
-rw-r--r-- | gdb/.Sanitize | 1 | ||||
-rw-r--r-- | gdb/ChangeLog | 29 | ||||
-rw-r--r-- | gdb/Makefile.in | 23 | ||||
-rw-r--r-- | gdb/cplus-dem.c | 202 | ||||
-rw-r--r-- | gdb/demangle.c | 185 | ||||
-rw-r--r-- | gdb/demangle.h | 19 | ||||
-rw-r--r-- | gdb/dwarfread.c | 70 |
7 files changed, 440 insertions, 89 deletions
diff --git a/gdb/.Sanitize b/gdb/.Sanitize index 3e25295..78b4d85 100644 --- a/gdb/.Sanitize +++ b/gdb/.Sanitize @@ -71,6 +71,7 @@ cplus-dem.c createtags dbxread.c defs.h +demangle.c demangle.h depend doc diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1d12c7f..4422419 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,32 @@ +Mon Jul 13 19:06:54 1992 Fred Fish (fnf@cygnus.com) + + * Makefile.in (DEMANGLING_STYLE): New define to set default + demangling style for C++. Defaults to "auto". + * Makefile.in (DEMANGLE_OPTS): Use DEMANGLING_STYLE. + * Makefile.in (SFILES_MAINDIR): Add demangle.c + * Makefile.in (OBS): Add demangle.o + * cplus-dem.c (GNU_DEMANGLING, ARM_DEMANGLING, LUCID_DEMANGLING): + Remove compile time decisions about demangling style and replace + with runtime decisions using current_demangling_style. + * cplus-dem.c (main): Expand code included during building of + standalone demangler to recognize demangling style options. + * dbxread.c (demangle.h): Include. + * dbxread.c (read_ofile_symtab, process_one_symbol): Set GNU C++ + demangling style if processing g++ code and current demangling style + is auto (Note: this feature currently disabled.) + * demangle.c: New file, generic demangling control. + * demangle.h (demangling_styles): New enumeration to select one + of several demangling styles. Also define string names for each + style. + * demangle.h (set_demangling_style): Add prototype. + * dwarfread.c (demangle.h): Include. + * dwarfread.c (GPLUS_PRODUCER, LCC_PRODUCER, CFRONT_PRODUCER): + New producer string prefixes to recognize. + * dwarfread.c (handle_producer): Consolidate actions for specific + producers. Set demangling style based on producer string if + current style is auto. (Note: this feature currently disabled.) + * config/ncr3000.mt (DEMANGLE_OPTS): Remove. + Sat Jul 11 18:23:58 1992 John Gilmore (gnu at cygnus.com) * config/sun4sol2.mh: Remove -xs flag, default INSTALL to cp. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 54d9074..35ddfbe 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -168,15 +168,20 @@ DIST=gdb LINT=/usr/5bin/lint LINTFLAGS= -I${BFD_DIR} +# Select the default C++ demangling style to use. The default is "auto", +# which allows gdb to attempt to pick an appropriate demangling style for +# the executable it has loaded. It can be set to a specific style ("gnu", +# "lucid", "cfront", etc) in which case gdb will never attempt to do auto +# selection of the style unless you do an explicit "set demangle auto". +# To select one of these as the default, set DEMANGLING_STYLE in the +# appropriate target dependent makefile fragment. +DEMANGLING_STYLE = "auto" + # Select demangler to use. -DEMANGLER=cplus-dem +DEMANGLER = cplus-dem -# Select options to use when compiling ${DEMANGLER}.c. The default is no -# options, which is correct for most targets, and also defaults to g++ style -# demangling. For other demangling styles, such as the Annotated C++ -# Reference Manual (section 7.2.1c) style, set this define in the target- -# dependent makefile fragment. -DEMANGLE_OPTS= +# Select options to use when compiling ${DEMANGLER}.c. +DEMANGLE_OPTS = -DDEMANGLING_STYLE=${DEMANGLING_STYLE} # Host and target-dependent makefile fragments come in here. #### @@ -186,7 +191,7 @@ DEMANGLE_OPTS= # Files which are included via a config/* Makefile fragment # should *not* be specified here; they're in "ALLDEPFILES". SFILES_MAINDIR = \ - blockframe.c breakpoint.c command.c core.c \ + blockframe.c breakpoint.c command.c core.c demangle.c \ environ.c eval.c expprint.c findvar.c infcmd.c inflow.c infrun.c \ main.c printcmd.c gdbtypes.c \ remote.c source.c stack.c symmisc.c symtab.c symfile.c \ @@ -280,7 +285,7 @@ OBS = main.o blockframe.o breakpoint.o findvar.o stack.o source.o \ command.o utils.o expprint.o environ.o version.o gdbtypes.o \ copying.o $(DEPFILES) ${DEMANGLER}.o mem-break.o target.o \ inftarg.o ieee-float.o putenv.o parse.o language.o $(YYOBJ) \ - buildsym.o objfiles.o minsyms.o maint.o \ + buildsym.o objfiles.o minsyms.o maint.o demangle.o \ dbxread.o coffread.o elfread.o dwarfread.o xcoffread.o mipsread.o RAPP_OBS = rgdb.o rudp.o rserial.o serial.o udp.o $(XDEPFILES) diff --git a/gdb/cplus-dem.c b/gdb/cplus-dem.c index f3b3d88..525df0b 100644 --- a/gdb/cplus-dem.c +++ b/gdb/cplus-dem.c @@ -32,10 +32,6 @@ #include <ctype.h> #include <string.h> -#if !defined (GNU_DEMANGLING) && !defined (ARM_DEMANGLING) -# define GNU_DEMANGLING 1 -#endif - /* This is '$' on systems where the assembler can deal with that. Where the assembler can't, it's '.' (but on many systems '.' is used for other things). */ @@ -91,11 +87,8 @@ static const struct optable "ami", "-=", DMGL_ANSI, /* ansi */ "mult", "*", 0, /* old */ "ml", "*", DMGL_ANSI, /* ansi */ -#ifdef ARM_DEMANGLING - "amu", "*=", DMGL_ANSI, /* ansi */ -#else - "aml", "*=", DMGL_ANSI, /* ansi */ -#endif + "amu", "*=", DMGL_ANSI, /* ansi (ARM/Lucid) */ + "aml", "*=", DMGL_ANSI, /* ansi (GNU/g++) */ "convert", "+", 0, /* old (unary +) */ "negate", "-", 0, /* old (unary -) */ "trunc_mod", "%", 0, /* old */ @@ -134,11 +127,8 @@ static const struct optable "rs", ">>", DMGL_ANSI, /* ansi */ "ars", ">>=", DMGL_ANSI, /* ansi */ "component", "->", 0, /* old */ -#ifdef LUCID_DEMANGLING "pt", "->", DMGL_ANSI, /* ansi; Lucid C++ form */ -#else - "rf", "->", DMGL_ANSI, /* ansi */ -#endif + "rf", "->", DMGL_ANSI, /* ansi; ARM/GNU form */ "indirect", "*", 0, /* old */ "method_call", "->()", 0, /* old */ "addr", "&", 0, /* old (unary &) */ @@ -434,9 +424,7 @@ demangle_signature (declp, mangled, work) { int success = 1; int func_done = 0; -#ifdef GNU_DEMANGLING int expect_func = 0; -#endif #ifndef LONGERNAMES const char *premangle; #endif @@ -451,9 +439,11 @@ demangle_signature (declp, mangled, work) { case 'Q': success = demangle_qualified (declp, mangled, work); -#ifdef GNU_DEMANGLING - expect_func = 1; -#endif + if (current_demangling_style == auto_demangling || + current_demangling_style == gnu_demangling) + { + expect_func = 1; + } break; case 'S': @@ -477,9 +467,11 @@ demangle_signature (declp, mangled, work) remember_type (premangle, *mangled - premangle, work); } #endif -#ifdef GNU_DEMANGLING - expect_func = 1; -#endif + if (current_demangling_style == auto_demangling || + current_demangling_style == gnu_demangling) + { + expect_func = 1; + } break; case 'F': @@ -508,39 +500,47 @@ demangle_signature (declp, mangled, work) break; default: -#ifdef GNU_DEMANGLING - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = 1; - success = demangle_args (declp, mangled, work); -#else - /* Non-GNU demanglers use a specific token to mark the start - of the outermost function argument tokens. Typically 'F', - for ARM-demangling, for example. So if we find something - we are not prepared for, it must be an error. */ - success = 0; -#endif + if (current_demangling_style == auto_demangling || + current_demangling_style == gnu_demangling) + { + /* Assume we have stumbled onto the first outermost function + argument token, and start processing args. */ + func_done = 1; + success = demangle_args (declp, mangled, work); + } + else + { + /* Non-GNU demanglers use a specific token to mark the start + of the outermost function argument tokens. Typically 'F', + for ARM-demangling, for example. So if we find something + we are not prepared for, it must be an error. */ + success = 0; + } break; } -#ifdef GNU_DEMANGLING - if (success && expect_func) + if (current_demangling_style == auto_demangling || + current_demangling_style == gnu_demangling) { - func_done = 1; - success = demangle_args (declp, mangled, work); + if (success && expect_func) + { + func_done = 1; + success = demangle_args (declp, mangled, work); + } } -#endif } if (success && !func_done) { -#ifdef GNU_DEMANGLING - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added to - the current declp. Note that with ARM_DEMANGLING, the first - case represents the name of a static data member 'foo::bar', - which is in the current declp, so we leave it alone. */ - success = demangle_args (declp, mangled, work); -#endif + if (current_demangling_style == auto_demangling || + current_demangling_style == gnu_demangling) + { + /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and + bar__3fooi is 'foo::bar(int)'. We get here when we find the + first case, and need to ensure that the '(void)' gets added to + the current declp. Note that with ARM, the first case + represents the name of a static data member 'foo::bar', + which is in the current declp, so we leave it alone. */ + success = demangle_args (declp, mangled, work); + } } if (success && work -> static_type && PRINT_ARG_TYPES) { @@ -895,9 +895,18 @@ demangle_prefix (declp, mangled, work) int success = 1; const char *scan; - if ((scan = strstr (*mangled, "__")) == NULL) + scan = strstr (*mangled, "__"); + if (scan == NULL) { - success = gnu_special (declp, mangled, work); + if (current_demangling_style == auto_demangling || + current_demangling_style == gnu_demangling) + { + success = gnu_special (declp, mangled, work); + } + else + { + success = 0; + } } else if (work -> static_type) { @@ -1575,9 +1584,11 @@ demangle_args (declp, type, work) { return (0); } -#ifdef ARM_DEMANGLING - t--; -#endif + if (current_demangling_style == lucid_demangling || + current_demangling_style == cfront_demangling) + { + t--; + } /* Validate the type index. Protect against illegal indices from malformed type strings. */ if ((t < 0) || (t >= work -> ntypes)) @@ -1664,28 +1675,29 @@ demangle_function_name (declp, mangled, work, scan) (*mangled) = scan + 2; -#ifdef ARM_DEMANGLING + if (current_demangling_style == lucid_demangling || + current_demangling_style == cfront_demangling) + { - /* See if we have an ARM style constructor or destructor operator. - If so, then just record it, clear the decl, and return. - We can't build the actual constructor/destructor decl until later, - when we recover the class name from the signature. */ + /* See if we have an ARM style constructor or destructor operator. + If so, then just record it, clear the decl, and return. + We can't build the actual constructor/destructor decl until later, + when we recover the class name from the signature. */ - if (strcmp (declp -> b, "__ct") == 0) - { - work -> constructor = 1; - string_clear (declp); - return; - } - else if (strcmp (declp -> b, "__dt") == 0) - { - work -> destructor = 1; - string_clear (declp); - return; + if (strcmp (declp -> b, "__ct") == 0) + { + work -> constructor = 1; + string_clear (declp); + return; + } + else if (strcmp (declp -> b, "__dt") == 0) + { + work -> destructor = 1; + string_clear (declp); + return; + } } -#endif - if (declp->p - declp->b >= 3 && declp->b[0] == 'o' && declp->b[1] == 'p' @@ -1996,20 +2008,56 @@ xrealloc (oldmem, size) return (newmem); } +#include <stdio.h> + +enum demangling_styles current_demangling_style = gnu_demangling; + main (argc, argv) int argc; char **argv; { char mangled_name[128]; char *result; - - if (argc > 1) + int c; + extern char *optarg; + extern int optind; + + while ((c = getopt (argc, argv, "s:?")) != EOF) { - argc--; - argv++; - while (argc-- > 0) + switch (c) { - demangle_it (*argv); + case '?': + fprintf (stderr, "usage: demangle [-s style] [arg1 [arg2]] ...\n"); + fprintf (stderr, "style = { gnu, lucid, cfront }\n"); + fprintf (stderr, "reads args from stdin if none supplied\n"); + exit (0); + break; + case 's': + if (strcmp (optarg, "gnu") == 0) + { + current_demangling_style = gnu_demangling; + } + else if (strcmp (optarg, "lucid") == 0) + { + current_demangling_style = lucid_demangling; + } + else if (strcmp (optarg, "cfront") == 0) + { + current_demangling_style = cfront_demangling; + } + else + { + fprintf (stderr, "unknown demangling style `%s'\n", optarg); + exit (1); + } + break; + } + } + if (optind < argc) + { + for ( ; optind < argc; optind++) + { + demangle_it (argv[optind]); } } else @@ -2021,4 +2069,4 @@ main (argc, argv) } } -#endif +#endif /* main */ diff --git a/gdb/demangle.c b/gdb/demangle.c new file mode 100644 index 0000000..9710856 --- /dev/null +++ b/gdb/demangle.c @@ -0,0 +1,185 @@ +/* Basic C++ demangling support for GDB. + Copyright 1991, 1992 Free Software Foundation, Inc. + Written by Fred Fish at Cygnus Support. + +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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* This file contains support code for C++ demangling that is common + to a styles of demangling, and GDB specific. */ + +#include "defs.h" +#include "command.h" +#include "gdbcmd.h" +#include "demangle.h" +#include <string.h> + +#ifndef DEMANGLING_STYLE +# define DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING +#endif + +/* The current demangling style in affect. Global so that the demangler + can read it (FIXME: change the interface) */ + +enum demangling_styles current_demangling_style; + +/* String name for the current demangling style. Set by the "set demangling" + command, printed as part of the output by the "show demangling" command. */ + +static char *current_demangling_style_string; + +/* List of supported demangling styles. Contains the name of the style as + seen by the user, and the enum value that corresponds to that style. */ + +static const struct demangler +{ + char *demangling_style_name; + enum demangling_styles demangling_style; + char *demangling_style_doc; +} demanglers [] = +{ + {AUTO_DEMANGLING_STYLE_STRING, + auto_demangling, + "Automatic selection based on executable"}, + {GNU_DEMANGLING_STYLE_STRING, + gnu_demangling, + "GNU (g++) style demangling"}, + {LUCID_DEMANGLING_STYLE_STRING, + lucid_demangling, + "Lucid (lcc) style demangling"}, + {CFRONT_DEMANGLING_STYLE_STRING, + cfront_demangling, + "ARM (cfront) style demangling"}, + {NULL, 0, NULL} +}; + +/* show current demangling style. */ + +static void +show_demangling_command (ignore, from_tty) + char *ignore; + int from_tty; +{ + /* done automatically by show command. */ +} + + +/* set current demangling style. called by the "set demangling" command + after it has updated the current_demangling_style_string to match + what the user has entered. + + if the user has entered a string that matches a known demangling style + name in the demanglers[] array then just leave the string alone and update + the current_demangling_style enum value to match. + + if the user has entered a string that doesn't match, including an empty + string, then print a list of the currently known styles and restore + the current_demangling_style_string to match the current_demangling_style + enum value. + + Note: Assumes that current_demangling_style_string always points to + a malloc'd string, even if it is a null-string. */ + +static void +set_demangling_command (ignore, from_tty) + char *ignore; + int from_tty; +{ + const struct demangler *dem; + + /* First just try to match whatever style name the user supplied with + one of the known ones. Don't bother special casing for an empty + name, we just treat it as any other style name that doesn't match. + If we match, update the current demangling style enum. */ + + for (dem = demanglers; dem -> demangling_style_name != NULL; dem++) + { + if (strcmp (current_demangling_style_string, + dem -> demangling_style_name) == 0) + { + current_demangling_style = dem -> demangling_style; + break; + } + } + + /* Check to see if we found a match. If not, gripe about any non-empty + style name and supply a list of valid ones. FIXME: This should + probably be done with some sort of completion and with help. */ + + if (dem -> demangling_style_name == NULL) + { + if (*current_demangling_style_string != '\0') + { + printf ("Unknown demangling style `%s'.\n", + current_demangling_style_string); + } + printf ("The currently understood settings are:\n\n"); + for (dem = demanglers; dem -> demangling_style_name != NULL; dem++) + { + printf ("%-10s %s\n", dem -> demangling_style_name, + dem -> demangling_style_doc); + if (dem -> demangling_style == current_demangling_style) + { + free (current_demangling_style_string); + current_demangling_style_string = + strdup (dem -> demangling_style_name); + } + } + if (current_demangling_style == unknown_demangling) + { + /* This can happen during initialization if gdb is compiled with + a DEMANGLING_STYLE value that is unknown, so pick the first + one as the default. */ + current_demangling_style = demanglers[0].demangling_style; + current_demangling_style_string = + strdup (demanglers[0].demangling_style_name); + warning ("`%s' style demangling chosen as the default.\n", + current_demangling_style_string); + } + } +} + +/* Fake a "set demangling" command. */ + +void +set_demangling_style (style) + char *style; +{ + if (current_demangling_style_string != NULL) + { + free (current_demangling_style_string); + } + current_demangling_style_string = strdup (style); + set_demangling_command ((char *) NULL, 0); +} + +void +_initialize_demangler () +{ + struct cmd_list_element *set, *show; + + set = add_set_cmd ("demangle-style", class_support, var_string_noescape, + (char *) ¤t_demangling_style_string, + "Set the current C++ demangling style.", + &setlist); + show = add_show_from_set (set, &showlist); + set -> function.cfunc = set_demangling_command; + show -> function.cfunc = show_demangling_command; + + /* Set the default demangling style chosen at compilation time. */ + set_demangling_style (DEMANGLING_STYLE); +} diff --git a/gdb/demangle.h b/gdb/demangle.h index 71cdb80..ce50eb7 100644 --- a/gdb/demangle.h +++ b/gdb/demangle.h @@ -1,4 +1,4 @@ -/* Demangler defs for GNU C++ style demangling. +/* Defs for interface to demanglers. Copyright 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -18,3 +18,20 @@ #define DMGL_PARAMS (1 << 0) /* Include function args */ #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ + +extern enum demangling_styles +{ + unknown_demangling = 0, + auto_demangling, + gnu_demangling, + lucid_demangling, + cfront_demangling +} current_demangling_style; + +#define GNU_DEMANGLING_STYLE_STRING "gnu" +#define LUCID_DEMANGLING_STYLE_STRING "lucid" +#define CFRONT_DEMANGLING_STYLE_STRING "cfront" +#define AUTO_DEMANGLING_STYLE_STRING "auto" + +extern void +set_demangling_style PARAMS ((char *)); diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 484472d..6ba1e77 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -53,6 +53,7 @@ other things to work on, if you get bored. :-) #include "libbfd.h" /* FIXME Secret Internal BFD stuff (bfd_read) */ #include "elf/dwarf.h" #include "buildsym.h" +#include "demangle.h" #ifdef MAINTENANCE /* Define to 1 to compile in some maintenance stuff */ #define SQUAWK(stuff) dwarfwarn stuff @@ -70,6 +71,18 @@ typedef unsigned int DIE_REF; /* Reference to a DIE */ #define GCC_PRODUCER "GNU C " #endif +#ifndef GPLUS_PRODUCER +#define GPLUS_PRODUCER "GNU C++ " +#endif + +#ifndef LCC_PRODUCER +#define LCC_PRODUCER "LUCID C++ " +#endif + +#ifndef CFRONT_PRODUCER +#define CFRONT_PRODUCER "CFRONT " /* A wild a** guess... */ +#endif + #define STREQ(a,b) (strcmp(a,b)==0) #define STREQN(a,b,n) (strncmp(a,b,n)==0) @@ -302,6 +315,9 @@ static void add_enum_psymbol PARAMS ((struct dieinfo *, struct objfile *)); static void +handle_producer PARAMS ((char *)); + +static void read_file_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *)); static void @@ -1530,6 +1546,57 @@ read_func_scope (dip, thisdie, enddie, objfile) list_in_scope = &file_symbols; } + +/* + +LOCAL FUNCTION + + handle_producer -- process the AT_producer attribute + +DESCRIPTION + + Perform any operations that depend on finding a particular + AT_producer attribute. + + */ + +static void +handle_producer (producer) + char *producer; +{ + + /* If this compilation unit was compiled with g++ or gcc, then set the + processing_gcc_compilation flag. */ + + processing_gcc_compilation = + STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)) + || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)); + + /* Select a demangling style if we can identify the producer and if + the current style is auto. We leave the current style alone if it + is not auto. We also leave the demangling style alone if we find a + gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */ + +#if 0 /* Works, but is disabled for now. -fnf */ + if (current_demangling_style == auto_demangling) + { + if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))) + { + set_demangling_style (GNU_DEMANGLING_STYLE_STRING); + } + else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER))) + { + set_demangling_style (LUCID_DEMANGLING_STYLE_STRING); + } + else if (STREQN (producer, CFRONT_PRODUCER, strlen (CFRONT_PRODUCER))) + { + set_demangling_style (CFRONT_DEMANGLING_STYLE_STRING); + } + } +#endif +} + + /* LOCAL FUNCTION @@ -1570,8 +1637,7 @@ read_file_scope (dip, thisdie, enddie, objfile) } if (dip -> at_producer != NULL) { - processing_gcc_compilation = - STREQN (dip -> at_producer, GCC_PRODUCER, strlen (GCC_PRODUCER)); + handle_producer (dip -> at_producer); } numutypes = (enddie - thisdie) / 4; utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *)); |