gdbserver: include linux-arm-tdesc.h in linux-arm-tdesc.c
[deliverable/binutils-gdb.git] / libiberty / cplus-dem.c
CommitLineData
252b5132 1/* Demangler for GNU C++
82704155 2 Copyright (C) 1989-2019 Free Software Foundation, Inc.
252b5132
RH
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
7This file is part of the libiberty library.
8Libiberty is free software; you can redistribute it and/or
9modify it under the terms of the GNU Library General Public
10License as published by the Free Software Foundation; either
11version 2 of the License, or (at your option) any later version.
12
a01fefeb
DD
13In addition to the permissions in the GNU Library General Public
14License, the Free Software Foundation gives you unlimited permission
15to link the compiled version of this file into combinations with other
16programs, and to distribute those combinations without any restriction
17coming from the use of this file. (The Library Public License
18restrictions do apply in other respects; for example, they cover
19modification of the file, and distribution when not linked into a
20combined executable.)
21
252b5132
RH
22Libiberty is distributed in the hope that it will be useful,
23but WITHOUT ANY WARRANTY; without even the implied warranty of
24MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25Library General Public License for more details.
26
27You should have received a copy of the GNU Library General Public
28License along with libiberty; see the file COPYING.LIB. If
979c05d3
NC
29not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
30Boston, MA 02110-1301, USA. */
252b5132 31
252b5132
RH
32/* This file lives in both GCC and libiberty. When making changes, please
33 try not to break either. */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
ac424eb3
DD
39#include "safe-ctype.h"
40
252b5132 41#include <string.h>
252b5132
RH
42
43#ifdef HAVE_STDLIB_H
44#include <stdlib.h>
45#else
6b357a9d
DD
46void * malloc ();
47void * realloc ();
252b5132
RH
48#endif
49
50#include <demangle.h>
51#undef CURRENT_DEMANGLING_STYLE
1910070b 52#define CURRENT_DEMANGLING_STYLE options
252b5132
RH
53
54#include "libiberty.h"
f211b8c0 55#include "rust-demangle.h"
252b5132 56
e49a569c 57enum demangling_styles current_demangling_style = auto_demangling;
252b5132 58
e6450fe5 59const struct demangler_engine libiberty_demanglers[] =
eb383413 60{
2da4c07f
RH
61 {
62 NO_DEMANGLING_STYLE_STRING,
63 no_demangling,
64 "Demangling disabled"
65 }
66 ,
eb383413
L
67 {
68 AUTO_DEMANGLING_STYLE_STRING,
69 auto_demangling,
70 "Automatic selection based on executable"
71 }
72 ,
eb383413 73 {
e49a569c
DD
74 GNU_V3_DEMANGLING_STYLE_STRING,
75 gnu_v3_demangling,
1910070b 76 "GNU (g++) V3 (Itanium C++ ABI) style demangling"
eb383413
L
77 }
78 ,
16e85745
HPN
79 {
80 JAVA_DEMANGLING_STYLE_STRING,
81 java_demangling,
82 "Java style demangling"
83 }
84 ,
85 {
86 GNAT_DEMANGLING_STYLE_STRING,
87 gnat_demangling,
88 "GNAT style demangling"
89 }
90 ,
b55f9678
IB
91 {
92 DLANG_DEMANGLING_STYLE_STRING,
93 dlang_demangling,
94 "DLANG style demangling"
95 }
96 ,
535aade6
DT
97 {
98 RUST_DEMANGLING_STYLE_STRING,
99 rust_demangling,
100 "Rust style demangling"
101 }
102 ,
eb383413
L
103 {
104 NULL, unknown_demangling, NULL
105 }
106};
107
eb383413
L
108/* Add a routine to set the demangling style to be sure it is valid and
109 allow for any demangler initialization that maybe necessary. */
110
111enum demangling_styles
9334f9c6 112cplus_demangle_set_style (enum demangling_styles style)
eb383413 113{
e6450fe5 114 const struct demangler_engine *demangler = libiberty_demanglers;
eb383413
L
115
116 for (; demangler->demangling_style != unknown_demangling; ++demangler)
117 if (style == demangler->demangling_style)
118 {
119 current_demangling_style = style;
120 return current_demangling_style;
121 }
122
123 return unknown_demangling;
124}
125
126/* Do string name to style translation */
127
128enum demangling_styles
9334f9c6 129cplus_demangle_name_to_style (const char *name)
eb383413 130{
e6450fe5 131 const struct demangler_engine *demangler = libiberty_demanglers;
eb383413
L
132
133 for (; demangler->demangling_style != unknown_demangling; ++demangler)
134 if (strcmp (name, demangler->demangling_style_name) == 0)
135 return demangler->demangling_style;
136
137 return unknown_demangling;
138}
139
252b5132
RH
140/* char *cplus_demangle (const char *mangled, int options)
141
142 If MANGLED is a mangled function name produced by GNU C++, then
5d852400 143 a pointer to a @code{malloc}ed string giving a C++ representation
252b5132
RH
144 of the name will be returned; otherwise NULL will be returned.
145 It is the caller's responsibility to free the string which
146 is returned.
147
252b5132
RH
148 Note that any leading underscores, or other such characters prepended by
149 the compilation system, are presumed to have already been stripped from
150 MANGLED. */
151
152char *
9334f9c6 153cplus_demangle (const char *mangled, int options)
252b5132
RH
154{
155 char *ret;
2da4c07f
RH
156
157 if (current_demangling_style == no_demangling)
158 return xstrdup (mangled);
159
1910070b
NC
160 if ((options & DMGL_STYLE_MASK) == 0)
161 options |= (int) current_demangling_style & DMGL_STYLE_MASK;
252b5132 162
e49a569c 163 /* The V3 ABI demangling is implemented elsewhere. */
535aade6 164 if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
e49a569c 165 {
1910070b 166 ret = cplus_demangle_v3 (mangled, options);
535aade6
DT
167 if (GNU_V3_DEMANGLING)
168 return ret;
169
170 if (ret)
171 {
172 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
173 The subtitutions are always smaller, so do in place changes. */
174 if (rust_is_mangled (ret))
175 rust_demangle_sym (ret);
176 else if (RUST_DEMANGLING)
177 {
178 free (ret);
179 ret = NULL;
180 }
181 }
182
183 if (ret || RUST_DEMANGLING)
e49a569c
DD
184 return ret;
185 }
eb383413 186
bc9bf259
DD
187 if (JAVA_DEMANGLING)
188 {
189 ret = java_demangle_v3 (mangled);
190 if (ret)
191 return ret;
192 }
193
16e85745 194 if (GNAT_DEMANGLING)
6d390a9e 195 return ada_demangle (mangled, options);
16e85745 196
b55f9678
IB
197 if (DLANG_DEMANGLING)
198 {
199 ret = dlang_demangle (mangled, options);
200 if (ret)
201 return ret;
202 }
203
252b5132
RH
204 return (ret);
205}
206
535aade6
DT
207char *
208rust_demangle (const char *mangled, int options)
209{
210 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
211 char *ret = cplus_demangle_v3 (mangled, options);
212
213 /* The Rust subtitutions are always smaller, so do in place changes. */
214 if (ret != NULL)
215 {
216 if (rust_is_mangled (ret))
217 rust_demangle_sym (ret);
218 else
219 {
220 free (ret);
221 ret = NULL;
222 }
223 }
224
225 return ret;
226}
227
6d390a9e 228/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
252b5132 229
6d390a9e 230char *
9334f9c6 231ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
16e85745 232{
16e85745
HPN
233 int len0;
234 const char* p;
6d390a9e 235 char *d;
aba19b62 236 char *demangled = NULL;
16e85745 237
6d390a9e 238 /* Discard leading _ada_, which is used for library level subprograms. */
16e85745 239 if (strncmp (mangled, "_ada_", 5) == 0)
6d390a9e
DD
240 mangled += 5;
241
242 /* All ada unit names are lower-case. */
243 if (!ISLOWER (mangled[0]))
244 goto unknown;
245
246 /* Most of the demangling will trivially remove chars. Operator names
247 may add one char but because they are always preceeded by '__' which is
6a44904e
DD
248 replaced by '.', they eventually never expand the size.
249 A few special names such as '___elabs' add a few chars (at most 7), but
250 they occur only once. */
251 len0 = strlen (mangled) + 7 + 1;
6d390a9e 252 demangled = XNEWVEC (char, len0);
16e85745 253
6d390a9e
DD
254 d = demangled;
255 p = mangled;
256 while (1)
16e85745 257 {
6a44904e 258 /* An entity names is expected. */
6d390a9e
DD
259 if (ISLOWER (*p))
260 {
6a44904e 261 /* An identifier, which is always lower case. */
6d390a9e
DD
262 do
263 *d++ = *p++;
264 while (ISLOWER(*p) || ISDIGIT (*p)
265 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
266 }
267 else if (p[0] == 'O')
268 {
6a44904e 269 /* An operator name. */
6d390a9e
DD
270 static const char * const operators[][2] =
271 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
272 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
273 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
274 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
275 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
276 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
277 {"Oexpon", "**"}, {NULL, NULL}};
278 int k;
279
6a44904e 280 for (k = 0; operators[k][0] != NULL; k++)
6d390a9e 281 {
6a44904e
DD
282 size_t slen = strlen (operators[k][0]);
283 if (strncmp (p, operators[k][0], slen) == 0)
6d390a9e 284 {
6a44904e
DD
285 p += slen;
286 slen = strlen (operators[k][1]);
6d390a9e 287 *d++ = '"';
6a44904e
DD
288 memcpy (d, operators[k][1], slen);
289 d += slen;
6d390a9e
DD
290 *d++ = '"';
291 break;
292 }
293 }
294 /* Operator not found. */
6a44904e 295 if (operators[k][0] == NULL)
6d390a9e
DD
296 goto unknown;
297 }
16e85745 298 else
6d390a9e
DD
299 {
300 /* Not a GNAT encoding. */
301 goto unknown;
302 }
303
6a44904e
DD
304 /* The name can be directly followed by some uppercase letters. */
305 if (p[0] == 'T' && p[1] == 'K')
306 {
307 /* Task stuff. */
308 if (p[2] == 'B' && p[3] == 0)
309 {
310 /* Subprogram for task body. */
311 break;
312 }
313 else if (p[2] == '_' && p[3] == '_')
314 {
315 /* Inner declarations in a task. */
316 p += 4;
317 *d++ = '.';
318 continue;
319 }
320 else
321 goto unknown;
322 }
323 if (p[0] == 'E' && p[1] == 0)
324 {
325 /* Exception name. */
326 goto unknown;
327 }
328 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
329 {
330 /* Protected type subprogram. */
331 break;
332 }
333 if ((*p == 'N' || *p == 'S') && p[1] == 0)
334 {
335 /* Enumerated type name table. */
336 goto unknown;
337 }
338 if (p[0] == 'X')
339 {
340 /* Body nested. */
341 p++;
342 while (p[0] == 'n' || p[0] == 'b')
343 p++;
344 }
345 if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
346 {
347 /* Stream operations. */
348 const char *name;
349 switch (p[1])
350 {
351 case 'R':
352 name = "'Read";
353 break;
354 case 'W':
355 name = "'Write";
356 break;
357 case 'I':
358 name = "'Input";
359 break;
360 case 'O':
361 name = "'Output";
362 break;
363 default:
364 goto unknown;
365 }
366 p += 2;
367 strcpy (d, name);
368 d += strlen (name);
369 }
370 else if (p[0] == 'D')
371 {
372 /* Controlled type operation. */
373 const char *name;
374 switch (p[1])
375 {
376 case 'F':
377 name = ".Finalize";
378 break;
379 case 'A':
380 name = ".Adjust";
381 break;
382 default:
383 goto unknown;
384 }
385 strcpy (d, name);
386 d += strlen (name);
387 break;
388 }
389
6d390a9e
DD
390 if (p[0] == '_')
391 {
392 /* Separator. */
393 if (p[1] == '_')
394 {
395 /* Standard separator. Handled first. */
396 p += 2;
6a44904e 397
6d390a9e
DD
398 if (ISDIGIT (*p))
399 {
6a44904e 400 /* Overloading number. */
6d390a9e
DD
401 do
402 p++;
403 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
6a44904e
DD
404 if (*p == 'X')
405 {
406 p++;
407 while (p[0] == 'n' || p[0] == 'b')
408 p++;
409 }
6d390a9e 410 }
6a44904e 411 else if (p[0] == '_' && p[1] != '_')
6d390a9e 412 {
6a44904e
DD
413 /* Special names. */
414 static const char * const special[][2] = {
415 { "_elabb", "'Elab_Body" },
416 { "_elabs", "'Elab_Spec" },
417 { "_size", "'Size" },
418 { "_alignment", "'Alignment" },
419 { "_assign", ".\":=\"" },
420 { NULL, NULL }
421 };
422 int k;
423
424 for (k = 0; special[k][0] != NULL; k++)
425 {
426 size_t slen = strlen (special[k][0]);
427 if (strncmp (p, special[k][0], slen) == 0)
428 {
429 p += slen;
430 slen = strlen (special[k][1]);
431 memcpy (d, special[k][1], slen);
432 d += slen;
433 break;
434 }
435 }
436 if (special[k][0] != NULL)
437 break;
438 else
439 goto unknown;
6d390a9e
DD
440 }
441 else
442 {
443 *d++ = '.';
444 continue;
445 }
446 }
447 else if (p[1] == 'B' || p[1] == 'E')
448 {
449 /* Entry Body or barrier Evaluation. */
450 p += 2;
451 while (ISDIGIT (*p))
452 p++;
453 if (p[0] == 's' && p[1] == 0)
454 break;
455 else
456 goto unknown;
457 }
458 else
459 goto unknown;
460 }
461
6d390a9e
DD
462 if (p[0] == '.' && ISDIGIT (p[1]))
463 {
464 /* Nested subprogram. */
465 p += 2;
466 while (ISDIGIT (*p))
467 p++;
468 }
469 if (*p == 0)
470 {
471 /* End of mangled name. */
472 break;
473 }
16e85745 474 else
6d390a9e 475 goto unknown;
16e85745 476 }
6d390a9e
DD
477 *d = 0;
478 return demangled;
16e85745 479
6d390a9e 480 unknown:
aba19b62 481 XDELETEVEC (demangled);
6d390a9e
DD
482 len0 = strlen (mangled);
483 demangled = XNEWVEC (char, len0 + 3);
0d3deb8d 484
16e85745 485 if (mangled[0] == '<')
d0f0b69d 486 strcpy (demangled, mangled);
16e85745
HPN
487 else
488 sprintf (demangled, "<%s>", mangled);
489
490 return demangled;
491}
This page took 0.857294 seconds and 4 git commands to generate.