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