xref: /openbsd-src/gnu/usr.bin/binutils/gdb/demangle.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1e93f7393Sniklas /* Basic C++ demangling support for GDB.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
4b725ae77Skettenis    2001, 2003 Free Software Foundation, Inc.
5b725ae77Skettenis 
6e93f7393Sniklas    Written by Fred Fish at Cygnus Support.
7e93f7393Sniklas 
8e93f7393Sniklas    This file is part of GDB.
9e93f7393Sniklas 
10e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
11e93f7393Sniklas    it under the terms of the GNU General Public License as published by
12e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
13e93f7393Sniklas    (at your option) any later version.
14e93f7393Sniklas 
15e93f7393Sniklas    This program is distributed in the hope that it will be useful,
16e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
17e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18e93f7393Sniklas    GNU General Public License for more details.
19e93f7393Sniklas 
20e93f7393Sniklas    You should have received a copy of the GNU General Public License
21e93f7393Sniklas    along with this program; if not, write to the Free Software
22b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
23b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
24e93f7393Sniklas 
25e93f7393Sniklas 
26e93f7393Sniklas /*  This file contains support code for C++ demangling that is common
27e93f7393Sniklas    to a styles of demangling, and GDB specific. */
28e93f7393Sniklas 
29e93f7393Sniklas #include "defs.h"
30e93f7393Sniklas #include "command.h"
31e93f7393Sniklas #include "gdbcmd.h"
32e93f7393Sniklas #include "demangle.h"
33e93f7393Sniklas #include "gdb_string.h"
34e93f7393Sniklas 
35e93f7393Sniklas /* Select the default C++ demangling style to use.  The default is "auto",
36e93f7393Sniklas    which allows gdb to attempt to pick an appropriate demangling style for
37e93f7393Sniklas    the executable it has loaded.  It can be set to a specific style ("gnu",
38b725ae77Skettenis    "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto
39e93f7393Sniklas    selection of the style unless you do an explicit "set demangle auto".
40e93f7393Sniklas    To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in
41e93f7393Sniklas    the appropriate target configuration file. */
42e93f7393Sniklas 
43e93f7393Sniklas #ifndef DEFAULT_DEMANGLING_STYLE
44e93f7393Sniklas #define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
45e93f7393Sniklas #endif
46e93f7393Sniklas 
47b725ae77Skettenis extern void _initialize_demangler (void);
48b725ae77Skettenis 
49b725ae77Skettenis /* String name for the current demangling style.  Set by the
50b725ae77Skettenis    "set demangle-style" command, printed as part of the output by the
51b725ae77Skettenis    "show demangle-style" command. */
52e93f7393Sniklas 
53e93f7393Sniklas static char *current_demangling_style_string;
54e93f7393Sniklas 
55b725ae77Skettenis /* The array of names of the known demanglyng styles.  Generated by
56b725ae77Skettenis    _initialize_demangler from libiberty_demanglers[] array.  */
57e93f7393Sniklas 
58b725ae77Skettenis static const char **demangling_style_names;
59e93f7393Sniklas 
60b725ae77Skettenis static void set_demangling_command (char *, int, struct cmd_list_element *);
61e93f7393Sniklas 
62b725ae77Skettenis /* Set current demangling style.  Called by the "set demangle-style"
63b725ae77Skettenis    command after it has updated the current_demangling_style_string to
64b725ae77Skettenis    match what the user has entered.
65e93f7393Sniklas 
66b725ae77Skettenis    If the user has entered a string that matches a known demangling style
67e93f7393Sniklas    name in the demanglers[] array then just leave the string alone and update
68e93f7393Sniklas    the current_demangling_style enum value to match.
69e93f7393Sniklas 
70b725ae77Skettenis    If the user has entered a string that doesn't match, including an empty
71e93f7393Sniklas    string, then print a list of the currently known styles and restore
72e93f7393Sniklas    the current_demangling_style_string to match the current_demangling_style
73e93f7393Sniklas    enum value.
74e93f7393Sniklas 
75e93f7393Sniklas    Note:  Assumes that current_demangling_style_string always points to
76e93f7393Sniklas    a malloc'd string, even if it is a null-string. */
77e93f7393Sniklas 
78e93f7393Sniklas static void
set_demangling_command(char * ignore,int from_tty,struct cmd_list_element * c)79b725ae77Skettenis set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
80e93f7393Sniklas {
81b725ae77Skettenis   const struct demangler_engine *dem;
82e93f7393Sniklas 
83e93f7393Sniklas   /*  First just try to match whatever style name the user supplied with
84e93f7393Sniklas      one of the known ones.  Don't bother special casing for an empty
85e93f7393Sniklas      name, we just treat it as any other style name that doesn't match.
86e93f7393Sniklas      If we match, update the current demangling style enum. */
87e93f7393Sniklas 
88b725ae77Skettenis   for (dem = libiberty_demanglers;
89b725ae77Skettenis        dem->demangling_style != unknown_demangling;
90b725ae77Skettenis        dem++)
91e93f7393Sniklas     {
92b725ae77Skettenis       if (strcmp (current_demangling_style_string,
93b725ae77Skettenis 		  dem->demangling_style_name) == 0)
94e93f7393Sniklas 	{
95e93f7393Sniklas 	  current_demangling_style = dem->demangling_style;
96e93f7393Sniklas 	  break;
97e93f7393Sniklas 	}
98e93f7393Sniklas     }
99e93f7393Sniklas 
100e93f7393Sniklas   /* Check to see if we found a match.  If not, gripe about any non-empty
101e93f7393Sniklas      style name and supply a list of valid ones.  FIXME:  This should
102e93f7393Sniklas      probably be done with some sort of completion and with help. */
103e93f7393Sniklas 
104b725ae77Skettenis   if (dem->demangling_style == unknown_demangling)
105e93f7393Sniklas     {
106e93f7393Sniklas       if (*current_demangling_style_string != '\0')
107e93f7393Sniklas 	{
108e93f7393Sniklas 	  printf_unfiltered ("Unknown demangling style `%s'.\n",
109e93f7393Sniklas 			     current_demangling_style_string);
110e93f7393Sniklas 	}
111e93f7393Sniklas       printf_unfiltered ("The currently understood settings are:\n\n");
112b725ae77Skettenis       for (dem = libiberty_demanglers;
113b725ae77Skettenis 	   dem->demangling_style != unknown_demangling;
114b725ae77Skettenis 	   dem++)
115e93f7393Sniklas 	{
116e93f7393Sniklas 	  printf_unfiltered ("%-10s %s\n", dem->demangling_style_name,
117e93f7393Sniklas 			     dem->demangling_style_doc);
118e93f7393Sniklas 	  if (dem->demangling_style == current_demangling_style)
119e93f7393Sniklas 	    {
120b725ae77Skettenis 	      xfree (current_demangling_style_string);
121e93f7393Sniklas 	      current_demangling_style_string =
122e93f7393Sniklas 		savestring (dem->demangling_style_name,
123e93f7393Sniklas 			    strlen (dem->demangling_style_name));
124e93f7393Sniklas 	    }
125e93f7393Sniklas 	}
126e93f7393Sniklas       if (current_demangling_style == unknown_demangling)
127e93f7393Sniklas 	{
128e93f7393Sniklas 	  /* This can happen during initialization if gdb is compiled with
129e93f7393Sniklas 	     a DEMANGLING_STYLE value that is unknown, so pick the first
130e93f7393Sniklas 	     one as the default. */
131b725ae77Skettenis 	  current_demangling_style = libiberty_demanglers[0].demangling_style;
132e93f7393Sniklas 	  current_demangling_style_string =
133b725ae77Skettenis 	    savestring (
134b725ae77Skettenis               libiberty_demanglers[0].demangling_style_name,
135b725ae77Skettenis 	      strlen (libiberty_demanglers[0].demangling_style_name));
136e93f7393Sniklas 	  warning ("`%s' style demangling chosen as the default.\n",
137e93f7393Sniklas 		   current_demangling_style_string);
138e93f7393Sniklas 	}
139e93f7393Sniklas     }
140e93f7393Sniklas }
141e93f7393Sniklas 
142b725ae77Skettenis /* Fake a "set demangle-style" command. */
143e93f7393Sniklas 
144e93f7393Sniklas void
set_demangling_style(char * style)145b725ae77Skettenis set_demangling_style (char *style)
146e93f7393Sniklas {
147e93f7393Sniklas   if (current_demangling_style_string != NULL)
148e93f7393Sniklas     {
149b725ae77Skettenis       xfree (current_demangling_style_string);
150e93f7393Sniklas     }
151e93f7393Sniklas   current_demangling_style_string = savestring (style, strlen (style));
152e93f7393Sniklas   set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
153e93f7393Sniklas }
154e93f7393Sniklas 
155b725ae77Skettenis /* G++ uses a special character to indicate certain internal names.  Which
156b725ae77Skettenis    character it is depends on the platform:
157b725ae77Skettenis    - Usually '$' on systems where the assembler will accept that
158b725ae77Skettenis    - Usually '.' otherwise (this includes most sysv4-like systems and most
159b725ae77Skettenis      ELF targets)
160b725ae77Skettenis    - Occasionally '_' if neither of the above is usable
161e93f7393Sniklas 
162b725ae77Skettenis    We check '$' first because it is the safest, and '.' often has another
163b725ae77Skettenis    meaning.  We don't currently try to handle '_' because the precise forms
164b725ae77Skettenis    of the names are different on those targets.  */
165e93f7393Sniklas 
166b725ae77Skettenis static char cplus_markers[] = {'$', '.', '\0'};
167e93f7393Sniklas 
168e93f7393Sniklas int
is_cplus_marker(int c)169b725ae77Skettenis is_cplus_marker (int c)
170e93f7393Sniklas {
171e93f7393Sniklas   return c && strchr (cplus_markers, c) != NULL;
172e93f7393Sniklas }
173e93f7393Sniklas 
174e93f7393Sniklas void
_initialize_demangler(void)175b725ae77Skettenis _initialize_demangler (void)
176e93f7393Sniklas {
177e93f7393Sniklas   struct cmd_list_element *set, *show;
178b725ae77Skettenis   int i, ndems;
179e93f7393Sniklas 
180b725ae77Skettenis   /* Fill the demangling_style_names[] array.  */
181b725ae77Skettenis   for (ndems = 0;
182b725ae77Skettenis        libiberty_demanglers[ndems].demangling_style != unknown_demangling;
183b725ae77Skettenis        ndems++)
184b725ae77Skettenis     ;
185b725ae77Skettenis   demangling_style_names = xcalloc (ndems + 1, sizeof (char *));
186b725ae77Skettenis   for (i = 0;
187b725ae77Skettenis        libiberty_demanglers[i].demangling_style != unknown_demangling;
188b725ae77Skettenis        i++)
189b725ae77Skettenis     demangling_style_names[i] =
190b725ae77Skettenis       xstrdup (libiberty_demanglers[i].demangling_style_name);
191b725ae77Skettenis 
192b725ae77Skettenis   set = add_set_enum_cmd ("demangle-style", class_support,
193b725ae77Skettenis 			  demangling_style_names,
194b725ae77Skettenis 			  (const char **) &current_demangling_style_string,
195e93f7393Sniklas 			  "Set the current C++ demangling style.\n\
196e93f7393Sniklas Use `set demangle-style' without arguments for a list of demangling styles.",
197e93f7393Sniklas 			  &setlist);
198*63addd46Skettenis   show = deprecated_add_show_from_set (set, &showlist);
199b725ae77Skettenis   set_cmd_sfunc (set, set_demangling_command);
200e93f7393Sniklas 
201e93f7393Sniklas   /* Set the default demangling style chosen at compilation time. */
202e93f7393Sniklas   set_demangling_style (DEFAULT_DEMANGLING_STYLE);
203e93f7393Sniklas }
204