]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/cxxfilt.c
Don't use windows-termcap.c when linking against a curses library
[thirdparty/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);
179
869b9d07
MM
180 expandargv (&argc, &argv);
181
cbf1f5df 182 while ((c = getopt_long (argc, argv, "_hinps:tv", long_options, (int *) 0)) != EOF)
bb279dc0
ZW
183 {
184 switch (c)
185 {
186 case '?':
187 usage (stderr, 1);
188 break;
189 case 'h':
190 usage (stdout, 0);
191 case 'n':
192 strip_underscore = 0;
193 break;
4e48c9dd
ILT
194 case 'p':
195 flags &= ~ DMGL_PARAMS;
196 break;
cbf1f5df 197 case 't':
ec948987 198 flags |= DMGL_TYPES;
cbf1f5df
NC
199 break;
200 case 'i':
201 flags &= ~ DMGL_VERBOSE;
202 break;
bb279dc0
ZW
203 case 'v':
204 print_version ("c++filt");
cbf1f5df 205 return 0;
bb279dc0
ZW
206 case '_':
207 strip_underscore = 1;
208 break;
209 case 's':
cbf1f5df
NC
210 style = cplus_demangle_name_to_style (optarg);
211 if (style == unknown_demangling)
212 {
213 fprintf (stderr, "%s: unknown demangling style `%s'\n",
214 program_name, optarg);
215 return 1;
216 }
217 cplus_demangle_set_style (style);
bb279dc0
ZW
218 break;
219 }
220 }
221
222 if (optind < argc)
223 {
224 for ( ; optind < argc; optind++)
ec948987
NC
225 {
226 demangle_it (argv[optind]);
227 putchar ('\n');
228 }
cbf1f5df
NC
229
230 return 0;
bb279dc0 231 }
cbf1f5df
NC
232
233 switch (current_demangling_style)
bb279dc0 234 {
cbf1f5df
NC
235 case gnu_demangling:
236 case lucid_demangling:
237 case arm_demangling:
238 case java_demangling:
239 case edg_demangling:
240 case gnat_demangling:
241 case gnu_v3_demangling:
da37262b 242 case dlang_demangling:
cbf1f5df
NC
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}