]> gcc.gnu.org Git - gcc.git/blame - gcc/cplus-dem.c
(jump_optimize): Insert conditional move after jump insn instead of
[gcc.git] / gcc / cplus-dem.c
CommitLineData
a3184468 1/* Demangler for GNU C++
47fd14f4 2 Copyright 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
a3184468
JM
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5
6This file is part of the libiberty library.
7Libiberty is free software; you can redistribute it and/or
8modify it under the terms of the GNU Library General Public
9License as published by the Free Software Foundation; either
10version 2 of the License, or (at your option) any later version.
11
12Libiberty is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15Library General Public License for more details.
16
17You should have received a copy of the GNU Library General Public
18License along with libiberty; see the file COPYING.LIB. If
940d9d63
RK
19not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a3184468
JM
21
22/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
23
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
0f41302f 26 available memory. */
a3184468
JM
27
28#include <ctype.h>
29#include <string.h>
30#include <stdio.h>
31
32#include <demangle.h>
33#undef CURRENT_DEMANGLING_STYLE
34#define CURRENT_DEMANGLING_STYLE work->options
35
36extern char *xmalloc PARAMS((unsigned));
37extern char *xrealloc PARAMS((char *, unsigned));
a3184468 38
c4b5dcfb 39char *
f83d4617 40mystrstr (s1, s2)
c4b5dcfb
RK
41 char *s1, *s2;
42{
43 register char *p = s1;
c4b5dcfb
RK
44 register int len = strlen (s2);
45
46 for (; (p = strchr (p, *s2)) != 0; p++)
47 {
48 if (strncmp (p, s2, len) == 0)
49 {
50 return (p);
51 }
52 }
53 return (0);
54}
c4b5dcfb 55
a3184468
JM
56/* In order to allow a single demangler executable to demangle strings
57 using various common values of CPLUS_MARKER, as well as any specific
58 one set at compile time, we maintain a string containing all the
59 commonly used ones, and check to see if the marker we are looking for
60 is in that string. CPLUS_MARKER is usually '$' on systems where the
61 assembler can deal with that. Where the assembler can't, it's usually
62 '.' (but on many systems '.' is used for other things). We put the
63 current defined CPLUS_MARKER first (which defaults to '$'), followed
64 by the next most common value, followed by an explicit '$' in case
65 the value of CPLUS_MARKER is not '$'.
66
67 We could avoid this if we could just get g++ to tell us what the actual
68 cplus marker character is as part of the debug information, perhaps by
69 ensuring that it is the character that terminates the gcc<n>_compiled
0f41302f 70 marker symbol (FIXME). */
a3184468
JM
71
72#if !defined (CPLUS_MARKER)
73#define CPLUS_MARKER '$'
74#endif
75
76enum demangling_styles current_demangling_style = gnu_demangling;
77
78static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
79
80void
81set_cplus_marker_for_demangling (ch)
82 int ch;
83{
84 cplus_markers[0] = ch;
85}
86
87/* Stuff that is shared between sub-routines.
0f41302f 88 Using a shared structure allows cplus_demangle to be reentrant. */
a3184468
JM
89
90struct work_stuff
91{
92 int options;
93 char **typevec;
94 int ntypes;
95 int typevec_size;
96 int constructor;
97 int destructor;
98 int static_type; /* A static member function */
99 int const_type; /* A const member function */
100};
101
102#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
103#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
104
105static const struct optable
106{
107 const char *in;
108 const char *out;
109 int flags;
110} optable[] = {
111 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
112 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
113 {"new", " new", 0}, /* old (1.91, and 1.x) */
114 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
115 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
116 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
117 {"as", "=", DMGL_ANSI}, /* ansi */
118 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
119 {"eq", "==", DMGL_ANSI}, /* old, ansi */
120 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
121 {"gt", ">", DMGL_ANSI}, /* old, ansi */
122 {"le", "<=", DMGL_ANSI}, /* old, ansi */
123 {"lt", "<", DMGL_ANSI}, /* old, ansi */
124 {"plus", "+", 0}, /* old */
125 {"pl", "+", DMGL_ANSI}, /* ansi */
126 {"apl", "+=", DMGL_ANSI}, /* ansi */
127 {"minus", "-", 0}, /* old */
128 {"mi", "-", DMGL_ANSI}, /* ansi */
129 {"ami", "-=", DMGL_ANSI}, /* ansi */
130 {"mult", "*", 0}, /* old */
131 {"ml", "*", DMGL_ANSI}, /* ansi */
132 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
133 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
134 {"convert", "+", 0}, /* old (unary +) */
135 {"negate", "-", 0}, /* old (unary -) */
136 {"trunc_mod", "%", 0}, /* old */
137 {"md", "%", DMGL_ANSI}, /* ansi */
138 {"amd", "%=", DMGL_ANSI}, /* ansi */
139 {"trunc_div", "/", 0}, /* old */
140 {"dv", "/", DMGL_ANSI}, /* ansi */
141 {"adv", "/=", DMGL_ANSI}, /* ansi */
142 {"truth_andif", "&&", 0}, /* old */
143 {"aa", "&&", DMGL_ANSI}, /* ansi */
144 {"truth_orif", "||", 0}, /* old */
145 {"oo", "||", DMGL_ANSI}, /* ansi */
146 {"truth_not", "!", 0}, /* old */
147 {"nt", "!", DMGL_ANSI}, /* ansi */
148 {"postincrement","++", 0}, /* old */
149 {"pp", "++", DMGL_ANSI}, /* ansi */
150 {"postdecrement","--", 0}, /* old */
151 {"mm", "--", DMGL_ANSI}, /* ansi */
152 {"bit_ior", "|", 0}, /* old */
153 {"or", "|", DMGL_ANSI}, /* ansi */
154 {"aor", "|=", DMGL_ANSI}, /* ansi */
155 {"bit_xor", "^", 0}, /* old */
156 {"er", "^", DMGL_ANSI}, /* ansi */
157 {"aer", "^=", DMGL_ANSI}, /* ansi */
158 {"bit_and", "&", 0}, /* old */
159 {"ad", "&", DMGL_ANSI}, /* ansi */
160 {"aad", "&=", DMGL_ANSI}, /* ansi */
161 {"bit_not", "~", 0}, /* old */
162 {"co", "~", DMGL_ANSI}, /* ansi */
163 {"call", "()", 0}, /* old */
164 {"cl", "()", DMGL_ANSI}, /* ansi */
165 {"alshift", "<<", 0}, /* old */
166 {"ls", "<<", DMGL_ANSI}, /* ansi */
167 {"als", "<<=", DMGL_ANSI}, /* ansi */
168 {"arshift", ">>", 0}, /* old */
169 {"rs", ">>", DMGL_ANSI}, /* ansi */
170 {"ars", ">>=", DMGL_ANSI}, /* ansi */
171 {"component", "->", 0}, /* old */
172 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
173 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
174 {"indirect", "*", 0}, /* old */
175 {"method_call", "->()", 0}, /* old */
176 {"addr", "&", 0}, /* old (unary &) */
177 {"array", "[]", 0}, /* old */
178 {"vc", "[]", DMGL_ANSI}, /* ansi */
179 {"compound", ", ", 0}, /* old */
180 {"cm", ", ", DMGL_ANSI}, /* ansi */
181 {"cond", "?:", 0}, /* old */
ddd5a7c1 182 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
a3184468 183 {"max", ">?", 0}, /* old */
ddd5a7c1 184 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
a3184468 185 {"min", "<?", 0}, /* old */
ddd5a7c1 186 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
a3184468
JM
187 {"nop", "", 0}, /* old (for operator=) */
188 {"rm", "->*", DMGL_ANSI} /* ansi */
189};
190
191
192typedef struct string /* Beware: these aren't required to be */
0f41302f 193{ /* '\0' terminated. */
a3184468
JM
194 char *b; /* pointer to start of string */
195 char *p; /* pointer after last character */
196 char *e; /* pointer after end of allocated space */
197} string;
198
199#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
200#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
201 string_prepend(str, " ");}
202#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
203 string_append(str, " ");}
204
205#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
206#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
207
208/* Prototypes for local functions */
209
210static char *
211mop_up PARAMS ((struct work_stuff *, string *, int));
212
213#if 0
214static int
215demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
216#endif
217
218static int
219demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
220 string *));
221
222static int
223demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
224 int, int));
225
226static int
227demangle_class PARAMS ((struct work_stuff *, const char **, string *));
228
229static int
230demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
231
232static int
233demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
234
235static int
236demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
237
238static int
239gnu_special PARAMS ((struct work_stuff *, const char **, string *));
240
241static int
242arm_special PARAMS ((struct work_stuff *, const char **, string *));
243
244static void
245string_need PARAMS ((string *, int));
246
247static void
248string_delete PARAMS ((string *));
249
250static void
251string_init PARAMS ((string *));
252
253static void
254string_clear PARAMS ((string *));
255
256#if 0
257static int
258string_empty PARAMS ((string *));
259#endif
260
261static void
262string_append PARAMS ((string *, const char *));
263
264static void
265string_appends PARAMS ((string *, string *));
266
267static void
268string_appendn PARAMS ((string *, const char *, int));
269
270static void
271string_prepend PARAMS ((string *, const char *));
272
273static void
274string_prependn PARAMS ((string *, const char *, int));
275
276static int
277get_count PARAMS ((const char **, int *));
278
279static int
280consume_count PARAMS ((const char **));
281
282static int
283demangle_args PARAMS ((struct work_stuff *, const char **, string *));
284
285static int
286do_type PARAMS ((struct work_stuff *, const char **, string *));
287
288static int
289do_arg PARAMS ((struct work_stuff *, const char **, string *));
290
291static void
292demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
293 const char *));
294
295static void
296remember_type PARAMS ((struct work_stuff *, const char *, int));
297
298static void
299forget_types PARAMS ((struct work_stuff *));
300
301static void
302string_prepends PARAMS ((string *, string *));
303
304/* Translate count to integer, consuming tokens in the process.
305 Conversion terminates on the first non-digit character.
306 Trying to consume something that isn't a count results in
0f41302f 307 no consumption of input and a return of 0. */
a3184468
JM
308
309static int
310consume_count (type)
311 const char **type;
312{
313 int count = 0;
314
315 while (isdigit (**type))
316 {
317 count *= 10;
318 count += **type - '0';
319 (*type)++;
320 }
321 return (count);
322}
323
324int
325cplus_demangle_opname (opname, result, options)
47fd14f4 326 const char *opname;
a3184468
JM
327 char *result;
328 int options;
329{
330 int len, i, len1, ret;
331 string type;
332 struct work_stuff work[1];
333 const char *tem;
334
335 len = strlen(opname);
336 result[0] = '\0';
337 ret = 0;
338 work->options = options;
339
340 if (opname[0] == '_' && opname[1] == '_'
341 && opname[2] == 'o' && opname[3] == 'p')
342 {
343 /* ANSI. */
344 /* type conversion operator. */
345 tem = opname + 4;
346 if (do_type (work, &tem, &type))
347 {
348 strcat (result, "operator ");
349 strncat (result, type.b, type.p - type.b);
350 string_delete (&type);
351 ret = 1;
352 }
353 }
354 else if (opname[0] == '_' && opname[1] == '_'
355 && opname[2] >= 'a' && opname[2] <= 'z'
356 && opname[3] >= 'a' && opname[3] <= 'z')
357 {
358 if (opname[4] == '\0')
359 {
360 /* Operator. */
361 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
362 {
363 if (strlen (optable[i].in) == 2
364 && memcmp (optable[i].in, opname + 2, 2) == 0)
365 {
366 strcat (result, "operator");
367 strcat (result, optable[i].out);
368 ret = 1;
369 break;
370 }
371 }
372 }
373 else
374 {
375 if (opname[2] == 'a' && opname[5] == '\0')
376 {
0f41302f 377 /* Assignment. */
a3184468
JM
378 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
379 {
380 if (strlen (optable[i].in) == 3
381 && memcmp (optable[i].in, opname + 2, 3) == 0)
382 {
383 strcat (result, "operator");
384 strcat (result, optable[i].out);
385 ret = 1;
386 break;
387 }
388 }
389 }
390 }
391 }
392 else if (len >= 3
393 && opname[0] == 'o'
394 && opname[1] == 'p'
395 && strchr (cplus_markers, opname[2]) != NULL)
396 {
397 /* see if it's an assignment expression */
398 if (len >= 10 /* op$assign_ */
399 && memcmp (opname + 3, "assign_", 7) == 0)
400 {
401 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
402 {
403 len1 = len - 10;
404 if (strlen (optable[i].in) == len1
405 && memcmp (optable[i].in, opname + 10, len1) == 0)
406 {
407 strcat (result, "operator");
408 strcat (result, optable[i].out);
409 strcat (result, "=");
410 ret = 1;
411 break;
412 }
413 }
414 }
415 else
416 {
417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
418 {
419 len1 = len - 3;
420 if (strlen (optable[i].in) == len1
421 && memcmp (optable[i].in, opname + 3, len1) == 0)
422 {
423 strcat (result, "operator");
424 strcat (result, optable[i].out);
425 ret = 1;
426 break;
427 }
428 }
429 }
430 }
431 else if (len >= 5 && memcmp (opname, "type", 4) == 0
432 && strchr (cplus_markers, opname[4]) != NULL)
433 {
434 /* type conversion operator */
435 tem = opname + 5;
436 if (do_type (work, &tem, &type))
437 {
438 strcat (result, "operator ");
439 strncat (result, type.b, type.p - type.b);
440 string_delete (&type);
441 ret = 1;
442 }
443 }
444 return ret;
445
446}
447/* Takes operator name as e.g. "++" and returns mangled
448 operator name (e.g. "postincrement_expr"), or NULL if not found.
449
450 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
451 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
452
47fd14f4 453const char *
a3184468 454cplus_mangle_opname (opname, options)
47fd14f4 455 const char *opname;
a3184468
JM
456 int options;
457{
458 int i;
459 int len;
460
461 len = strlen (opname);
462 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
463 {
464 if (strlen (optable[i].out) == len
465 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
466 && memcmp (optable[i].out, opname, len) == 0)
47fd14f4 467 return optable[i].in;
a3184468
JM
468 }
469 return (0);
470}
471
0f41302f
MS
472/* Check to see whether MANGLED can match TEXT in the first TEXT_LEN
473 characters. */
a3184468
JM
474
475int cplus_match (mangled, text, text_len)
476 const char *mangled;
477 char *text;
478 int text_len;
479{
480 if (strncmp (mangled, text, text_len) != 0) {
481 return(0); /* cannot match either */
482 } else {
483 return(1); /* matches mangled, may match demangled */
484 }
485}
486
487/* char *cplus_demangle (const char *mangled, int options)
488
489 If MANGLED is a mangled function name produced by GNU C++, then
490 a pointer to a malloced string giving a C++ representation
491 of the name will be returned; otherwise NULL will be returned.
492 It is the caller's responsibility to free the string which
493 is returned.
494
495 The OPTIONS arg may contain one or more of the following bits:
496
497 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
498 included.
499 DMGL_PARAMS Function parameters are included.
500
501 For example,
502
503 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
504 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
505 cplus_demangle ("foo__1Ai", 0) => "A::foo"
506
507 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
508 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
509 cplus_demangle ("foo__1Afe", 0) => "A::foo"
510
511 Note that any leading underscores, or other such characters prepended by
512 the compilation system, are presumed to have already been stripped from
513 MANGLED. */
514
515char *
516cplus_demangle (mangled, options)
517 const char *mangled;
518 int options;
519{
520 string decl;
521 int success = 0;
522 struct work_stuff work[1];
523 char *demangled = NULL;
524
525 if ((mangled != NULL) && (*mangled != '\0'))
526 {
527 memset ((char *) work, 0, sizeof (work));
528 work -> options = options;
529 if ((work->options & DMGL_STYLE_MASK) == 0)
530 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
531
532 string_init (&decl);
533
534 /* First check to see if gnu style demangling is active and if the
535 string to be demangled contains a CPLUS_MARKER. If so, attempt to
536 recognize one of the gnu special forms rather than looking for a
537 standard prefix. In particular, don't worry about whether there
538 is a "__" string in the mangled string. Consider "_$_5__foo" for
0f41302f 539 example. */
a3184468
JM
540
541 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
542 {
543 success = gnu_special (work, &mangled, &decl);
544 }
545 if (!success)
546 {
547 success = demangle_prefix (work, &mangled, &decl);
548 }
549 if (success && (*mangled != '\0'))
550 {
551 success = demangle_signature (work, &mangled, &decl);
552 }
553 if (work->constructor == 2)
554 {
555 string_prepend(&decl, "global constructors keyed to ");
556 work->constructor = 0;
557 }
558 else if (work->destructor == 2)
559 {
560 string_prepend(&decl, "global destructors keyed to ");
561 work->destructor = 0;
562 }
563 demangled = mop_up (work, &decl, success);
564 }
565 return (demangled);
566}
567
568static char *
569mop_up (work, declp, success)
570 struct work_stuff *work;
571 string *declp;
572 int success;
573{
574 char *demangled = NULL;
575
0f41302f 576 /* Discard the remembered types, if any. */
a3184468
JM
577
578 forget_types (work);
579 if (work -> typevec != NULL)
580 {
581 free ((char *) work -> typevec);
582 }
583
584 /* If demangling was successful, ensure that the demangled string is null
0f41302f 585 terminated and return it. Otherwise, free the demangling decl. */
a3184468
JM
586
587 if (!success)
588 {
589 string_delete (declp);
590 }
591 else
592 {
593 string_appendn (declp, "", 1);
594 demangled = declp -> b;
595 }
596 return (demangled);
597}
598
599/*
600
601LOCAL FUNCTION
602
603 demangle_signature -- demangle the signature part of a mangled name
604
605SYNOPSIS
606
607 static int
608 demangle_signature (struct work_stuff *work, const char **mangled,
609 string *declp);
610
611DESCRIPTION
612
613 Consume and demangle the signature portion of the mangled name.
614
615 DECLP is the string where demangled output is being built. At
616 entry it contains the demangled root name from the mangled name
617 prefix. I.E. either a demangled operator name or the root function
618 name. In some special cases, it may contain nothing.
619
620 *MANGLED points to the current unconsumed location in the mangled
621 name. As tokens are consumed and demangling is performed, the
622 pointer is updated to continuously point at the next token to
623 be consumed.
624
625 Demangling GNU style mangled names is nasty because there is no
626 explicit token that marks the start of the outermost function
0f41302f 627 argument list. */
a3184468
JM
628
629static int
630demangle_signature (work, mangled, declp)
631 struct work_stuff *work;
632 const char **mangled;
633 string *declp;
634{
635 int success = 1;
636 int func_done = 0;
637 int expect_func = 0;
638 const char *oldmangled = NULL;
639 string trawname;
640 string tname;
641
642 while (success && (**mangled != '\0'))
643 {
644 switch (**mangled)
645 {
646 case 'Q':
647 oldmangled = *mangled;
648 success = demangle_qualified (work, mangled, declp, 1, 0);
649 if (success)
650 {
651 remember_type (work, oldmangled, *mangled - oldmangled);
652 }
653 if (AUTO_DEMANGLING || GNU_DEMANGLING)
654 {
655 expect_func = 1;
656 }
657 oldmangled = NULL;
658 break;
659
660 case 'S':
661 /* Static member function */
662 if (oldmangled == NULL)
663 {
664 oldmangled = *mangled;
665 }
666 (*mangled)++;
667 work -> static_type = 1;
668 break;
669
670 case 'C':
671 /* a const member function */
672 if (oldmangled == NULL)
673 {
674 oldmangled = *mangled;
675 }
676 (*mangled)++;
677 work -> const_type = 1;
678 break;
679
680 case '0': case '1': case '2': case '3': case '4':
681 case '5': case '6': case '7': case '8': case '9':
682 if (oldmangled == NULL)
683 {
684 oldmangled = *mangled;
685 }
686 success = demangle_class (work, mangled, declp);
687 if (success)
688 {
689 remember_type (work, oldmangled, *mangled - oldmangled);
690 }
691 if (AUTO_DEMANGLING || GNU_DEMANGLING)
692 {
693 expect_func = 1;
694 }
695 oldmangled = NULL;
696 break;
697
698 case 'F':
699 /* Function */
700 /* ARM style demangling includes a specific 'F' character after
701 the class name. For GNU style, it is just implied. So we can
702 safely just consume any 'F' at this point and be compatible
0f41302f 703 with either style. */
a3184468
JM
704
705 oldmangled = NULL;
706 func_done = 1;
707 (*mangled)++;
708
709 /* For lucid/ARM style we have to forget any types we might
710 have remembered up to this point, since they were not argument
711 types. GNU style considers all types seen as available for
712 back references. See comment in demangle_args() */
713
714 if (LUCID_DEMANGLING || ARM_DEMANGLING)
715 {
716 forget_types (work);
717 }
718 success = demangle_args (work, mangled, declp);
719 break;
720
721 case 't':
722 /* G++ Template */
723 string_init(&trawname);
724 string_init(&tname);
725 if (oldmangled == NULL)
726 {
727 oldmangled = *mangled;
728 }
729 success = demangle_template (work, mangled, &tname, &trawname);
730 if (success)
731 {
732 remember_type (work, oldmangled, *mangled - oldmangled);
733 }
734 string_append(&tname, "::");
735 string_prepends(declp, &tname);
736 if (work -> destructor & 1)
737 {
738 string_prepend (&trawname, "~");
739 string_appends (declp, &trawname);
740 work->destructor -= 1;
741 }
742 if ((work->constructor & 1) || (work->destructor & 1))
743 {
744 string_appends (declp, &trawname);
745 work->constructor -= 1;
746 }
747 string_delete(&trawname);
748 string_delete(&tname);
749 oldmangled = NULL;
750 expect_func = 1;
751 break;
752
753 case '_':
754 /* At the outermost level, we cannot have a return type specified,
755 so if we run into another '_' at this point we are dealing with
756 a mangled name that is either bogus, or has been mangled by
757 some algorithm we don't know how to deal with. So just
0f41302f 758 reject the entire demangling. */
a3184468
JM
759 success = 0;
760 break;
761
762 default:
763 if (AUTO_DEMANGLING || GNU_DEMANGLING)
764 {
765 /* Assume we have stumbled onto the first outermost function
0f41302f 766 argument token, and start processing args. */
a3184468
JM
767 func_done = 1;
768 success = demangle_args (work, mangled, declp);
769 }
770 else
771 {
772 /* Non-GNU demanglers use a specific token to mark the start
773 of the outermost function argument tokens. Typically 'F',
774 for ARM-demangling, for example. So if we find something
0f41302f 775 we are not prepared for, it must be an error. */
a3184468
JM
776 success = 0;
777 }
778 break;
779 }
780/*
781 if (AUTO_DEMANGLING || GNU_DEMANGLING)
782*/
783 {
784 if (success && expect_func)
785 {
786 func_done = 1;
787 success = demangle_args (work, mangled, declp);
788 }
789 }
790 }
791 if (success && !func_done)
792 {
793 if (AUTO_DEMANGLING || GNU_DEMANGLING)
794 {
795 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
796 bar__3fooi is 'foo::bar(int)'. We get here when we find the
797 first case, and need to ensure that the '(void)' gets added to
798 the current declp. Note that with ARM, the first case
799 represents the name of a static data member 'foo::bar',
0f41302f 800 which is in the current declp, so we leave it alone. */
a3184468
JM
801 success = demangle_args (work, mangled, declp);
802 }
803 }
804 if (success && work -> static_type && PRINT_ARG_TYPES)
805 {
806 string_append (declp, " static");
807 }
808 if (success && work -> const_type && PRINT_ARG_TYPES)
809 {
810 string_append (declp, " const");
811 }
812 return (success);
813}
814
815#if 0
816
817static int
818demangle_method_args (work, mangled, declp)
819 struct work_stuff *work;
820 const char **mangled;
821 string *declp;
822{
823 int success = 0;
824
825 if (work -> static_type)
826 {
827 string_append (declp, *mangled + 1);
828 *mangled += strlen (*mangled);
829 success = 1;
830 }
831 else
832 {
833 success = demangle_args (work, mangled, declp);
834 }
835 return (success);
836}
837
838#endif
839
840static int
841demangle_template (work, mangled, tname, trawname)
842 struct work_stuff *work;
843 const char **mangled;
844 string *tname;
845 string *trawname;
846{
847 int i;
848 int is_pointer;
849 int is_real;
850 int is_integral;
851 int is_char;
852 int is_bool;
853 int r;
854 int need_comma = 0;
855 int success = 0;
856 int done;
857 const char *old_p;
858 const char *start;
859 int symbol_len;
860 string temp;
861
862 (*mangled)++;
863 start = *mangled;
864 /* get template name */
865 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
866 {
867 return (0);
868 }
869 if (trawname)
870 string_appendn (trawname, *mangled, r);
871 string_appendn (tname, *mangled, r);
872 *mangled += r;
873 string_append (tname, "<");
874 /* get size of template parameter list */
875 if (!get_count (mangled, &r))
876 {
877 return (0);
878 }
879 for (i = 0; i < r; i++)
880 {
881 if (need_comma)
882 {
883 string_append (tname, ", ");
884 }
885 /* Z for type parameters */
886 if (**mangled == 'Z')
887 {
888 (*mangled)++;
889 /* temp is initialized in do_type */
890 success = do_type (work, mangled, &temp);
891 if (success)
892 {
893 string_appends (tname, &temp);
894 }
895 string_delete(&temp);
896 if (!success)
897 {
898 break;
899 }
900 }
901 else
902 {
903 /* otherwise, value parameter */
904 old_p = *mangled;
905 is_pointer = 0;
906 is_real = 0;
907 is_integral = 0;
908 is_char = 0;
943a140b 909 is_bool = 0;
a3184468
JM
910 done = 0;
911 /* temp is initialized in do_type */
912 success = do_type (work, mangled, &temp);
913/*
914 if (success)
915 {
916 string_appends (tname, &temp);
917 }
918*/
919 string_delete(&temp);
920 if (!success)
921 {
922 break;
923 }
924/*
925 string_append (tname, "=");
926*/
927 while (*old_p && !done)
928 {
929 switch (*old_p)
930 {
931 case 'P':
932 case 'p':
933 case 'R':
934 done = is_pointer = 1;
935 break;
936 case 'C': /* const */
937 case 'S': /* explicitly signed [char] */
938 case 'U': /* unsigned */
939 case 'V': /* volatile */
940 case 'F': /* function */
941 case 'M': /* member function */
942 case 'O': /* ??? */
943 old_p++;
944 continue;
945 case 'Q': /* qualified name */
946 done = is_integral = 1;
947 break;
948 case 'T': /* remembered type */
949 abort ();
950 break;
951 case 'v': /* void */
952 abort ();
953 break;
954 case 'x': /* long long */
955 case 'l': /* long */
956 case 'i': /* int */
957 case 's': /* short */
958 case 'w': /* wchar_t */
959 done = is_integral = 1;
960 break;
961 case 'b': /* bool */
962 done = is_bool = 1;
963 break;
964 case 'c': /* char */
965 done = is_char = 1;
966 break;
967 case 'r': /* long double */
968 case 'd': /* double */
969 case 'f': /* float */
970 done = is_real = 1;
971 break;
972 default:
973 /* it's probably user defined type, let's assume
ddd5a7c1 974 it's integral, it seems hard to figure out
a3184468
JM
975 what it really is */
976 done = is_integral = 1;
977 }
978 }
979 if (is_integral)
980 {
981 if (**mangled == 'm')
982 {
983 string_appendn (tname, "-", 1);
984 (*mangled)++;
985 }
986 while (isdigit (**mangled))
987 {
988 string_appendn (tname, *mangled, 1);
989 (*mangled)++;
990 }
991 }
992 else if (is_char)
993 {
994 char tmp[2];
995 int val;
996 if (**mangled == 'm')
997 {
998 string_appendn (tname, "-", 1);
999 (*mangled)++;
1000 }
1001 string_appendn (tname, "'", 1);
1002 val = consume_count(mangled);
1003 if (val == 0)
1004 {
1005 success = 0;
1006 break;
1007 }
1008 tmp[0] = (char)val;
1009 tmp[1] = '\0';
1010 string_appendn (tname, &tmp[0], 1);
1011 string_appendn (tname, "'", 1);
1012 }
1013 else if (is_bool)
1014 {
1015 int val = consume_count (mangled);
1016 if (val == 0)
1017 string_appendn (tname, "false", 5);
1018 else if (val == 1)
1019 string_appendn (tname, "true", 4);
1020 else
1021 success = 0;
1022 }
1023 else if (is_real)
1024 {
1025 if (**mangled == 'm')
1026 {
1027 string_appendn (tname, "-", 1);
1028 (*mangled)++;
1029 }
1030 while (isdigit (**mangled))
1031 {
1032 string_appendn (tname, *mangled, 1);
1033 (*mangled)++;
1034 }
1035 if (**mangled == '.') /* fraction */
1036 {
1037 string_appendn (tname, ".", 1);
1038 (*mangled)++;
1039 while (isdigit (**mangled))
1040 {
1041 string_appendn (tname, *mangled, 1);
1042 (*mangled)++;
1043 }
1044 }
1045 if (**mangled == 'e') /* exponent */
1046 {
1047 string_appendn (tname, "e", 1);
1048 (*mangled)++;
1049 while (isdigit (**mangled))
1050 {
1051 string_appendn (tname, *mangled, 1);
1052 (*mangled)++;
1053 }
1054 }
1055 }
1056 else if (is_pointer)
1057 {
1058 if (!get_count (mangled, &symbol_len))
1059 {
1060 success = 0;
1061 break;
1062 }
943a140b
JM
1063 if (symbol_len == 0)
1064 string_appendn (tname, "0", 1);
1065 else
983edca4
JM
1066 {
1067 char *p = xmalloc (symbol_len + 1), *q;
1068 strncpy (p, *mangled, symbol_len);
ba9d9bfa 1069 p [symbol_len] = '\0';
983edca4
JM
1070 q = cplus_demangle (p, work->options);
1071 string_appendn (tname, "&", 1);
ba9d9bfa
JM
1072 if (q)
1073 {
1074 string_append (tname, q);
1075 free (q);
1076 }
1077 else
1078 string_append (tname, p);
983edca4 1079 free (p);
983edca4 1080 }
a3184468
JM
1081 *mangled += symbol_len;
1082 }
1083 }
1084 need_comma = 1;
1085 }
1086 if (tname->p[-1] == '>')
1087 string_append (tname, " ");
1088 string_append (tname, ">");
1089
1090/*
1091 if (work -> static_type)
1092 {
1093 string_append (declp, *mangled + 1);
1094 *mangled += strlen (*mangled);
1095 success = 1;
1096 }
1097 else
1098 {
1099 success = demangle_args (work, mangled, declp);
1100 }
1101 }
1102*/
1103 return (success);
1104}
1105
1106static int
1107arm_pt (work, mangled, n, anchor, args)
1108 struct work_stuff *work;
1109 const char *mangled;
1110 int n;
1111 const char **anchor, **args;
1112{
1113 /* ARM template? */
f83d4617 1114 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
a3184468
JM
1115 {
1116 int len;
1117 *args = *anchor + 6;
1118 len = consume_count (args);
1119 if (*args + len == mangled + n && **args == '_')
1120 {
1121 ++*args;
1122 return 1;
1123 }
1124 }
1125 return 0;
1126}
1127
1128static void
1129demangle_arm_pt (work, mangled, n, declp)
1130 struct work_stuff *work;
1131 const char **mangled;
1132 int n;
1133 string *declp;
1134{
1135 const char *p;
1136 const char *args;
1137 const char *e = *mangled + n;
1138
1139 /* ARM template? */
1140 if (arm_pt (work, *mangled, n, &p, &args))
1141 {
1142 string arg;
1143 string_init (&arg);
1144 string_appendn (declp, *mangled, p - *mangled);
1145 string_append (declp, "<");
1146 /* should do error checking here */
1147 while (args < e) {
1148 string_clear (&arg);
1149 do_type (work, &args, &arg);
1150 string_appends (declp, &arg);
1151 string_append (declp, ",");
1152 }
1153 string_delete (&arg);
1154 --declp->p;
1155 string_append (declp, ">");
1156 }
1157 else
1158 {
1159 string_appendn (declp, *mangled, n);
1160 }
1161 *mangled += n;
1162}
1163
1164static int
1165demangle_class_name (work, mangled, declp)
1166 struct work_stuff *work;
1167 const char **mangled;
1168 string *declp;
1169{
1170 int n;
1171 int success = 0;
1172
1173 n = consume_count (mangled);
1174 if (strlen (*mangled) >= n)
1175 {
1176 demangle_arm_pt (work, mangled, n, declp);
1177 success = 1;
1178 }
1179
1180 return (success);
1181}
1182
1183/*
1184
1185LOCAL FUNCTION
1186
1187 demangle_class -- demangle a mangled class sequence
1188
1189SYNOPSIS
1190
1191 static int
1192 demangle_class (struct work_stuff *work, const char **mangled,
1193 strint *declp)
1194
1195DESCRIPTION
1196
1197 DECLP points to the buffer into which demangling is being done.
1198
1199 *MANGLED points to the current token to be demangled. On input,
1200 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1201 On exit, it points to the next token after the mangled class on
1202 success, or the first unconsumed token on failure.
1203
abc95ed3 1204 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
a3184468
JM
1205 we are demangling a constructor or destructor. In this case
1206 we prepend "class::class" or "class::~class" to DECLP.
1207
1208 Otherwise, we prepend "class::" to the current DECLP.
1209
1210 Reset the constructor/destructor flags once they have been
1211 "consumed". This allows demangle_class to be called later during
1212 the same demangling, to do normal class demangling.
1213
1214 Returns 1 if demangling is successful, 0 otherwise.
1215
1216*/
1217
1218static int
1219demangle_class (work, mangled, declp)
1220 struct work_stuff *work;
1221 const char **mangled;
1222 string *declp;
1223{
1224 int success = 0;
1225 string class_name;
1226
1227 string_init (&class_name);
1228 if (demangle_class_name (work, mangled, &class_name))
1229 {
1230 if ((work->constructor & 1) || (work->destructor & 1))
1231 {
1232 string_prepends (declp, &class_name);
1233 if (work -> destructor & 1)
1234 {
1235 string_prepend (declp, "~");
1236 work -> destructor -= 1;
1237 }
1238 else
1239 {
1240 work -> constructor -= 1;
1241 }
1242 }
1243 string_prepend (declp, "::");
1244 string_prepends (declp, &class_name);
1245 success = 1;
1246 }
1247 string_delete (&class_name);
1248 return (success);
1249}
1250
1251/*
1252
1253LOCAL FUNCTION
1254
1255 demangle_prefix -- consume the mangled name prefix and find signature
1256
1257SYNOPSIS
1258
1259 static int
1260 demangle_prefix (struct work_stuff *work, const char **mangled,
1261 string *declp);
1262
1263DESCRIPTION
1264
1265 Consume and demangle the prefix of the mangled name.
1266
1267 DECLP points to the string buffer into which demangled output is
1268 placed. On entry, the buffer is empty. On exit it contains
1269 the root function name, the demangled operator name, or in some
1270 special cases either nothing or the completely demangled result.
1271
1272 MANGLED points to the current pointer into the mangled name. As each
1273 token of the mangled name is consumed, it is updated. Upon entry
1274 the current mangled name pointer points to the first character of
1275 the mangled name. Upon exit, it should point to the first character
1276 of the signature if demangling was successful, or to the first
1277 unconsumed character if demangling of the prefix was unsuccessful.
1278
1279 Returns 1 on success, 0 otherwise.
1280 */
1281
1282static int
1283demangle_prefix (work, mangled, declp)
1284 struct work_stuff *work;
1285 const char **mangled;
1286 string *declp;
1287{
1288 int success = 1;
1289 const char *scan;
1290 int i;
1291
1292 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1293 {
1294 char *marker = strchr (cplus_markers, (*mangled)[8]);
1295 if (marker != NULL && *marker == (*mangled)[10])
1296 {
1297 if ((*mangled)[9] == 'D')
1298 {
1299 /* it's a GNU global destructor to be executed at program exit */
1300 (*mangled) += 11;
1301 work->destructor = 2;
1302 if (gnu_special (work, mangled, declp))
1303 return success;
1304 }
1305 else if ((*mangled)[9] == 'I')
1306 {
1307 /* it's a GNU global constructor to be executed at program init */
1308 (*mangled) += 11;
1309 work->constructor = 2;
1310 if (gnu_special (work, mangled, declp))
1311 return success;
1312 }
1313 }
1314 }
1315 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1316 {
1317 /* it's a ARM global destructor to be executed at program exit */
1318 (*mangled) += 7;
1319 work->destructor = 2;
1320 }
1321 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1322 {
1323 /* it's a ARM global constructor to be executed at program initial */
1324 (*mangled) += 7;
1325 work->constructor = 2;
1326 }
1327
1328/* This block of code is a reduction in strength time optimization
1329 of:
f83d4617 1330 scan = mystrstr (*mangled, "__"); */
a3184468
JM
1331
1332 {
1333 scan = *mangled;
1334
1335 do {
1336 scan = strchr (scan, '_');
1337 } while (scan != NULL && *++scan != '_');
1338
1339 if (scan != NULL) --scan;
1340 }
1341
1342 if (scan != NULL)
1343 {
1344 /* We found a sequence of two or more '_', ensure that we start at
0f41302f 1345 the last pair in the sequence. */
a3184468
JM
1346 i = strspn (scan, "_");
1347 if (i > 2)
1348 {
1349 scan += (i - 2);
1350 }
1351 }
1352
1353 if (scan == NULL)
1354 {
1355 success = 0;
1356 }
1357 else if (work -> static_type)
1358 {
1359 if (!isdigit (scan[0]) && (scan[0] != 't'))
1360 {
1361 success = 0;
1362 }
1363 }
1364 else if ((scan == *mangled) &&
1365 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1366 {
1367 /* The ARM says nothing about the mangling of local variables.
1368 But cfront mangles local variables by prepending __<nesting_level>
1369 to them. As an extension to ARM demangling we handle this case. */
1370 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1371 {
1372 *mangled = scan + 2;
1373 consume_count (mangled);
1374 string_append (declp, *mangled);
1375 *mangled += strlen (*mangled);
1376 success = 1;
1377 }
1378 else
1379 {
1380 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1381 names like __Q2_3foo3bar for nested type names. So don't accept
1382 this style of constructor for cfront demangling. */
1383 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1384 work -> constructor += 1;
1385 *mangled = scan + 2;
1386 }
1387 }
1388 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1389 {
1390 /* Mangled name starts with "__". Skip over any leading '_' characters,
1391 then find the next "__" that separates the prefix from the signature.
1392 */
1393 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1394 || (arm_special (work, mangled, declp) == 0))
1395 {
1396 while (*scan == '_')
1397 {
1398 scan++;
1399 }
f83d4617 1400 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
a3184468
JM
1401 {
1402 /* No separator (I.E. "__not_mangled"), or empty signature
1403 (I.E. "__not_mangled_either__") */
1404 success = 0;
1405 }
1406 else
1407 {
1408 demangle_function_name (work, mangled, declp, scan);
1409 }
1410 }
1411 }
1412 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1413 {
0f41302f 1414 /* Cfront-style parameterized type. Handled later as a signature. */
a3184468
JM
1415 success = 1;
1416
1417 /* ARM template? */
1418 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1419 }
1420 else if (*(scan + 2) != '\0')
1421 {
1422 /* Mangled name does not start with "__" but does have one somewhere
1423 in there with non empty stuff after it. Looks like a global
0f41302f 1424 function name. */
a3184468
JM
1425 demangle_function_name (work, mangled, declp, scan);
1426 }
1427 else
1428 {
1429 /* Doesn't look like a mangled name */
1430 success = 0;
1431 }
1432
1433 if (!success && (work->constructor == 2 || work->destructor == 2))
1434 {
1435 string_append (declp, *mangled);
1436 *mangled += strlen (*mangled);
1437 success = 1;
1438 }
1439 return (success);
1440}
1441
1442/*
1443
1444LOCAL FUNCTION
1445
1446 gnu_special -- special handling of gnu mangled strings
1447
1448SYNOPSIS
1449
1450 static int
1451 gnu_special (struct work_stuff *work, const char **mangled,
1452 string *declp);
1453
1454
1455DESCRIPTION
1456
1457 Process some special GNU style mangling forms that don't fit
1458 the normal pattern. For example:
1459
1460 _$_3foo (destructor for class foo)
1461 _vt$foo (foo virtual table)
1462 _vt$foo$bar (foo::bar virtual table)
1463 __vt_foo (foo virtual table, new style with thunks)
1464 _3foo$varname (static data member)
1465 _Q22rs2tu$vw (static data member)
1466 __t6vector1Zii (constructor with template)
1467 __thunk_4__$_7ostream (virtual function thunk)
1468 */
1469
1470static int
1471gnu_special (work, mangled, declp)
1472 struct work_stuff *work;
1473 const char **mangled;
1474 string *declp;
1475{
1476 int n;
1477 int success = 1;
1478 const char *p;
1479
1480 if ((*mangled)[0] == '_'
1481 && strchr (cplus_markers, (*mangled)[1]) != NULL
1482 && (*mangled)[2] == '_')
1483 {
1484 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1485 (*mangled) += 3;
1486 work -> destructor += 1;
1487 }
1488 else if ((*mangled)[0] == '_'
1489 && (((*mangled)[1] == '_'
1490 && (*mangled)[2] == 'v'
1491 && (*mangled)[3] == 't'
1492 && (*mangled)[4] == '_')
1493 || ((*mangled)[1] == 'v'
1494 && (*mangled)[2] == 't'
1495 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1496 {
1497 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1498 and create the decl. Note that we consume the entire mangled
1499 input string, which means that demangle_signature has no work
0f41302f 1500 to do. */
a3184468
JM
1501 if ((*mangled)[2] == 'v')
1502 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1503 else
1504 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1505 while (**mangled != '\0')
1506 {
1507 p = strpbrk (*mangled, cplus_markers);
1508 switch (**mangled)
1509 {
1510 case 'Q':
1511 success = demangle_qualified (work, mangled, declp, 0, 1);
1512 break;
1513 case 't':
1514 success = demangle_template (work, mangled, declp, 0);
1515 break;
1516 default:
1517 if (isdigit(*mangled[0]))
1518 {
1519 n = consume_count(mangled);
1520 }
1521 else
1522 {
1523 n = strcspn (*mangled, cplus_markers);
1524 }
1525 string_appendn (declp, *mangled, n);
1526 (*mangled) += n;
1527 }
1528
1529 if (success && ((p == NULL) || (p == *mangled)))
1530 {
1531 if (p != NULL)
1532 {
1533 string_append (declp, "::");
1534 (*mangled)++;
1535 }
1536 }
1537 else
1538 {
1539 success = 0;
1540 break;
1541 }
1542 }
1543 if (success)
1544 string_append (declp, " virtual table");
1545 }
1546 else if ((*mangled)[0] == '_'
1547 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1548 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1549 {
1550 /* static data member, "_3foo$varname" for example */
1551 (*mangled)++;
1552 switch (**mangled)
1553 {
1554 case 'Q':
1555 success = demangle_qualified (work, mangled, declp, 0, 1);
1556 break;
1557 case 't':
1558 success = demangle_template (work, mangled, declp, 0);
1559 break;
1560 default:
1561 n = consume_count (mangled);
1562 string_appendn (declp, *mangled, n);
1563 (*mangled) += n;
1564 }
1565 if (success && (p == *mangled))
1566 {
1567 /* Consumed everything up to the cplus_marker, append the
0f41302f 1568 variable name. */
a3184468
JM
1569 (*mangled)++;
1570 string_append (declp, "::");
1571 n = strlen (*mangled);
1572 string_appendn (declp, *mangled, n);
1573 (*mangled) += n;
1574 }
1575 else
1576 {
1577 success = 0;
1578 }
1579 }
1580 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1581 {
1582 int delta = ((*mangled) += 8, consume_count (mangled));
1583 char *method = cplus_demangle (++*mangled, work->options);
1584 if (method)
1585 {
1586 char buf[50];
1587 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1588 string_append (declp, buf);
1589 string_append (declp, method);
1590 free (method);
1591 n = strlen (*mangled);
1592 (*mangled) += n;
1593 }
1594 else
1595 {
1596 success = 0;
1597 }
1598 }
1599 else
1600 {
1601 success = 0;
1602 }
1603 return (success);
1604}
1605
1606/*
1607
1608LOCAL FUNCTION
1609
1610 arm_special -- special handling of ARM/lucid mangled strings
1611
1612SYNOPSIS
1613
1614 static int
1615 arm_special (struct work_stuff *work, const char **mangled,
1616 string *declp);
1617
1618
1619DESCRIPTION
1620
1621 Process some special ARM style mangling forms that don't fit
1622 the normal pattern. For example:
1623
1624 __vtbl__3foo (foo virtual table)
1625 __vtbl__3foo__3bar (bar::foo virtual table)
1626
1627 */
1628
1629static int
1630arm_special (work, mangled, declp)
1631 struct work_stuff *work;
1632 const char **mangled;
1633 string *declp;
1634{
1635 int n;
1636 int success = 1;
1637 const char *scan;
1638
1639 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1640 {
1641 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1642 and create the decl. Note that we consume the entire mangled
1643 input string, which means that demangle_signature has no work
0f41302f 1644 to do. */
a3184468
JM
1645 scan = *mangled + ARM_VTABLE_STRLEN;
1646 while (*scan != '\0') /* first check it can be demangled */
1647 {
1648 n = consume_count (&scan);
1649 if (n==0)
1650 {
1651 return (0); /* no good */
1652 }
1653 scan += n;
1654 if (scan[0] == '_' && scan[1] == '_')
1655 {
1656 scan += 2;
1657 }
1658 }
1659 (*mangled) += ARM_VTABLE_STRLEN;
1660 while (**mangled != '\0')
1661 {
1662 n = consume_count (mangled);
1663 string_prependn (declp, *mangled, n);
1664 (*mangled) += n;
1665 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1666 {
1667 string_prepend (declp, "::");
1668 (*mangled) += 2;
1669 }
1670 }
1671 string_append (declp, " virtual table");
1672 }
1673 else
1674 {
1675 success = 0;
1676 }
1677 return (success);
1678}
1679
1680/*
1681
1682LOCAL FUNCTION
1683
1684 demangle_qualified -- demangle 'Q' qualified name strings
1685
1686SYNOPSIS
1687
1688 static int
1689 demangle_qualified (struct work_stuff *, const char *mangled,
1690 string *result, int isfuncname, int append);
1691
1692DESCRIPTION
1693
1694 Demangle a qualified name, such as "Q25Outer5Inner" which is
1695 the mangled form of "Outer::Inner". The demangled output is
1696 prepended or appended to the result string according to the
1697 state of the append flag.
1698
1699 If isfuncname is nonzero, then the qualified name we are building
1700 is going to be used as a member function name, so if it is a
1701 constructor or destructor function, append an appropriate
1702 constructor or destructor name. I.E. for the above example,
1703 the result for use as a constructor is "Outer::Inner::Inner"
1704 and the result for use as a destructor is "Outer::Inner::~Inner".
1705
1706BUGS
1707
1708 Numeric conversion is ASCII dependent (FIXME).
1709
1710 */
1711
1712static int
1713demangle_qualified (work, mangled, result, isfuncname, append)
1714 struct work_stuff *work;
1715 const char **mangled;
1716 string *result;
1717 int isfuncname;
1718 int append;
1719{
1720 int qualifiers;
1721 int namelength;
1722 int success = 1;
1723 const char *p;
1724 char num[2];
1725 string temp;
1726
1727 string_init (&temp);
1728 switch ((*mangled)[1])
1729 {
1730 case '_':
1731 /* GNU mangled name with more than 9 classes. The count is preceded
1732 by an underscore (to distinguish it from the <= 9 case) and followed
1733 by an underscore. */
1734 p = *mangled + 2;
1735 qualifiers = atoi (p);
1736 if (!isdigit (*p) || *p == '0')
1737 success = 0;
1738
1739 /* Skip the digits. */
1740 while (isdigit (*p))
1741 ++p;
1742
1743 if (*p != '_')
1744 success = 0;
1745
1746 *mangled = p + 1;
1747 break;
1748
1749 case '1':
1750 case '2':
1751 case '3':
1752 case '4':
1753 case '5':
1754 case '6':
1755 case '7':
1756 case '8':
1757 case '9':
1758 /* The count is in a single digit. */
1759 num[0] = (*mangled)[1];
1760 num[1] = '\0';
1761 qualifiers = atoi (num);
1762
1763 /* If there is an underscore after the digit, skip it. This is
1764 said to be for ARM-qualified names, but the ARM makes no
1765 mention of such an underscore. Perhaps cfront uses one. */
1766 if ((*mangled)[2] == '_')
1767 {
1768 (*mangled)++;
1769 }
1770 (*mangled) += 2;
1771 break;
1772
1773 case '0':
1774 default:
1775 success = 0;
1776 }
1777
1778 if (!success)
1779 return success;
1780
1781 /* Pick off the names and collect them in the temp buffer in the order
0f41302f 1782 in which they are found, separated by '::'. */
a3184468
JM
1783
1784 while (qualifiers-- > 0)
1785 {
1786 if (*mangled[0] == '_')
1787 *mangled = *mangled + 1;
1788 if (*mangled[0] == 't')
1789 {
1790 success = demangle_template(work, mangled, &temp, 0);
1791 if (!success) break;
1792 }
1793 else
1794 {
1795 namelength = consume_count (mangled);
1796 if (strlen (*mangled) < namelength)
1797 {
1798 /* Simple sanity check failed */
1799 success = 0;
1800 break;
1801 }
1802 string_appendn (&temp, *mangled, namelength);
1803 *mangled += namelength;
1804 }
1805 if (qualifiers > 0)
1806 {
1807 string_appendn (&temp, "::", 2);
1808 }
1809 }
1810
1811 /* If we are using the result as a function name, we need to append
1812 the appropriate '::' separated constructor or destructor name.
1813 We do this here because this is the most convenient place, where
0f41302f 1814 we already have a pointer to the name and the length of the name. */
a3184468
JM
1815
1816 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1817 {
1818 string_appendn (&temp, "::", 2);
1819 if (work -> destructor & 1)
1820 {
1821 string_append (&temp, "~");
1822 }
1823 string_appendn (&temp, (*mangled) - namelength, namelength);
1824 }
1825
1826 /* Now either prepend the temp buffer to the result, or append it,
0f41302f 1827 depending upon the state of the append flag. */
a3184468
JM
1828
1829 if (append)
1830 {
1831 string_appends (result, &temp);
1832 }
1833 else
1834 {
1835 if (!STRING_EMPTY (result))
1836 {
1837 string_appendn (&temp, "::", 2);
1838 }
1839 string_prepends (result, &temp);
1840 }
1841
1842 string_delete (&temp);
1843 return (success);
1844}
1845
1846/*
1847
1848LOCAL FUNCTION
1849
1850 get_count -- convert an ascii count to integer, consuming tokens
1851
1852SYNOPSIS
1853
1854 static int
1855 get_count (const char **type, int *count)
1856
1857DESCRIPTION
1858
1859 Return 0 if no conversion is performed, 1 if a string is converted.
1860*/
1861
1862static int
1863get_count (type, count)
1864 const char **type;
1865 int *count;
1866{
1867 const char *p;
1868 int n;
1869
1870 if (!isdigit (**type))
1871 {
1872 return (0);
1873 }
1874 else
1875 {
1876 *count = **type - '0';
1877 (*type)++;
1878 if (isdigit (**type))
1879 {
1880 p = *type;
1881 n = *count;
1882 do
1883 {
1884 n *= 10;
1885 n += *p - '0';
1886 p++;
1887 }
1888 while (isdigit (*p));
1889 if (*p == '_')
1890 {
1891 *type = p + 1;
1892 *count = n;
1893 }
1894 }
1895 }
1896 return (1);
1897}
1898
1899/* result will be initialised here; it will be freed on failure */
1900
1901static int
1902do_type (work, mangled, result)
1903 struct work_stuff *work;
1904 const char **mangled;
1905 string *result;
1906{
1907 int n;
1908 int done;
1909 int success;
1910 string decl;
1911 const char *remembered_type;
1912 int constp;
1913 int volatilep;
1914
1915 string_init (&decl);
1916 string_init (result);
1917
1918 done = 0;
1919 success = 1;
1920 while (success && !done)
1921 {
1922 int member;
1923 switch (**mangled)
1924 {
1925
1926 /* A pointer type */
1927 case 'P':
1928 case 'p':
1929 (*mangled)++;
1930 string_prepend (&decl, "*");
1931 break;
1932
1933 /* A reference type */
1934 case 'R':
1935 (*mangled)++;
1936 string_prepend (&decl, "&");
1937 break;
1938
1939 /* An array */
1940 case 'A':
1941 {
1942 const char *p = ++(*mangled);
1943
1944 string_prepend (&decl, "(");
1945 string_append (&decl, ")[");
1946 /* Copy anything up until the next underscore (the size of the
1947 array). */
1948 while (**mangled && **mangled != '_')
1949 ++(*mangled);
1950 if (**mangled == '_')
1951 {
1952 string_appendn (&decl, p, *mangled - p);
1953 string_append (&decl, "]");
1954 *mangled += 1;
1955 }
1956 else
1957 success = 0;
1958 break;
1959 }
1960
1961 /* A back reference to a previously seen type */
1962 case 'T':
1963 (*mangled)++;
1964 if (!get_count (mangled, &n) || n >= work -> ntypes)
1965 {
1966 success = 0;
1967 }
1968 else
1969 {
1970 remembered_type = work -> typevec[n];
1971 mangled = &remembered_type;
1972 }
1973 break;
1974
1975 /* A function */
1976 case 'F':
1977 (*mangled)++;
1978 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1979 {
1980 string_prepend (&decl, "(");
1981 string_append (&decl, ")");
1982 }
1983 /* After picking off the function args, we expect to either find the
1984 function return type (preceded by an '_') or the end of the
0f41302f 1985 string. */
a3184468
JM
1986 if (!demangle_args (work, mangled, &decl)
1987 || (**mangled != '_' && **mangled != '\0'))
1988 {
1989 success = 0;
1990 }
1991 if (success && (**mangled == '_'))
1992 {
1993 (*mangled)++;
1994 }
1995 break;
1996
1997 case 'M':
1998 case 'O':
1999 {
2000 constp = 0;
2001 volatilep = 0;
2002
2003 member = **mangled == 'M';
2004 (*mangled)++;
2005 if (!isdigit (**mangled))
2006 {
2007 success = 0;
2008 break;
2009 }
2010 n = consume_count (mangled);
2011 if (strlen (*mangled) < n)
2012 {
2013 success = 0;
2014 break;
2015 }
2016 string_append (&decl, ")");
2017 string_prepend (&decl, "::");
2018 string_prependn (&decl, *mangled, n);
2019 string_prepend (&decl, "(");
2020 *mangled += n;
2021 if (member)
2022 {
2023 if (**mangled == 'C')
2024 {
2025 (*mangled)++;
2026 constp = 1;
2027 }
2028 if (**mangled == 'V')
2029 {
2030 (*mangled)++;
2031 volatilep = 1;
2032 }
2033 if (*(*mangled)++ != 'F')
2034 {
2035 success = 0;
2036 break;
2037 }
2038 }
2039 if ((member && !demangle_args (work, mangled, &decl))
2040 || **mangled != '_')
2041 {
2042 success = 0;
2043 break;
2044 }
2045 (*mangled)++;
2046 if (! PRINT_ANSI_QUALIFIERS)
2047 {
2048 break;
2049 }
2050 if (constp)
2051 {
2052 APPEND_BLANK (&decl);
2053 string_append (&decl, "const");
2054 }
2055 if (volatilep)
2056 {
2057 APPEND_BLANK (&decl);
2058 string_append (&decl, "volatile");
2059 }
2060 break;
2061 }
2062 case 'G':
2063 (*mangled)++;
2064 break;
2065
2066 case 'C':
2067 (*mangled)++;
2068/*
2069 if ((*mangled)[1] == 'P')
2070 {
2071*/
2072 if (PRINT_ANSI_QUALIFIERS)
2073 {
2074 if (!STRING_EMPTY (&decl))
2075 {
2076 string_prepend (&decl, " ");
2077 }
2078 string_prepend (&decl, "const");
2079 }
2080 break;
2081/*
2082 }
2083*/
2084
2085 /* fall through */
2086 default:
2087 done = 1;
2088 break;
2089 }
2090 }
2091
2092 switch (**mangled)
2093 {
0f41302f 2094 /* A qualified name, such as "Outer::Inner". */
a3184468
JM
2095 case 'Q':
2096 success = demangle_qualified (work, mangled, result, 0, 1);
2097 break;
2098
2099 default:
2100 success = demangle_fund_type (work, mangled, result);
2101 break;
2102 }
2103
2104 if (success)
2105 {
2106 if (!STRING_EMPTY (&decl))
2107 {
2108 string_append (result, " ");
2109 string_appends (result, &decl);
2110 }
2111 }
2112 else
2113 {
2114 string_delete (result);
2115 }
2116 string_delete (&decl);
2117 return (success);
2118}
2119
2120/* Given a pointer to a type string that represents a fundamental type
2121 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2122 string in which the demangled output is being built in RESULT, and
2123 the WORK structure, decode the types and add them to the result.
2124
2125 For example:
2126
2127 "Ci" => "const int"
2128 "Sl" => "signed long"
2129 "CUs" => "const unsigned short"
2130
2131 */
2132
2133static int
2134demangle_fund_type (work, mangled, result)
2135 struct work_stuff *work;
2136 const char **mangled;
2137 string *result;
2138{
2139 int done = 0;
2140 int success = 1;
2141
0f41302f 2142 /* First pick off any type qualifiers. There can be more than one. */
a3184468
JM
2143
2144 while (!done)
2145 {
2146 switch (**mangled)
2147 {
2148 case 'C':
2149 (*mangled)++;
2150 if (PRINT_ANSI_QUALIFIERS)
2151 {
2152 APPEND_BLANK (result);
2153 string_append (result, "const");
2154 }
2155 break;
2156 case 'U':
2157 (*mangled)++;
2158 APPEND_BLANK (result);
2159 string_append (result, "unsigned");
2160 break;
2161 case 'S': /* signed char only */
2162 (*mangled)++;
2163 APPEND_BLANK (result);
2164 string_append (result, "signed");
2165 break;
2166 case 'V':
2167 (*mangled)++;
2168 if (PRINT_ANSI_QUALIFIERS)
2169 {
2170 APPEND_BLANK (result);
2171 string_append (result, "volatile");
2172 }
2173 break;
2174 default:
2175 done = 1;
2176 break;
2177 }
2178 }
2179
0f41302f 2180 /* Now pick off the fundamental type. There can be only one. */
a3184468
JM
2181
2182 switch (**mangled)
2183 {
2184 case '\0':
2185 case '_':
2186 break;
2187 case 'v':
2188 (*mangled)++;
2189 APPEND_BLANK (result);
2190 string_append (result, "void");
2191 break;
2192 case 'x':
2193 (*mangled)++;
2194 APPEND_BLANK (result);
2195 string_append (result, "long long");
2196 break;
2197 case 'l':
2198 (*mangled)++;
2199 APPEND_BLANK (result);
2200 string_append (result, "long");
2201 break;
2202 case 'i':
2203 (*mangled)++;
2204 APPEND_BLANK (result);
2205 string_append (result, "int");
2206 break;
2207 case 's':
2208 (*mangled)++;
2209 APPEND_BLANK (result);
2210 string_append (result, "short");
2211 break;
2212 case 'b':
2213 (*mangled)++;
2214 APPEND_BLANK (result);
2215 string_append (result, "bool");
2216 break;
2217 case 'c':
2218 (*mangled)++;
2219 APPEND_BLANK (result);
2220 string_append (result, "char");
2221 break;
2222 case 'w':
2223 (*mangled)++;
2224 APPEND_BLANK (result);
2225 string_append (result, "wchar_t");
2226 break;
2227 case 'r':
2228 (*mangled)++;
2229 APPEND_BLANK (result);
2230 string_append (result, "long double");
2231 break;
2232 case 'd':
2233 (*mangled)++;
2234 APPEND_BLANK (result);
2235 string_append (result, "double");
2236 break;
2237 case 'f':
2238 (*mangled)++;
2239 APPEND_BLANK (result);
2240 string_append (result, "float");
2241 break;
2242 case 'G':
2243 (*mangled)++;
2244 if (!isdigit (**mangled))
2245 {
2246 success = 0;
2247 break;
2248 }
2249 /* fall through */
2250 /* An explicit type, such as "6mytype" or "7integer" */
2251 case '0':
2252 case '1':
2253 case '2':
2254 case '3':
2255 case '4':
2256 case '5':
2257 case '6':
2258 case '7':
2259 case '8':
2260 case '9':
2261 APPEND_BLANK (result);
2262 if (!demangle_class_name (work, mangled, result)) {
2263 --result->p;
2264 success = 0;
2265 }
2266 break;
2267 case 't':
2268 success = demangle_template(work,mangled, result, 0);
2269 break;
2270 default:
2271 success = 0;
2272 break;
2273 }
2274
2275 return (success);
2276}
2277
2278/* `result' will be initialized in do_type; it will be freed on failure */
2279
2280static int
2281do_arg (work, mangled, result)
2282 struct work_stuff *work;
2283 const char **mangled;
2284 string *result;
2285{
2286 const char *start = *mangled;
2287
2288 if (!do_type (work, mangled, result))
2289 {
2290 return (0);
2291 }
2292 else
2293 {
2294 remember_type (work, start, *mangled - start);
2295 return (1);
2296 }
2297}
2298
2299static void
2300remember_type (work, start, len)
2301 struct work_stuff *work;
2302 const char *start;
2303 int len;
2304{
2305 char *tem;
2306
2307 if (work -> ntypes >= work -> typevec_size)
2308 {
2309 if (work -> typevec_size == 0)
2310 {
2311 work -> typevec_size = 3;
2312 work -> typevec =
2313 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2314 }
2315 else
2316 {
2317 work -> typevec_size *= 2;
2318 work -> typevec =
2319 (char **) xrealloc ((char *)work -> typevec,
2320 sizeof (char *) * work -> typevec_size);
2321 }
2322 }
2323 tem = xmalloc (len + 1);
2324 memcpy (tem, start, len);
2325 tem[len] = '\0';
2326 work -> typevec[work -> ntypes++] = tem;
2327}
2328
0f41302f 2329/* Forget the remembered types, but not the type vector itself. */
a3184468
JM
2330
2331static void
2332forget_types (work)
2333 struct work_stuff *work;
2334{
2335 int i;
2336
2337 while (work -> ntypes > 0)
2338 {
2339 i = --(work -> ntypes);
2340 if (work -> typevec[i] != NULL)
2341 {
2342 free (work -> typevec[i]);
2343 work -> typevec[i] = NULL;
2344 }
2345 }
2346}
2347
2348/* Process the argument list part of the signature, after any class spec
2349 has been consumed, as well as the first 'F' character (if any). For
2350 example:
2351
2352 "__als__3fooRT0" => process "RT0"
2353 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2354
2355 DECLP must be already initialised, usually non-empty. It won't be freed
2356 on failure.
2357
2358 Note that g++ differs significantly from ARM and lucid style mangling
2359 with regards to references to previously seen types. For example, given
2360 the source fragment:
2361
2362 class foo {
2363 public:
2364 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2365 };
2366
2367 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2368 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2369
2370 g++ produces the names:
2371
2372 __3fooiRT0iT2iT2
2373 foo__FiR3fooiT1iT1
2374
2375 while lcc (and presumably other ARM style compilers as well) produces:
2376
2377 foo__FiR3fooT1T2T1T2
2378 __ct__3fooFiR3fooT1T2T1T2
2379
2380 Note that g++ bases it's type numbers starting at zero and counts all
2381 previously seen types, while lucid/ARM bases it's type numbers starting
2382 at one and only considers types after it has seen the 'F' character
2383 indicating the start of the function args. For lucid/ARM style, we
2384 account for this difference by discarding any previously seen types when
2385 we see the 'F' character, and subtracting one from the type number
2386 reference.
2387
2388 */
2389
2390static int
2391demangle_args (work, mangled, declp)
2392 struct work_stuff *work;
2393 const char **mangled;
2394 string *declp;
2395{
2396 string arg;
2397 int need_comma = 0;
2398 int r;
2399 int t;
2400 const char *tem;
2401 char temptype;
2402
2403 if (PRINT_ARG_TYPES)
2404 {
2405 string_append (declp, "(");
2406 if (**mangled == '\0')
2407 {
2408 string_append (declp, "void");
2409 }
2410 }
2411
2412 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2413 {
2414 if ((**mangled == 'N') || (**mangled == 'T'))
2415 {
2416 temptype = *(*mangled)++;
2417
2418 if (temptype == 'N')
2419 {
2420 if (!get_count (mangled, &r))
2421 {
2422 return (0);
2423 }
2424 }
2425 else
2426 {
2427 r = 1;
2428 }
2429 if (ARM_DEMANGLING && work -> ntypes >= 10)
2430 {
2431 /* If we have 10 or more types we might have more than a 1 digit
2432 index so we'll have to consume the whole count here. This
ddd5a7c1 2433 will lose if the next thing is a type name preceded by a
a3184468
JM
2434 count but it's impossible to demangle that case properly
2435 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
a3184468
JM
2436 Pc, ...)" or "(..., type12, char *, ...)" */
2437 if ((t = consume_count(mangled)) == 0)
2438 {
2439 return (0);
2440 }
2441 }
2442 else
2443 {
2444 if (!get_count (mangled, &t))
2445 {
2446 return (0);
2447 }
2448 }
2449 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2450 {
2451 t--;
2452 }
2453 /* Validate the type index. Protect against illegal indices from
0f41302f 2454 malformed type strings. */
a3184468
JM
2455 if ((t < 0) || (t >= work -> ntypes))
2456 {
2457 return (0);
2458 }
2459 while (--r >= 0)
2460 {
2461 tem = work -> typevec[t];
2462 if (need_comma && PRINT_ARG_TYPES)
2463 {
2464 string_append (declp, ", ");
2465 }
2466 if (!do_arg (work, &tem, &arg))
2467 {
2468 return (0);
2469 }
2470 if (PRINT_ARG_TYPES)
2471 {
2472 string_appends (declp, &arg);
2473 }
2474 string_delete (&arg);
2475 need_comma = 1;
2476 }
2477 }
2478 else
2479 {
2480 if (need_comma & PRINT_ARG_TYPES)
2481 {
2482 string_append (declp, ", ");
2483 }
2484 if (!do_arg (work, mangled, &arg))
2485 {
2486 return (0);
2487 }
2488 if (PRINT_ARG_TYPES)
2489 {
2490 string_appends (declp, &arg);
2491 }
2492 string_delete (&arg);
2493 need_comma = 1;
2494 }
2495 }
2496
2497 if (**mangled == 'e')
2498 {
2499 (*mangled)++;
2500 if (PRINT_ARG_TYPES)
2501 {
2502 if (need_comma)
2503 {
2504 string_append (declp, ",");
2505 }
2506 string_append (declp, "...");
2507 }
2508 }
2509
2510 if (PRINT_ARG_TYPES)
2511 {
2512 string_append (declp, ")");
2513 }
2514 return (1);
2515}
2516
2517static void
2518demangle_function_name (work, mangled, declp, scan)
2519 struct work_stuff *work;
2520 const char **mangled;
2521 string *declp;
2522 const char *scan;
2523{
2524 int i;
2525 int len;
2526 string type;
2527 const char *tem;
2528
2529 string_appendn (declp, (*mangled), scan - (*mangled));
2530 string_need (declp, 1);
2531 *(declp -> p) = '\0';
2532
2533 /* Consume the function name, including the "__" separating the name
2534 from the signature. We are guaranteed that SCAN points to the
0f41302f 2535 separator. */
a3184468
JM
2536
2537 (*mangled) = scan + 2;
2538
2539 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2540 {
2541
2542 /* See if we have an ARM style constructor or destructor operator.
2543 If so, then just record it, clear the decl, and return.
2544 We can't build the actual constructor/destructor decl until later,
0f41302f 2545 when we recover the class name from the signature. */
a3184468
JM
2546
2547 if (strcmp (declp -> b, "__ct") == 0)
2548 {
2549 work -> constructor += 1;
2550 string_clear (declp);
2551 return;
2552 }
2553 else if (strcmp (declp -> b, "__dt") == 0)
2554 {
2555 work -> destructor += 1;
2556 string_clear (declp);
2557 return;
2558 }
2559 }
2560
2561 if (declp->p - declp->b >= 3
2562 && declp->b[0] == 'o'
2563 && declp->b[1] == 'p'
2564 && strchr (cplus_markers, declp->b[2]) != NULL)
2565 {
2566 /* see if it's an assignment expression */
2567 if (declp->p - declp->b >= 10 /* op$assign_ */
2568 && memcmp (declp->b + 3, "assign_", 7) == 0)
2569 {
2570 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2571 {
2572 len = declp->p - declp->b - 10;
2573 if (strlen (optable[i].in) == len
2574 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2575 {
2576 string_clear (declp);
2577 string_append (declp, "operator");
2578 string_append (declp, optable[i].out);
2579 string_append (declp, "=");
2580 break;
2581 }
2582 }
2583 }
2584 else
2585 {
2586 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2587 {
2588 int len = declp->p - declp->b - 3;
2589 if (strlen (optable[i].in) == len
2590 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2591 {
2592 string_clear (declp);
2593 string_append (declp, "operator");
2594 string_append (declp, optable[i].out);
2595 break;
2596 }
2597 }
2598 }
2599 }
2600 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2601 && strchr (cplus_markers, declp->b[4]) != NULL)
2602 {
2603 /* type conversion operator */
2604 tem = declp->b + 5;
2605 if (do_type (work, &tem, &type))
2606 {
2607 string_clear (declp);
2608 string_append (declp, "operator ");
2609 string_appends (declp, &type);
2610 string_delete (&type);
2611 }
2612 }
2613 else if (declp->b[0] == '_' && declp->b[1] == '_'
2614 && declp->b[2] == 'o' && declp->b[3] == 'p')
2615 {
2616 /* ANSI. */
2617 /* type conversion operator. */
2618 tem = declp->b + 4;
2619 if (do_type (work, &tem, &type))
2620 {
2621 string_clear (declp);
2622 string_append (declp, "operator ");
2623 string_appends (declp, &type);
2624 string_delete (&type);
2625 }
2626 }
2627 else if (declp->b[0] == '_' && declp->b[1] == '_'
2628 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2629 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2630 {
2631 if (declp->b[4] == '\0')
2632 {
2633 /* Operator. */
2634 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2635 {
2636 if (strlen (optable[i].in) == 2
2637 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2638 {
2639 string_clear (declp);
2640 string_append (declp, "operator");
2641 string_append (declp, optable[i].out);
2642 break;
2643 }
2644 }
2645 }
2646 else
2647 {
2648 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2649 {
0f41302f 2650 /* Assignment. */
a3184468
JM
2651 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2652 {
2653 if (strlen (optable[i].in) == 3
2654 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2655 {
2656 string_clear (declp);
2657 string_append (declp, "operator");
2658 string_append (declp, optable[i].out);
2659 break;
2660 }
2661 }
2662 }
2663 }
2664 }
2665}
2666
2667/* a mini string-handling package */
2668
2669static void
2670string_need (s, n)
2671 string *s;
2672 int n;
2673{
2674 int tem;
2675
2676 if (s->b == NULL)
2677 {
2678 if (n < 32)
2679 {
2680 n = 32;
2681 }
2682 s->p = s->b = xmalloc (n);
2683 s->e = s->b + n;
2684 }
2685 else if (s->e - s->p < n)
2686 {
2687 tem = s->p - s->b;
2688 n += tem;
2689 n *= 2;
2690 s->b = xrealloc (s->b, n);
2691 s->p = s->b + tem;
2692 s->e = s->b + n;
2693 }
2694}
2695
2696static void
2697string_delete (s)
2698 string *s;
2699{
2700 if (s->b != NULL)
2701 {
2702 free (s->b);
2703 s->b = s->e = s->p = NULL;
2704 }
2705}
2706
2707static void
2708string_init (s)
2709 string *s;
2710{
2711 s->b = s->p = s->e = NULL;
2712}
2713
2714static void
2715string_clear (s)
2716 string *s;
2717{
2718 s->p = s->b;
2719}
2720
2721#if 0
2722
2723static int
2724string_empty (s)
2725 string *s;
2726{
2727 return (s->b == s->p);
2728}
2729
2730#endif
2731
2732static void
2733string_append (p, s)
2734 string *p;
2735 const char *s;
2736{
2737 int n;
2738 if (s == NULL || *s == '\0')
2739 return;
2740 n = strlen (s);
2741 string_need (p, n);
2742 memcpy (p->p, s, n);
2743 p->p += n;
2744}
2745
2746static void
2747string_appends (p, s)
2748 string *p, *s;
2749{
2750 int n;
2751
2752 if (s->b != s->p)
2753 {
2754 n = s->p - s->b;
2755 string_need (p, n);
2756 memcpy (p->p, s->b, n);
2757 p->p += n;
2758 }
2759}
2760
2761static void
2762string_appendn (p, s, n)
2763 string *p;
2764 const char *s;
2765 int n;
2766{
2767 if (n != 0)
2768 {
2769 string_need (p, n);
2770 memcpy (p->p, s, n);
2771 p->p += n;
2772 }
2773}
2774
2775static void
2776string_prepend (p, s)
2777 string *p;
2778 const char *s;
2779{
2780 if (s != NULL && *s != '\0')
2781 {
2782 string_prependn (p, s, strlen (s));
2783 }
2784}
2785
2786static void
2787string_prepends (p, s)
2788 string *p, *s;
2789{
2790 if (s->b != s->p)
2791 {
2792 string_prependn (p, s->b, s->p - s->b);
2793 }
2794}
2795
2796static void
2797string_prependn (p, s, n)
2798 string *p;
2799 const char *s;
2800 int n;
2801{
2802 char *q;
2803
2804 if (n != 0)
2805 {
2806 string_need (p, n);
2807 for (q = p->p - 1; q >= p->b; q--)
2808 {
2809 q[n] = q[0];
2810 }
2811 memcpy (p->b, s, n);
2812 p->p += n;
2813 }
2814}
2815
2816/* To generate a standalone demangler program for testing purposes,
2817 just compile and link this file with -DMAIN and libiberty.a. When
2818 run, it demangles each command line arg, or each stdin string, and
0f41302f 2819 prints the result on stdout. */
a3184468
JM
2820
2821#ifdef MAIN
2822
2823static void
2824demangle_it (mangled_name)
2825 char *mangled_name;
2826{
2827 char *result;
2828
2829 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2830 if (result == NULL)
2831 {
2832 printf ("%s\n", mangled_name);
2833 }
2834 else
2835 {
2836 printf ("%s\n", result);
2837 free (result);
2838 }
2839}
2840
2841#include "getopt.h"
2842
2843static char *program_name;
2844static char *program_version = VERSION;
2845
2846static void
2847usage (stream, status)
2848 FILE *stream;
2849 int status;
2850{
2851 fprintf (stream, "\
2852Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2853 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2854 [--help] [--version] [arg...]\n",
2855 program_name);
2856 exit (status);
2857}
2858
2859#define MBUF_SIZE 512
2860char mbuffer[MBUF_SIZE];
2861
0f41302f 2862/* Defined in the automatically-generated underscore.c. */
a3184468
JM
2863extern int prepends_underscore;
2864
2865int strip_underscore = 0;
2866
2867static struct option long_options[] = {
2868 {"strip-underscores", no_argument, 0, '_'},
2869 {"format", required_argument, 0, 's'},
2870 {"help", no_argument, 0, 'h'},
2871 {"no-strip-underscores", no_argument, 0, 'n'},
2872 {"version", no_argument, 0, 'v'},
2873 {0, no_argument, 0, 0}
2874};
2875
2876int
2877main (argc, argv)
2878 int argc;
2879 char **argv;
2880{
2881 char *result;
2882 int c;
2883
2884 program_name = argv[0];
2885
2886 strip_underscore = prepends_underscore;
2887
2888 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2889 {
2890 switch (c)
2891 {
2892 case '?':
2893 usage (stderr, 1);
2894 break;
2895 case 'h':
2896 usage (stdout, 0);
2897 case 'n':
2898 strip_underscore = 0;
2899 break;
2900 case 'v':
2901 printf ("GNU %s version %s\n", program_name, program_version);
2902 exit (0);
2903 case '_':
2904 strip_underscore = 1;
2905 break;
2906 case 's':
2907 if (strcmp (optarg, "gnu") == 0)
2908 {
2909 current_demangling_style = gnu_demangling;
2910 }
2911 else if (strcmp (optarg, "lucid") == 0)
2912 {
2913 current_demangling_style = lucid_demangling;
2914 }
2915 else if (strcmp (optarg, "arm") == 0)
2916 {
2917 current_demangling_style = arm_demangling;
2918 }
2919 else
2920 {
2921 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2922 program_name, optarg);
2923 exit (1);
2924 }
2925 break;
2926 }
2927 }
2928
2929 if (optind < argc)
2930 {
2931 for ( ; optind < argc; optind++)
2932 {
2933 demangle_it (argv[optind]);
2934 }
2935 }
2936 else
2937 {
2938 for (;;)
2939 {
2940 int i = 0;
2941 c = getchar ();
0f41302f 2942 /* Try to read a label. */
a3184468
JM
2943 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2944 {
2945 if (i >= MBUF_SIZE-1)
2946 break;
2947 mbuffer[i++] = c;
2948 c = getchar ();
2949 }
2950 if (i > 0)
2951 {
2952 int skip_first = 0;
2953
2954 if (mbuffer[0] == '.')
2955 ++skip_first;
2956 if (strip_underscore && mbuffer[skip_first] == '_')
2957 ++skip_first;
2958
2959 if (skip_first > i)
2960 skip_first = i;
2961
2962 mbuffer[i] = 0;
2963
2964 result = cplus_demangle (mbuffer + skip_first,
2965 DMGL_PARAMS | DMGL_ANSI);
2966 if (result)
2967 {
2968 if (mbuffer[0] == '.')
2969 putc ('.', stdout);
2970 fputs (result, stdout);
2971 free (result);
2972 }
2973 else
2974 fputs (mbuffer, stdout);
2975
2976 fflush (stdout);
2977 }
2978 if (c == EOF)
2979 break;
2980 putchar (c);
2981 }
2982 }
2983
2984 exit (0);
2985}
2986
2987static void
2988fatal (str)
2989 char *str;
2990{
2991 fprintf (stderr, "%s: %s\n", program_name, str);
2992 exit (1);
2993}
2994
2995char * malloc ();
2996char * realloc ();
2997
2998char *
2999xmalloc (size)
3000 unsigned size;
3001{
3002 register char *value = (char *) malloc (size);
3003 if (value == 0)
3004 fatal ("virtual memory exhausted");
3005 return value;
3006}
3007
3008char *
3009xrealloc (ptr, size)
3010 char *ptr;
3011 unsigned size;
3012{
3013 register char *value = (char *) realloc (ptr, size);
3014 if (value == 0)
3015 fatal ("virtual memory exhausted");
3016 return value;
3017}
3018#endif /* main */
This page took 0.373111 seconds and 5 git commands to generate.