]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/cxxfilt.c
top level:
[thirdparty/binutils-gdb.git] / binutils / cxxfilt.c
CommitLineData
bb279dc0
ZW
1/* Demangler for GNU C++ - main program
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
92f01d61 3 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
bb279dc0
ZW
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7
cbf1f5df 8 This file is part of GCC.
bb279dc0 9
cbf1f5df
NC
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
bb279dc0 14
cbf1f5df
NC
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
bb279dc0 19
cbf1f5df
NC
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING. If not, write to the Free
22 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 02110-1301, USA. */
bb279dc0
ZW
24
25#include "config.h"
26#include "bfd.h"
27#include "bucomm.h"
28#include "libiberty.h"
29#include "demangle.h"
30#include "getopt.h"
31#include "safe-ctype.h"
32
ec948987 33static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
cbf1f5df 34static int strip_underscore = TARGET_PREPENDS_UNDERSCORE;
bb279dc0 35
cbf1f5df
NC
36static const struct option long_options[] =
37{
38 {"strip-underscore", no_argument, NULL, '_'},
39 {"format", required_argument, NULL, 's'},
40 {"help", no_argument, NULL, 'h'},
41 {"no-params", no_argument, NULL, 'p'},
42 {"no-strip-underscores", no_argument, NULL, 'n'},
cbf1f5df 43 {"no-verbose", no_argument, NULL, 'i'},
ec948987 44 {"types", no_argument, NULL, 't'},
cbf1f5df
NC
45 {"version", no_argument, NULL, 'v'},
46 {NULL, no_argument, NULL, 0}
47};
bb279dc0
ZW
48
49static void
2da42df6 50demangle_it (char *mangled_name)
bb279dc0
ZW
51{
52 char *result;
cbf1f5df
NC
53 unsigned int skip_first = 0;
54
ec948987
NC
55 /* _ and $ are sometimes found at the start of function names
56 in assembler sources in order to distinguish them from other
57 names (eg register names). So skip them here. */
cbf1f5df
NC
58 if (mangled_name[0] == '.' || mangled_name[0] == '$')
59 ++skip_first;
60 if (strip_underscore && mangled_name[skip_first] == '_')
61 ++skip_first;
62
63 result = cplus_demangle (mangled_name + skip_first, flags);
bb279dc0 64
bb279dc0 65 if (result == NULL)
ec948987 66 printf (mangled_name);
bb279dc0
ZW
67 else
68 {
cbf1f5df
NC
69 if (mangled_name[0] == '.')
70 putchar ('.');
ec948987 71 printf (result);
bb279dc0
ZW
72 free (result);
73 }
74}
75
2da42df6
AJ
76static void
77print_demangler_list (FILE *stream)
bb279dc0 78{
2da42df6 79 const struct demangler_engine *demangler;
bb279dc0
ZW
80
81 fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
2da42df6 82
bb279dc0
ZW
83 for (demangler = libiberty_demanglers + 1;
84 demangler->demangling_style != unknown_demangling;
85 ++demangler)
86 fprintf (stream, ",%s", demangler->demangling_style_name);
87
88 fprintf (stream, "}");
89}
90
91static void
2da42df6 92usage (FILE *stream, int status)
bb279dc0
ZW
93{
94 fprintf (stream, "\
cbf1f5df 95Usage: %s [options] [mangled names]\n", program_name);
bb279dc0 96 fprintf (stream, "\
cbf1f5df
NC
97Options are:\n\
98 [-_|--strip-underscore] Ignore first leading underscore%s\n",
99 TARGET_PREPENDS_UNDERSCORE ? " (default)" : "");
100 fprintf (stream, "\
101 [-n|--no-strip-underscore] Do not ignore a leading underscore%s\n",
102 TARGET_PREPENDS_UNDERSCORE ? "" : " (default)");
bb279dc0 103 fprintf (stream, "\
cbf1f5df 104 [-p|--no-params] Do not display function arguments\n\
cbf1f5df 105 [-i|--no-verbose] Do not show implementation details (if any)\n\
ec948987 106 [-t|--types] Also attempt to demangle type encodings\n\
cbf1f5df 107 [-s|--format ");
bb279dc0
ZW
108 print_demangler_list (stream);
109 fprintf (stream, "]\n");
110
111 fprintf (stream, "\
cbf1f5df
NC
112 [@<file>] Read extra options from <file>\n\
113 [-h|--help] Display this information\n\
114 [-v|--version] Show the version information\n\
115Demangled names are displayed to stdout.\n\
116If a name cannot be demangled it is just echoed to stdout.\n\
117If no names are provided on the command line, stdin is read.\n");
92f01d61
JM
118 if (REPORT_BUGS_TO[0] && status == 0)
119 fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
bb279dc0
ZW
120 exit (status);
121}
122
2da42df6 123/* Return the string of non-alnum characters that may occur
bb279dc0
ZW
124 as a valid symbol component, in the standard assembler symbol
125 syntax. */
126
127static const char *
2da42df6 128standard_symbol_characters (void)
bb279dc0
ZW
129{
130 return "_$.";
131}
132
bb279dc0
ZW
133/* Return the string of non-alnum characters that may occur
134 as a valid symbol name component in an HP object file.
135
136 Note that, since HP's compiler generates object code straight from
137 C++ source, without going through an assembler, its mangled
138 identifiers can use all sorts of characters that no assembler would
139 tolerate, so the alphabet this function creates is a little odd.
140 Here are some sample mangled identifiers offered by HP:
141
142 typeid*__XT24AddressIndExpClassMember_
143 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
144 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
145
146 This still seems really weird to me, since nowhere else in this
147 file is there anything to recognize curly brackets, parens, etc.
148 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
149 this is right, but I still strongly suspect that there's a
150 misunderstanding here.
151
152 If we decide it's better for c++filt to use HP's assembler syntax
153 to scrape identifiers out of its input, here's the definition of
154 the symbol name syntax from the HP assembler manual:
155
156 Symbols are composed of uppercase and lowercase letters, decimal
157 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
158 underscore (_). A symbol can begin with a letter, digit underscore or
159 dollar sign. If a symbol begins with a digit, it must contain a
160 non-digit character.
161
162 So have fun. */
163static const char *
2da42df6 164hp_symbol_characters (void)
bb279dc0
ZW
165{
166 return "_$.<>#,*&[]:(){}";
167}
168
2da42df6 169extern int main (int, char **);
bb279dc0
ZW
170
171int
2da42df6 172main (int argc, char **argv)
bb279dc0 173{
bb279dc0
ZW
174 int c;
175 const char *valid_symbols;
176 enum demangling_styles style = auto_demangling;
177
178 program_name = argv[0];
179 xmalloc_set_program_name (program_name);
180
869b9d07
MM
181 expandargv (&argc, &argv);
182
cbf1f5df 183 while ((c = getopt_long (argc, argv, "_hinps:tv", long_options, (int *) 0)) != EOF)
bb279dc0
ZW
184 {
185 switch (c)
186 {
187 case '?':
188 usage (stderr, 1);
189 break;
190 case 'h':
191 usage (stdout, 0);
192 case 'n':
193 strip_underscore = 0;
194 break;
4e48c9dd
ILT
195 case 'p':
196 flags &= ~ DMGL_PARAMS;
197 break;
cbf1f5df 198 case 't':
ec948987 199 flags |= DMGL_TYPES;
cbf1f5df
NC
200 break;
201 case 'i':
202 flags &= ~ DMGL_VERBOSE;
203 break;
bb279dc0
ZW
204 case 'v':
205 print_version ("c++filt");
cbf1f5df 206 return 0;
bb279dc0
ZW
207 case '_':
208 strip_underscore = 1;
209 break;
210 case 's':
cbf1f5df
NC
211 style = cplus_demangle_name_to_style (optarg);
212 if (style == unknown_demangling)
213 {
214 fprintf (stderr, "%s: unknown demangling style `%s'\n",
215 program_name, optarg);
216 return 1;
217 }
218 cplus_demangle_set_style (style);
bb279dc0
ZW
219 break;
220 }
221 }
222
223 if (optind < argc)
224 {
225 for ( ; optind < argc; optind++)
ec948987
NC
226 {
227 demangle_it (argv[optind]);
228 putchar ('\n');
229 }
cbf1f5df
NC
230
231 return 0;
bb279dc0 232 }
cbf1f5df
NC
233
234 switch (current_demangling_style)
bb279dc0 235 {
cbf1f5df
NC
236 case gnu_demangling:
237 case lucid_demangling:
238 case arm_demangling:
239 case java_demangling:
240 case edg_demangling:
241 case gnat_demangling:
242 case gnu_v3_demangling:
243 case auto_demangling:
244 valid_symbols = standard_symbol_characters ();
245 break;
246 case hp_demangling:
247 valid_symbols = hp_symbol_characters ();
248 break;
249 default:
250 /* Folks should explicitly indicate the appropriate alphabet for
251 each demangling. Providing a default would allow the
252 question to go unconsidered. */
253 fatal ("Internal error: no symbol alphabet for current style");
254 }
255
256 for (;;)
257 {
258 static char mbuffer[32767];
259 unsigned i = 0;
260
261 c = getchar ();
262 /* Try to read a mangled name. */
263 while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
bb279dc0 264 {
cbf1f5df
NC
265 if (i >= sizeof (mbuffer) - 1)
266 break;
267 mbuffer[i++] = c;
268 c = getchar ();
bb279dc0
ZW
269 }
270
cbf1f5df 271 if (i > 0)
bb279dc0 272 {
cbf1f5df
NC
273 mbuffer[i] = 0;
274 demangle_it (mbuffer);
bb279dc0 275 }
ec948987 276
cbf1f5df
NC
277 if (c == EOF)
278 break;
ec948987
NC
279
280 /* Echo the whitespace characters so that the output looks
281 like the input, only with the mangled names demangled. */
282 putchar (c);
02aec879
AH
283 if (c == '\n')
284 fflush (stdout);
bb279dc0
ZW
285 }
286
ec948987 287 fflush (stdout);
cbf1f5df 288 return 0;
bb279dc0 289}