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.
createtags
dbxread.c
defs.h
+demangle.c
demangle.h
depend
doc
+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.
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.
####
# 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 \
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)
#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). */
"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 */
"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 &) */
{
int success = 1;
int func_done = 0;
-#ifdef GNU_DEMANGLING
int expect_func = 0;
-#endif
#ifndef LONGERNAMES
const char *premangle;
#endif
{
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':
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':
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)
{
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)
{
{
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))
(*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'
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
}
}
-#endif
+#endif /* main */
--- /dev/null
+/* 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);
+}
-/* 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
#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 *));
#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
#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)
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 *));
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
}
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 *));