Missing parts of fixes for in-tree libiconv
[deliverable/binutils-gdb.git] / binutils / cxxfilt.c
CommitLineData
bb279dc0 1/* Demangler for GNU C++ - main program
b90efa5b 2 Copyright (C) 1989-2015 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
90static 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:
cbf1f5df
NC
244 case auto_demangling:
245 valid_symbols = standard_symbol_characters ();
246 break;
247 case hp_demangling:
248 valid_symbols = hp_symbol_characters ();
249 break;
250 default:
251 /* Folks should explicitly indicate the appropriate alphabet for
252 each demangling. Providing a default would allow the
253 question to go unconsidered. */
254 fatal ("Internal error: no symbol alphabet for current style");
255 }
256
257 for (;;)
258 {
259 static char mbuffer[32767];
260 unsigned i = 0;
261
262 c = getchar ();
263 /* Try to read a mangled name. */
264 while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
bb279dc0 265 {
cbf1f5df
NC
266 if (i >= sizeof (mbuffer) - 1)
267 break;
268 mbuffer[i++] = c;
269 c = getchar ();
bb279dc0
ZW
270 }
271
cbf1f5df 272 if (i > 0)
bb279dc0 273 {
cbf1f5df
NC
274 mbuffer[i] = 0;
275 demangle_it (mbuffer);
bb279dc0 276 }
ec948987 277
cbf1f5df
NC
278 if (c == EOF)
279 break;
ec948987
NC
280
281 /* Echo the whitespace characters so that the output looks
282 like the input, only with the mangled names demangled. */
283 putchar (c);
02aec879
AH
284 if (c == '\n')
285 fflush (stdout);
bb279dc0
ZW
286 }
287
ec948987 288 fflush (stdout);
cbf1f5df 289 return 0;
bb279dc0 290}
This page took 0.511709 seconds and 4 git commands to generate.