]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/cplus-dem.c
Update copyright years.
[thirdparty/gcc.git] / libiberty / cplus-dem.c
CommitLineData
2363489c 1/* Demangler for GNU C++
a945c346 2 Copyright (C) 1989-2024 Free Software Foundation, Inc.
6599da04
JM
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
70d5ccef 5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
2363489c 6
6599da04
JM
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
3bf27822
MM
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
6599da04
JM
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
ee58dffd
NC
29not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
30Boston, MA 02110-1301, USA. */
6599da04 31
6599da04
JM
32/* This file lives in both GCC and libiberty. When making changes, please
33 try not to break either. */
34
a7825625
KG
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
f6bbde28
ZW
39#include "safe-ctype.h"
40
6599da04 41#include <string.h>
6599da04 42
9ee02b5c
JL
43#ifdef HAVE_STDLIB_H
44#include <stdlib.h>
a7825625 45#else
5a9340fd
SP
46void * malloc ();
47void * realloc ();
9ee02b5c
JL
48#endif
49
6599da04
JM
50#include <demangle.h>
51#undef CURRENT_DEMANGLING_STYLE
6c8120c5 52#define CURRENT_DEMANGLING_STYLE options
6599da04 53
9b1a92d8 54#include "libiberty.h"
6599da04 55
c6e13630 56enum demangling_styles current_demangling_style = auto_demangling;
6599da04 57
0be6abca 58const struct demangler_engine libiberty_demanglers[] =
24eaa47a 59{
d06ba3c7
RH
60 {
61 NO_DEMANGLING_STYLE_STRING,
62 no_demangling,
63 "Demangling disabled"
64 }
65 ,
24eaa47a
KB
66 {
67 AUTO_DEMANGLING_STYLE_STRING,
68 auto_demangling,
69 "Automatic selection based on executable"
70 }
71 ,
69afa80d 72 {
c6e13630
JM
73 GNU_V3_DEMANGLING_STYLE_STRING,
74 gnu_v3_demangling,
6c8120c5 75 "GNU (g++) V3 (Itanium C++ ABI) style demangling"
69afa80d
AS
76 }
77 ,
61ab980a
KB
78 {
79 JAVA_DEMANGLING_STYLE_STRING,
80 java_demangling,
81 "Java style demangling"
82 }
83 ,
84 {
85 GNAT_DEMANGLING_STYLE_STRING,
86 gnat_demangling,
87 "GNAT style demangling"
88 }
89 ,
43b1b9ed
IB
90 {
91 DLANG_DEMANGLING_STYLE_STRING,
92 dlang_demangling,
93 "DLANG style demangling"
94 }
95 ,
10d48c59
DT
96 {
97 RUST_DEMANGLING_STYLE_STRING,
98 rust_demangling,
99 "Rust style demangling"
100 }
101 ,
24eaa47a
KB
102 {
103 NULL, unknown_demangling, NULL
104 }
105};
106
24eaa47a
KB
107/* Add a routine to set the demangling style to be sure it is valid and
108 allow for any demangler initialization that maybe necessary. */
109
110enum demangling_styles
500d7701 111cplus_demangle_set_style (enum demangling_styles style)
24eaa47a 112{
0be6abca 113 const struct demangler_engine *demangler = libiberty_demanglers;
24eaa47a
KB
114
115 for (; demangler->demangling_style != unknown_demangling; ++demangler)
116 if (style == demangler->demangling_style)
117 {
118 current_demangling_style = style;
119 return current_demangling_style;
120 }
121
122 return unknown_demangling;
123}
124
125/* Do string name to style translation */
126
127enum demangling_styles
500d7701 128cplus_demangle_name_to_style (const char *name)
24eaa47a 129{
0be6abca 130 const struct demangler_engine *demangler = libiberty_demanglers;
24eaa47a
KB
131
132 for (; demangler->demangling_style != unknown_demangling; ++demangler)
133 if (strcmp (name, demangler->demangling_style_name) == 0)
134 return demangler->demangling_style;
135
136 return unknown_demangling;
137}
138
6599da04
JM
139/* char *cplus_demangle (const char *mangled, int options)
140
141 If MANGLED is a mangled function name produced by GNU C++, then
5bed56d9 142 a pointer to a @code{malloc}ed string giving a C++ representation
6599da04
JM
143 of the name will be returned; otherwise NULL will be returned.
144 It is the caller's responsibility to free the string which
145 is returned.
146
6599da04
JM
147 Note that any leading underscores, or other such characters prepended by
148 the compilation system, are presumed to have already been stripped from
149 MANGLED. */
150
151char *
500d7701 152cplus_demangle (const char *mangled, int options)
6599da04 153{
5e5199e8 154 char *ret;
d06ba3c7
RH
155
156 if (current_demangling_style == no_demangling)
157 return xstrdup (mangled);
158
6c8120c5
JM
159 if ((options & DMGL_STYLE_MASK) == 0)
160 options |= (int) current_demangling_style & DMGL_STYLE_MASK;
5e5199e8 161
32fc3719
EMB
162 /* The Rust demangling is implemented elsewhere.
163 Legacy Rust symbols overlap with GNU_V3, so try Rust first. */
164 if (RUST_DEMANGLING || AUTO_DEMANGLING)
165 {
166 ret = rust_demangle (mangled, options);
167 if (ret || RUST_DEMANGLING)
168 return ret;
169 }
170
c6e13630 171 /* The V3 ABI demangling is implemented elsewhere. */
32fc3719 172 if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
c6e13630 173 {
6c8120c5 174 ret = cplus_demangle_v3 (mangled, options);
32fc3719 175 if (ret || GNU_V3_DEMANGLING)
c6e13630
JM
176 return ret;
177 }
69afa80d 178
3b60dd8e
BM
179 if (JAVA_DEMANGLING)
180 {
181 ret = java_demangle_v3 (mangled);
182 if (ret)
183 return ret;
184 }
185
61ab980a 186 if (GNAT_DEMANGLING)
5b40c067 187 return ada_demangle (mangled, options);
61ab980a 188
43b1b9ed
IB
189 if (DLANG_DEMANGLING)
190 {
191 ret = dlang_demangle (mangled, options);
192 if (ret)
193 return ret;
194 }
195
5e5199e8
AM
196 return (ret);
197}
5e5199e8 198
5b40c067 199/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
2363489c 200
5b40c067 201char *
500d7701 202ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
61ab980a 203{
61ab980a
KB
204 int len0;
205 const char* p;
5b40c067 206 char *d;
a3f3eec0 207 char *demangled = NULL;
61ab980a 208
5b40c067 209 /* Discard leading _ada_, which is used for library level subprograms. */
61ab980a 210 if (strncmp (mangled, "_ada_", 5) == 0)
5b40c067
TG
211 mangled += 5;
212
213 /* All ada unit names are lower-case. */
214 if (!ISLOWER (mangled[0]))
215 goto unknown;
216
217 /* Most of the demangling will trivially remove chars. Operator names
218 may add one char but because they are always preceeded by '__' which is
a69d9775
TG
219 replaced by '.', they eventually never expand the size.
220 A few special names such as '___elabs' add a few chars (at most 7), but
221 they occur only once. */
222 len0 = strlen (mangled) + 7 + 1;
5b40c067 223 demangled = XNEWVEC (char, len0);
61ab980a 224
5b40c067
TG
225 d = demangled;
226 p = mangled;
227 while (1)
61ab980a 228 {
a69d9775 229 /* An entity names is expected. */
5b40c067
TG
230 if (ISLOWER (*p))
231 {
a69d9775 232 /* An identifier, which is always lower case. */
5b40c067
TG
233 do
234 *d++ = *p++;
235 while (ISLOWER(*p) || ISDIGIT (*p)
236 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
237 }
238 else if (p[0] == 'O')
239 {
a69d9775 240 /* An operator name. */
5b40c067
TG
241 static const char * const operators[][2] =
242 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
243 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
244 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
245 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
246 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
247 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
248 {"Oexpon", "**"}, {NULL, NULL}};
249 int k;
250
a69d9775 251 for (k = 0; operators[k][0] != NULL; k++)
5b40c067 252 {
a69d9775
TG
253 size_t slen = strlen (operators[k][0]);
254 if (strncmp (p, operators[k][0], slen) == 0)
5b40c067 255 {
a69d9775
TG
256 p += slen;
257 slen = strlen (operators[k][1]);
5b40c067 258 *d++ = '"';
a69d9775
TG
259 memcpy (d, operators[k][1], slen);
260 d += slen;
5b40c067
TG
261 *d++ = '"';
262 break;
263 }
264 }
265 /* Operator not found. */
a69d9775 266 if (operators[k][0] == NULL)
5b40c067
TG
267 goto unknown;
268 }
61ab980a 269 else
5b40c067
TG
270 {
271 /* Not a GNAT encoding. */
272 goto unknown;
273 }
274
a69d9775
TG
275 /* The name can be directly followed by some uppercase letters. */
276 if (p[0] == 'T' && p[1] == 'K')
277 {
278 /* Task stuff. */
279 if (p[2] == 'B' && p[3] == 0)
280 {
281 /* Subprogram for task body. */
282 break;
283 }
284 else if (p[2] == '_' && p[3] == '_')
285 {
286 /* Inner declarations in a task. */
287 p += 4;
288 *d++ = '.';
289 continue;
290 }
291 else
292 goto unknown;
293 }
294 if (p[0] == 'E' && p[1] == 0)
295 {
296 /* Exception name. */
297 goto unknown;
298 }
299 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
300 {
301 /* Protected type subprogram. */
302 break;
303 }
304 if ((*p == 'N' || *p == 'S') && p[1] == 0)
305 {
306 /* Enumerated type name table. */
307 goto unknown;
308 }
309 if (p[0] == 'X')
310 {
311 /* Body nested. */
312 p++;
313 while (p[0] == 'n' || p[0] == 'b')
314 p++;
315 }
316 if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
317 {
318 /* Stream operations. */
319 const char *name;
320 switch (p[1])
321 {
322 case 'R':
323 name = "'Read";
324 break;
325 case 'W':
326 name = "'Write";
327 break;
328 case 'I':
329 name = "'Input";
330 break;
331 case 'O':
332 name = "'Output";
333 break;
334 default:
335 goto unknown;
336 }
337 p += 2;
338 strcpy (d, name);
339 d += strlen (name);
340 }
341 else if (p[0] == 'D')
342 {
343 /* Controlled type operation. */
344 const char *name;
345 switch (p[1])
346 {
347 case 'F':
348 name = ".Finalize";
349 break;
350 case 'A':
351 name = ".Adjust";
352 break;
353 default:
354 goto unknown;
355 }
356 strcpy (d, name);
357 d += strlen (name);
358 break;
359 }
360
5b40c067
TG
361 if (p[0] == '_')
362 {
363 /* Separator. */
364 if (p[1] == '_')
365 {
366 /* Standard separator. Handled first. */
367 p += 2;
a69d9775 368
5b40c067
TG
369 if (ISDIGIT (*p))
370 {
a69d9775 371 /* Overloading number. */
5b40c067
TG
372 do
373 p++;
374 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
a69d9775
TG
375 if (*p == 'X')
376 {
377 p++;
378 while (p[0] == 'n' || p[0] == 'b')
379 p++;
380 }
5b40c067 381 }
a69d9775 382 else if (p[0] == '_' && p[1] != '_')
5b40c067 383 {
a69d9775
TG
384 /* Special names. */
385 static const char * const special[][2] = {
386 { "_elabb", "'Elab_Body" },
387 { "_elabs", "'Elab_Spec" },
388 { "_size", "'Size" },
389 { "_alignment", "'Alignment" },
390 { "_assign", ".\":=\"" },
391 { NULL, NULL }
392 };
393 int k;
394
395 for (k = 0; special[k][0] != NULL; k++)
396 {
397 size_t slen = strlen (special[k][0]);
398 if (strncmp (p, special[k][0], slen) == 0)
399 {
400 p += slen;
401 slen = strlen (special[k][1]);
402 memcpy (d, special[k][1], slen);
403 d += slen;
404 break;
405 }
406 }
407 if (special[k][0] != NULL)
408 break;
409 else
410 goto unknown;
5b40c067
TG
411 }
412 else
413 {
414 *d++ = '.';
415 continue;
416 }
417 }
418 else if (p[1] == 'B' || p[1] == 'E')
419 {
420 /* Entry Body or barrier Evaluation. */
421 p += 2;
422 while (ISDIGIT (*p))
423 p++;
424 if (p[0] == 's' && p[1] == 0)
425 break;
426 else
427 goto unknown;
428 }
429 else
430 goto unknown;
431 }
432
5b40c067
TG
433 if (p[0] == '.' && ISDIGIT (p[1]))
434 {
435 /* Nested subprogram. */
436 p += 2;
437 while (ISDIGIT (*p))
438 p++;
439 }
440 if (*p == 0)
441 {
442 /* End of mangled name. */
443 break;
444 }
61ab980a 445 else
5b40c067 446 goto unknown;
61ab980a 447 }
5b40c067
TG
448 *d = 0;
449 return demangled;
61ab980a 450
5b40c067 451 unknown:
a3f3eec0 452 XDELETEVEC (demangled);
5b40c067
TG
453 len0 = strlen (mangled);
454 demangled = XNEWVEC (char, len0 + 3);
de78f58b 455
61ab980a
KB
456 if (mangled[0] == '<')
457 strcpy (demangled, mangled);
458 else
459 sprintf (demangled, "<%s>", mangled);
460
461 return demangled;
462}