m88k native support
[deliverable/binutils-gdb.git] / gdb / cplus-dem.c
1 /* Demangler for GNU C++
2 Copyright 1989, 1991 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /* This is for g++ 1.95.03 (November 13 version). */
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
26 available memory. */
27
28 /* GDB-specific, FIXME. */
29 #include "defs.h"
30 #include "demangle.h"
31
32 #include <ctype.h>
33 #include <string.h>
34
35 /* In order to allow a single demangler executable to demangle strings
36 using various common values of CPLUS_MARKER, as well as any specific
37 one set at compile time, we maintain a string containing all the
38 commonly used ones, and check to see if the marker we are looking for
39 is in that string. CPLUS_MARKER is usually '$' on systems where the
40 assembler can deal with that. Where the assembler can't, it's usually
41 '.' (but on many systems '.' is used for other things). We put the
42 current defined CPLUS_MARKER first (which defaults to '$'), followed
43 by the next most common value, followed by an explicit '$' in case
44 the value of CPLUS_MARKER is not '$'.
45
46 We could avoid this if we could just get g++ to tell us what the actual
47 cplus marker character is as part of the debug information, perhaps by
48 ensuring that it is the character that terminates the gcc<n>_compiled
49 marker symbol (FIXME). */
50
51 #if !defined (CPLUS_MARKER)
52 #define CPLUS_MARKER '$'
53 #endif
54
55 static const char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
56
57 #ifndef __STDC__
58 #define const
59 #endif
60
61 /* Stuff that is shared between sub-routines.
62 * Using a shared structure allows cplus_demangle to be reentrant. */
63
64 struct work_stuff
65 {
66 int options;
67 char **typevec;
68 int ntypes;
69 int typevec_size;
70 int constructor;
71 int destructor;
72 int static_type; /* A static member function */
73 int const_type; /* A const member function */
74 };
75
76 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
77 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
78
79 static const struct optable
80 {
81 const char *in;
82 const char *out;
83 int flags;
84 } optable[] = {
85 "nw", " new", DMGL_ANSI, /* new (1.92, ansi) */
86 "dl", " delete", DMGL_ANSI, /* new (1.92, ansi) */
87 "new", " new", 0, /* old (1.91, and 1.x) */
88 "delete", " delete", 0, /* old (1.91, and 1.x) */
89 "as", "=", DMGL_ANSI, /* ansi */
90 "ne", "!=", DMGL_ANSI, /* old, ansi */
91 "eq", "==", DMGL_ANSI, /* old, ansi */
92 "ge", ">=", DMGL_ANSI, /* old, ansi */
93 "gt", ">", DMGL_ANSI, /* old, ansi */
94 "le", "<=", DMGL_ANSI, /* old, ansi */
95 "lt", "<", DMGL_ANSI, /* old, ansi */
96 "plus", "+", 0, /* old */
97 "pl", "+", DMGL_ANSI, /* ansi */
98 "apl", "+=", DMGL_ANSI, /* ansi */
99 "minus", "-", 0, /* old */
100 "mi", "-", DMGL_ANSI, /* ansi */
101 "ami", "-=", DMGL_ANSI, /* ansi */
102 "mult", "*", 0, /* old */
103 "ml", "*", DMGL_ANSI, /* ansi */
104 "amu", "*=", DMGL_ANSI, /* ansi (ARM/Lucid) */
105 "aml", "*=", DMGL_ANSI, /* ansi (GNU/g++) */
106 "convert", "+", 0, /* old (unary +) */
107 "negate", "-", 0, /* old (unary -) */
108 "trunc_mod", "%", 0, /* old */
109 "md", "%", DMGL_ANSI, /* ansi */
110 "amd", "%=", DMGL_ANSI, /* ansi */
111 "trunc_div", "/", 0, /* old */
112 "dv", "/", DMGL_ANSI, /* ansi */
113 "adv", "/=", DMGL_ANSI, /* ansi */
114 "truth_andif", "&&", 0, /* old */
115 "aa", "&&", DMGL_ANSI, /* ansi */
116 "truth_orif", "||", 0, /* old */
117 "oo", "||", DMGL_ANSI, /* ansi */
118 "truth_not", "!", 0, /* old */
119 "nt", "!", DMGL_ANSI, /* ansi */
120 "postincrement","++", 0, /* old */
121 "pp", "++", DMGL_ANSI, /* ansi */
122 "postdecrement","--", 0, /* old */
123 "mm", "--", DMGL_ANSI, /* ansi */
124 "bit_ior", "|", 0, /* old */
125 "or", "|", DMGL_ANSI, /* ansi */
126 "aor", "|=", DMGL_ANSI, /* ansi */
127 "bit_xor", "^", 0, /* old */
128 "er", "^", DMGL_ANSI, /* ansi */
129 "aer", "^=", DMGL_ANSI, /* ansi */
130 "bit_and", "&", 0, /* old */
131 "ad", "&", DMGL_ANSI, /* ansi */
132 "aad", "&=", DMGL_ANSI, /* ansi */
133 "bit_not", "~", 0, /* old */
134 "co", "~", DMGL_ANSI, /* ansi */
135 "call", "()", 0, /* old */
136 "cl", "()", DMGL_ANSI, /* ansi */
137 "alshift", "<<", 0, /* old */
138 "ls", "<<", DMGL_ANSI, /* ansi */
139 "als", "<<=", DMGL_ANSI, /* ansi */
140 "arshift", ">>", 0, /* old */
141 "rs", ">>", DMGL_ANSI, /* ansi */
142 "ars", ">>=", DMGL_ANSI, /* ansi */
143 "component", "->", 0, /* old */
144 "pt", "->", DMGL_ANSI, /* ansi; Lucid C++ form */
145 "rf", "->", DMGL_ANSI, /* ansi; ARM/GNU form */
146 "indirect", "*", 0, /* old */
147 "method_call", "->()", 0, /* old */
148 "addr", "&", 0, /* old (unary &) */
149 "array", "[]", 0, /* old */
150 "vc", "[]", DMGL_ANSI, /* ansi */
151 "compound", ", ", 0, /* old */
152 "cm", ", ", DMGL_ANSI, /* ansi */
153 "cond", "?:", 0, /* old */
154 "cn", "?:", DMGL_ANSI, /* psuedo-ansi */
155 "max", ">?", 0, /* old */
156 "mx", ">?", DMGL_ANSI, /* psuedo-ansi */
157 "min", "<?", 0, /* old */
158 "mn", "<?", DMGL_ANSI, /* psuedo-ansi */
159 "nop", "", 0, /* old (for operator=) */
160 "rm", "->*", DMGL_ANSI, /* ansi */
161 };
162
163
164 typedef struct string /* Beware: these aren't required to be */
165 { /* '\0' terminated. */
166 char *b; /* pointer to start of string */
167 char *p; /* pointer after last character */
168 char *e; /* pointer after end of allocated space */
169 } string;
170
171 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
172 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
173 string_prepend(str, " ");}
174 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
175 string_append(str, " ");}
176
177 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/cfront virtual table prefix */
178 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
179
180 /* Prototypes for local functions */
181
182 static char *
183 mop_up PARAMS ((struct work_stuff *, string *, int));
184
185 #if 0
186 static int
187 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
188 #endif
189
190 static int
191 demangle_template PARAMS ((struct work_stuff *work, const char **, string *));
192
193 static int
194 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
195 int));
196
197 static int
198 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
199
200 static int
201 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
202
203 static int
204 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
205
206 static int
207 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
208
209 static int
210 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
211
212 static int
213 cfront_special PARAMS ((struct work_stuff *, const char **, string *));
214
215 static void
216 string_need PARAMS ((string *, int));
217
218 static void
219 string_delete PARAMS ((string *));
220
221 static void
222 string_init PARAMS ((string *));
223
224 static void
225 string_clear PARAMS ((string *));
226
227 #if 0
228 static int
229 string_empty PARAMS ((string *));
230 #endif
231
232 static void
233 string_append PARAMS ((string *, const char *));
234
235 static void
236 string_appends PARAMS ((string *, string *));
237
238 static void
239 string_appendn PARAMS ((string *, const char *, int));
240
241 static void
242 string_prepend PARAMS ((string *, const char *));
243
244 static void
245 string_prependn PARAMS ((string *, const char *, int));
246
247 static int
248 get_count PARAMS ((const char **, int *));
249
250 static int
251 consume_count PARAMS ((const char **));
252
253 static int
254 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
255
256 static int
257 do_type PARAMS ((struct work_stuff *, const char **, string *));
258
259 static int
260 do_arg PARAMS ((struct work_stuff *, const char **, string *));
261
262 static void
263 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
264 const char *));
265
266 static void
267 remember_type PARAMS ((struct work_stuff *, const char *, int));
268
269 static void
270 forget_types PARAMS ((struct work_stuff *));
271
272 #if 0
273 static void
274 string_prepends PARAMS ((string *, string *));
275 #endif
276
277 /* Translate count to integer, consuming tokens in the process.
278 Conversion terminates on the first non-digit character. */
279
280 static int
281 consume_count (type)
282 const char **type;
283 {
284 int count = 0;
285
286 do
287 {
288 count *= 10;
289 count += **type - '0';
290 (*type)++;
291 } while (isdigit (**type));
292 return (count);
293 }
294
295 /* Takes operator name as e.g. "++" and returns mangled
296 operator name (e.g. "postincrement_expr"), or NULL if not found.
297
298 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
299 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
300
301 char *
302 cplus_mangle_opname (opname, options)
303 char *opname;
304 int options;
305 {
306 int i;
307 int len;
308
309 len = strlen (opname);
310 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
311 {
312 if (strlen (optable[i].out) == len
313 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
314 && memcmp (optable[i].out, opname, len) == 0)
315 return ((char *)optable[i].in);
316 }
317 return (0);
318 }
319
320 /* char *cplus_demangle (const char *name, int options)
321
322 If NAME is a mangled function name produced by GNU C++, then
323 a pointer to a malloced string giving a C++ representation
324 of the name will be returned; otherwise NULL will be returned.
325 It is the caller's responsibility to free the string which
326 is returned.
327
328 The OPTIONS arg may contain one or more of the following bits:
329
330 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
331 included.
332 DMGL_PARAMS Function parameters are included.
333
334 For example,
335
336 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
337 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
338 cplus_demangle ("foo__1Ai", 0) => "A::foo"
339
340 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
341 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
342 cplus_demangle ("foo__1Afe", 0) => "A::foo"
343
344 Note that any leading underscores, or other such characters prepended by
345 the compilation system, are presumed to have already been stripped from
346 TYPE. */
347
348 char *
349 cplus_demangle (mangled, options)
350 const char *mangled;
351 int options;
352 {
353 string decl;
354 int success = 0;
355 struct work_stuff work[1];
356 char *demangled = NULL;
357
358 if ((mangled != NULL) && (*mangled != '\0'))
359 {
360 memset ((char *) work, 0, sizeof (work));
361 work -> options = options;
362
363 string_init (&decl);
364
365 /* First check to see if gnu style demangling is active and if the
366 string to be demangled contains a CPLUS_MARKER. If so, attempt to
367 recognize one of the gnu special forms rather than looking for a
368 standard prefix. In particular, don't worry about whether there
369 is a "__" string in the mangled string. Consider "_$_5__foo" for
370 example. */
371
372 if ((AUTO_DEMANGLING || GNU_DEMANGLING)
373 && (strpbrk (mangled, cplus_markers)) != NULL)
374 {
375 success = gnu_special (work, &mangled, &decl);
376 }
377 else
378 {
379 success = demangle_prefix (work, &mangled, &decl);
380 }
381 if (success && (*mangled != '\0'))
382 {
383 success = demangle_signature (work, &mangled, &decl);
384 }
385 demangled = mop_up (work, &decl, success);
386 }
387 return (demangled);
388 }
389
390 static char *
391 mop_up (work, declp, success)
392 struct work_stuff *work;
393 string *declp;
394 int success;
395 {
396 int i;
397 char *demangled = NULL;
398
399 /* Discard the remembered types, if any. */
400
401 forget_types (work);
402 if (work -> typevec != NULL)
403 {
404 free ((char *) work -> typevec);
405 }
406
407 /* If demangling was successful, ensure that the demangled string is null
408 terminated and return it. Otherwise, free the demangling decl. */
409
410 if (!success)
411 {
412 string_delete (declp);
413 }
414 else
415 {
416 string_appendn (declp, "", 1);
417 demangled = declp -> b;
418 }
419 return (demangled);
420 }
421
422 /*
423
424 LOCAL FUNCTION
425
426 demangle_signature -- demangle the signature part of a mangled name
427
428 SYNOPSIS
429
430 static int
431 demangle_signature (struct work_stuff *work, const char **mangled,
432 string *declp);
433
434 DESCRIPTION
435
436 Consume and demangle the signature portion of the mangled name.
437
438 DECLP is the string where demangled output is being built. At
439 entry it contains the demangled root name from the mangled name
440 prefix. I.E. either a demangled operator name or the root function
441 name. In some special cases, it may contain nothing.
442
443 *MANGLED points to the current unconsumed location in the mangled
444 name. As tokens are consumed and demangling is performed, the
445 pointer is updated to continuously point at the next token to
446 be consumed.
447
448 Demangling GNU style mangled names is nasty because there is no
449 explicit token that marks the start of the outermost function
450 argument list.
451 */
452
453 static int
454 demangle_signature (work, mangled, declp)
455 struct work_stuff *work;
456 const char **mangled;
457 string *declp;
458 {
459 int success = 1;
460 int func_done = 0;
461 int expect_func = 0;
462 const char *oldmangled;
463
464 while (success && (**mangled != '\0'))
465 {
466 switch (**mangled)
467 {
468 case 'Q':
469 oldmangled = *mangled;
470 success = demangle_qualified (work, mangled, declp, 1);
471 if (success)
472 {
473 remember_type (work, oldmangled, *mangled - oldmangled);
474 }
475 if (AUTO_DEMANGLING || GNU_DEMANGLING)
476 {
477 expect_func = 1;
478 }
479 break;
480
481 case 'S':
482 /* Static member function */
483 (*mangled)++;
484 work -> static_type = 1;
485 break;
486
487 case 'C':
488 /* a const member function */
489 (*mangled)++;
490 work -> const_type = 1;
491 break;
492
493 case '0': case '1': case '2': case '3': case '4':
494 case '5': case '6': case '7': case '8': case '9':
495 oldmangled = *mangled;
496 success = demangle_class (work, mangled, declp);
497 if (success)
498 {
499 remember_type (work, oldmangled, *mangled - oldmangled);
500 }
501 if (AUTO_DEMANGLING || GNU_DEMANGLING)
502 {
503 expect_func = 1;
504 }
505 break;
506
507 case 'F':
508 /* Function */
509 /* ARM style demangling includes a specific 'F' character after
510 the class name. For GNU style, it is just implied. So we can
511 safely just consume any 'F' at this point and be compatible
512 with either style. */
513
514 func_done = 1;
515 (*mangled)++;
516
517 /* For lucid/cfront style we have to forget any types we might
518 have remembered up to this point, since they were not argument
519 types. GNU style considers all types seen as available for
520 back references. See comment in demangle_args() */
521
522 if (LUCID_DEMANGLING || CFRONT_DEMANGLING)
523 {
524 forget_types (work);
525 }
526 success = demangle_args (work, mangled, declp);
527 break;
528
529 case 't':
530 /* Template */
531 success = demangle_template (work, mangled, declp);
532 break;
533
534 case '_':
535 /* At the outermost level, we cannot have a return type specified,
536 so if we run into another '_' at this point we are dealing with
537 a mangled name that is either bogus, or has been mangled by
538 some algorithm we don't know how to deal with. So just
539 reject the entire demangling. */
540 success = 0;
541 break;
542
543 default:
544 if (AUTO_DEMANGLING || GNU_DEMANGLING)
545 {
546 /* Assume we have stumbled onto the first outermost function
547 argument token, and start processing args. */
548 func_done = 1;
549 success = demangle_args (work, mangled, declp);
550 }
551 else
552 {
553 /* Non-GNU demanglers use a specific token to mark the start
554 of the outermost function argument tokens. Typically 'F',
555 for ARM-demangling, for example. So if we find something
556 we are not prepared for, it must be an error. */
557 success = 0;
558 }
559 break;
560 }
561 if (AUTO_DEMANGLING || GNU_DEMANGLING)
562 {
563 if (success && expect_func)
564 {
565 func_done = 1;
566 success = demangle_args (work, mangled, declp);
567 }
568 }
569 }
570 if (success && !func_done)
571 {
572 if (AUTO_DEMANGLING || GNU_DEMANGLING)
573 {
574 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
575 bar__3fooi is 'foo::bar(int)'. We get here when we find the
576 first case, and need to ensure that the '(void)' gets added to
577 the current declp. Note that with ARM, the first case
578 represents the name of a static data member 'foo::bar',
579 which is in the current declp, so we leave it alone. */
580 success = demangle_args (work, mangled, declp);
581 }
582 }
583 if (success && work -> static_type && PRINT_ARG_TYPES)
584 {
585 string_append (declp, " static");
586 }
587 if (success && work -> const_type && PRINT_ARG_TYPES)
588 {
589 string_append (declp, " const");
590 }
591 return (success);
592 }
593
594 #if 0
595
596 static int
597 demangle_method_args (work, mangled, declp)
598 struct work_stuff *work;
599 const char **mangled;
600 string *declp;
601 {
602 int success = 0;
603
604 if (work -> static_type)
605 {
606 string_append (declp, *mangled + 1);
607 *mangled += strlen (*mangled);
608 success = 1;
609 }
610 else
611 {
612 success = demangle_args (work, mangled, declp);
613 }
614 return (success);
615 }
616
617 #endif
618
619 static int
620 demangle_template (work, mangled, declp)
621 struct work_stuff *work;
622 const char **mangled;
623 string *declp;
624 {
625 int i;
626 string tname;
627 string trawname;
628 int is_pointer;
629 int is_real;
630 int is_integral;
631 int r;
632 int need_comma = 0;
633 int success = 0;
634 int done;
635 const char *old_p;
636 int symbol_len;
637 string temp;
638
639 (*mangled)++;
640 string_init (&tname);
641 string_init (&trawname);
642 /* get template name */
643 if (!get_count (mangled, &r))
644 {
645 return (0);
646 }
647 string_appendn (&tname, *mangled, r);
648 string_appendn (&trawname, *mangled, r);
649 string_appendn (&trawname, "", 1);
650 *mangled += r;
651 string_append (&tname, "<");
652 /* get size of template parameter list */
653 if (!get_count (mangled, &r))
654 {
655 return (0);
656 }
657 for (i = 0; i < r; i++)
658 {
659 if (need_comma)
660 {
661 string_append (&tname, ", ");
662 }
663 /* Z for type parameters */
664 if (**mangled == 'Z')
665 {
666 (*mangled)++;
667 success = do_type (work, mangled, &temp);
668 string_appendn (&temp, "", 1);
669 if (success)
670 {
671 string_append (&tname, temp.b);
672 }
673 string_delete(&temp);
674 if (!success)
675 {
676 break;
677 }
678 }
679 else
680 {
681 /* otherwise, value parameter */
682 old_p = *mangled;
683 is_pointer = 0;
684 is_real = 0;
685 is_integral = 0;
686 done = 0;
687 success = do_type (work, mangled, &temp);
688 string_appendn (&temp, "", 1);
689 if (success)
690 {
691 string_append (&tname, temp.b);
692 }
693 string_delete(&temp);
694 if (!success)
695 {
696 break;
697 }
698 string_append (&tname, "=");
699 while (*old_p && !done)
700 {
701 switch (*old_p)
702 {
703 case 'P':
704 case 'R':
705 done = is_pointer = 1;
706 break;
707 case 'C': /* const */
708 case 'S': /* explicitly signed [char] */
709 case 'U': /* unsigned */
710 case 'V': /* volatile */
711 case 'F': /* function */
712 case 'M': /* member function */
713 case 'O': /* ??? */
714 old_p++;
715 continue;
716 case 'Q': /* repetition of following */
717 case 'T': /* remembered type */
718 abort ();
719 break;
720 case 'v': /* void */
721 abort ();
722 break;
723 case 'x': /* long long */
724 case 'l': /* long */
725 case 'i': /* int */
726 case 's': /* short */
727 case 'c': /* char */
728 done = is_integral = 1;
729 break;
730 case 'r': /* long double */
731 case 'd': /* double */
732 case 'f': /* float */
733 done = is_real = 1;
734 break;
735 default:
736 abort ();
737 }
738 }
739 if (is_integral)
740 {
741 if (**mangled == 'm')
742 {
743 string_appendn (&tname, "-", 1);
744 (*mangled)++;
745 }
746 while (isdigit (**mangled))
747 {
748 string_appendn (&tname, *mangled, 1);
749 (*mangled)++;
750 }
751 }
752 else if (is_real)
753 {
754 if (**mangled == 'm')
755 {
756 string_appendn (&tname, "-", 1);
757 (*mangled)++;
758 }
759 while (isdigit (**mangled))
760 {
761 string_appendn (&tname, *mangled, 1);
762 (*mangled)++;
763 }
764 if (**mangled == '.') /* fraction */
765 {
766 string_appendn (&tname, ".", 1);
767 (*mangled)++;
768 while (isdigit (**mangled))
769 {
770 string_appendn (&tname, *mangled, 1);
771 (*mangled)++;
772 }
773 }
774 if (**mangled == 'e') /* exponent */
775 {
776 string_appendn (&tname, "e", 1);
777 (*mangled)++;
778 while (isdigit (**mangled))
779 {
780 string_appendn (&tname, *mangled, 1);
781 (*mangled)++;
782 }
783 }
784 }
785 else if (is_pointer)
786 {
787 if (!get_count (mangled, &symbol_len))
788 {
789 success = 0;
790 break;
791 }
792 string_appendn (&tname, *mangled, symbol_len);
793 *mangled += symbol_len;
794 }
795 }
796 need_comma = 1;
797 }
798 string_append (&tname, ">::");
799 if (work -> destructor)
800 {
801 string_append (&tname, "~");
802 }
803 if (work -> constructor || work -> destructor)
804 {
805 string_append (&tname, trawname.b);
806 }
807 string_delete(&trawname);
808
809 if (!success)
810 {
811 string_delete(&tname);
812 }
813 else
814 {
815 string_prepend (declp, tname.b);
816 string_delete (&tname);
817
818 if (work -> static_type)
819 {
820 string_append (declp, *mangled + 1);
821 *mangled += strlen (*mangled);
822 success = 1;
823 }
824 else
825 {
826 success = demangle_args (work, mangled, declp);
827 }
828 }
829 return (success);
830 }
831
832 /*
833
834 LOCAL FUNCTION
835
836 demangle_class -- demangle a mangled class sequence
837
838 SYNOPSIS
839
840 static int
841 demangle_class (struct work_stuff *work, const char **mangled,
842 strint *declp)
843
844 DESCRIPTION
845
846 DECLP points to the buffer into which demangling is being done.
847
848 *MANGLED points to the current token to be demangled. On input,
849 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
850 On exit, it points to the next token after the mangled class on
851 success, or the first unconsumed token on failure.
852
853 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
854 we are demangling a constructor or destructor. In this case
855 we prepend "class::class" or "class::~class" to DECLP.
856
857 Otherwise, we prepend "class::" to the current DECLP.
858
859 Reset the constructor/destructor flags once they have been
860 "consumed". This allows demangle_class to be called later during
861 the same demangling, to do normal class demangling.
862
863 Returns 1 if demangling is successful, 0 otherwise.
864
865 */
866
867 static int
868 demangle_class (work, mangled, declp)
869 struct work_stuff *work;
870 const char **mangled;
871 string *declp;
872 {
873 int n;
874 int success = 0;
875
876 n = consume_count (mangled);
877 if (strlen (*mangled) >= n)
878 {
879 if (work -> constructor || work -> destructor)
880 {
881 string_prependn (declp, *mangled, n);
882 if (work -> destructor)
883 {
884 string_prepend (declp, "~");
885 }
886 work -> constructor = work -> destructor = 0;
887 }
888 string_prepend (declp, "::");
889 string_prependn (declp, *mangled, n);
890 *mangled += n;
891 success = 1;
892 }
893 return (success);
894 }
895
896 /*
897
898 LOCAL FUNCTION
899
900 demangle_prefix -- consume the mangled name prefix and find signature
901
902 SYNOPSIS
903
904 static int
905 demangle_prefix (struct work_stuff *work, const char **mangled,
906 string *declp);
907
908 DESCRIPTION
909
910 Consume and demangle the prefix of the mangled name.
911
912 DECLP points to the string buffer into which demangled output is
913 placed. On entry, the buffer is empty. On exit it contains
914 the root function name, the demangled operator name, or in some
915 special cases either nothing or the completely demangled result.
916
917 MANGLED points to the current pointer into the mangled name. As each
918 token of the mangled name is consumed, it is updated. Upon entry
919 the current mangled name pointer points to the first character of
920 the mangled name. Upon exit, it should point to the first character
921 of the signature if demangling was successful, or to the first
922 unconsumed character if demangling of the prefix was unsuccessful.
923
924 Returns 1 on success, 0 otherwise.
925 */
926
927 static int
928 demangle_prefix (work, mangled, declp)
929 struct work_stuff *work;
930 const char **mangled;
931 string *declp;
932 {
933 int success = 1;
934 const char *scan;
935 int i;
936
937 scan = strstr (*mangled, "__");
938
939 if (scan != NULL)
940 {
941 /* We found a sequence of two or more '_', ensure that we start at
942 the last pair in the sequence. */
943 i = strspn (scan, "_");
944 if (i > 2)
945 {
946 scan += (i - 2);
947 }
948 }
949
950 if (scan == NULL)
951 {
952 success = 0;
953 }
954 else if (work -> static_type)
955 {
956 if (!isdigit (scan[0]) && (scan[0] != 't'))
957 {
958 success = 0;
959 }
960 }
961 else if ((scan == *mangled) && (isdigit (scan[2]) || (scan[2] == 'Q')))
962 {
963 /* A GNU style constructor starts with "__<digit>" or "__Q". */
964 work -> constructor = 1;
965 *mangled = scan + 2;
966 }
967 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
968 {
969 /* Mangled name starts with "__". Skip over any leading '_' characters,
970 then find the next "__" that separates the prefix from the signature.
971 */
972 if (!(CFRONT_DEMANGLING || LUCID_DEMANGLING)
973 || (cfront_special (work, mangled, declp) == 0))
974 {
975 while (*scan == '_')
976 {
977 scan++;
978 }
979 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
980 {
981 /* No separator (I.E. "__not_mangled"), or empty signature
982 (I.E. "__not_mangled_either__") */
983 success = 0;
984 }
985 else
986 {
987 demangle_function_name (work, mangled, declp, scan);
988 }
989 }
990 }
991 else if (*(scan + 2) != '\0')
992 {
993 /* Mangled name does not start with "__" but does have one somewhere
994 in there with non empty stuff after it. Looks like a global
995 function name. */
996 demangle_function_name (work, mangled, declp, scan);
997 }
998 else
999 {
1000 /* Doesn't look like a mangled name */
1001 success = 0;
1002 }
1003 return (success);
1004 }
1005
1006 /*
1007
1008 LOCAL FUNCTION
1009
1010 gnu_special -- special handling of gnu mangled strings
1011
1012 SYNOPSIS
1013
1014 static int
1015 gnu_special (struct work_stuff *work, const char **mangled,
1016 string *declp);
1017
1018
1019 DESCRIPTION
1020
1021 Process some special GNU style mangling forms that don't fit
1022 the normal pattern. For example:
1023
1024 _$_3foo (destructor for class foo)
1025 _vt$foo (foo virtual table)
1026 _vt$foo$bar (foo::bar virtual table)
1027 _3foo$varname (static data member)
1028 */
1029
1030 static int
1031 gnu_special (work, mangled, declp)
1032 struct work_stuff *work;
1033 const char **mangled;
1034 string *declp;
1035 {
1036 int n;
1037 int success = 1;
1038 const char *p;
1039
1040 if ((*mangled)[0] == '_'
1041 && strchr (cplus_markers, (*mangled)[1]) != NULL
1042 && (*mangled)[2] == '_')
1043 {
1044 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1045 (*mangled) += 3;
1046 work -> destructor = 1;
1047 }
1048 else if ((*mangled)[0] == '_'
1049 && (*mangled)[1] == 'v'
1050 && (*mangled)[2] == 't'
1051 && strchr (cplus_markers, (*mangled)[3]) != NULL)
1052 {
1053 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1054 and create the decl. Note that we consume the entire mangled
1055 input string, which means that demangle_signature has no work
1056 to do. */
1057 (*mangled) += 4;
1058 while (**mangled != '\0')
1059 {
1060 n = strcspn (*mangled, cplus_markers);
1061 string_appendn (declp, *mangled, n);
1062 (*mangled) += n;
1063 if (**mangled != '\0')
1064 {
1065 string_append (declp, "::");
1066 (*mangled)++;
1067 }
1068 }
1069 string_append (declp, " virtual table");
1070 }
1071 else if ((*mangled)[0] == '_'
1072 && isdigit ((*mangled)[1])
1073 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1074 {
1075 /* static data member, "_3foo$varname" for example */
1076 (*mangled)++;
1077 p++;
1078 n = consume_count (mangled);
1079 string_appendn (declp, *mangled, n);
1080 string_append (declp, "::");
1081 n = strlen (p);
1082 string_appendn (declp, p, n);
1083 (*mangled) = p + n;
1084 }
1085 else
1086 {
1087 success = 0;
1088 }
1089 return (success);
1090 }
1091
1092 /*
1093
1094 LOCAL FUNCTION
1095
1096 cfront_special -- special handling of cfront/lucid mangled strings
1097
1098 SYNOPSIS
1099
1100 static int
1101 cfront_special (struct work_stuff *work, const char **mangled,
1102 string *declp);
1103
1104
1105 DESCRIPTION
1106
1107 Process some special cfront style mangling forms that don't fit
1108 the normal pattern. For example:
1109
1110 __vtbl__3foo (foo virtual table)
1111 __vtbl__3foo__3bar (bar::foo virtual table)
1112
1113 */
1114
1115 static int
1116 cfront_special (work, mangled, declp)
1117 struct work_stuff *work;
1118 const char **mangled;
1119 string *declp;
1120 {
1121 int n;
1122 int i;
1123 int success = 1;
1124 const char *p;
1125
1126 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1127 {
1128 /* Found a cfront style virtual table, get past ARM_VTABLE_STRING
1129 and create the decl. Note that we consume the entire mangled
1130 input string, which means that demangle_signature has no work
1131 to do. */
1132 (*mangled) += ARM_VTABLE_STRLEN;
1133 while (**mangled != '\0')
1134 {
1135 n = consume_count (mangled);
1136 string_prependn (declp, *mangled, n);
1137 (*mangled) += n;
1138 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1139 {
1140 string_prepend (declp, "::");
1141 (*mangled) += 2;
1142 }
1143 }
1144 string_append (declp, " virtual table");
1145 }
1146 else
1147 {
1148 success = 0;
1149 }
1150 return (success);
1151 }
1152
1153 /*
1154
1155 LOCAL FUNCTION
1156
1157 demangle_qualified -- demangle 'Q' qualified name strings
1158
1159 SYNOPSIS
1160
1161 static int
1162 demangle_qualified (struct work_stuff *, const char *mangled,
1163 string *result, int isfuncname);
1164
1165 DESCRIPTION
1166
1167 Demangle a qualified name, such as "Q25Outer5Inner" which is
1168 the mangled form of "Outer::Inner". The demangled output is
1169 appended to the result string.
1170
1171 If isfuncname is nonzero, then the qualified name we are building
1172 is going to be used as a member function name, so if it is a
1173 constructor or destructor function, append an appropriate
1174 constructor or destructor name. I.E. for the above example,
1175 the result for use as a constructor is "Outer::Inner::Inner"
1176 and the result for use as a destructor is "Outer::Inner::~Inner".
1177
1178 BUGS
1179
1180 Numeric conversion is ASCII dependent (FIXME).
1181
1182 */
1183
1184 static int
1185 demangle_qualified (work, mangled, result, isfuncname)
1186 struct work_stuff *work;
1187 const char **mangled;
1188 string *result;
1189 int isfuncname;
1190 {
1191 int qualifiers;
1192 int namelength;
1193 int success = 0;
1194
1195 qualifiers = (*mangled)[1] - '0';
1196 if (qualifiers > 0 && qualifiers < 10)
1197 {
1198 /* Assume success until we discover otherwise. Skip over the 'Q', the
1199 qualifier count, and any '_' between the qualifier count and the
1200 first name (cfront qualified names). */
1201
1202 success = 1;
1203 if ((*mangled)[2] == '_')
1204 {
1205 (*mangled)++;
1206 }
1207 (*mangled) += 2;
1208
1209
1210 /* Pick off the names and append them to the result string as they
1211 are found, separated by '::'. */
1212
1213 while (qualifiers-- > 0)
1214 {
1215 namelength = consume_count (mangled);
1216 if (strlen (*mangled) < namelength)
1217 {
1218 /* Simple sanity check failed */
1219 success = 0;
1220 break;
1221 }
1222 string_appendn (result, *mangled, namelength);
1223 if (qualifiers > 0)
1224 {
1225 string_appendn (result, "::", 2);
1226 }
1227 *mangled += namelength;
1228 }
1229
1230 /* If we are using the result as a function name, we need to append
1231 the appropriate '::' separated constructor or destructor name.
1232 We do this here because this is the most convenient place, where
1233 we already have a pointer to the name and the length of the name. */
1234
1235 if (isfuncname && (work -> constructor || work -> destructor))
1236 {
1237 string_appendn (result, "::", 2);
1238 if (work -> destructor)
1239 {
1240 string_append (result, "~");
1241 }
1242 string_appendn (result, (*mangled) - namelength, namelength);
1243 }
1244 }
1245 return (success);
1246 }
1247
1248 /*
1249
1250 LOCAL FUNCTION
1251
1252 get_count -- convert an ascii count to integer, consuming tokens
1253
1254 SYNOPSIS
1255
1256 static int
1257 get_count (const char **type, int *count)
1258
1259 DESCRIPTION
1260
1261 Return 0 if no conversion is performed, 1 if a string is converted.
1262 */
1263
1264 static int
1265 get_count (type, count)
1266 const char **type;
1267 int *count;
1268 {
1269 const char *p;
1270 int n;
1271
1272 if (!isdigit (**type))
1273 {
1274 return (0);
1275 }
1276 else
1277 {
1278 *count = **type - '0';
1279 (*type)++;
1280 if (isdigit (**type))
1281 {
1282 p = *type;
1283 n = *count;
1284 do
1285 {
1286 n *= 10;
1287 n += *p - '0';
1288 p++;
1289 }
1290 while (isdigit (*p));
1291 if (*p == '_')
1292 {
1293 *type = p + 1;
1294 *count = n;
1295 }
1296 }
1297 }
1298 return (1);
1299 }
1300
1301 /* result will be initialised here; it will be freed on failure */
1302
1303 static int
1304 do_type (work, mangled, result)
1305 struct work_stuff *work;
1306 const char **mangled;
1307 string *result;
1308 {
1309 int n;
1310 int done;
1311 int success;
1312 string decl;
1313 const char *remembered_type;
1314 int constp;
1315 int volatilep;
1316
1317 string_init (&decl);
1318 string_init (result);
1319
1320 done = 0;
1321 success = 1;
1322 while (success && !done)
1323 {
1324 int member;
1325 switch (**mangled)
1326 {
1327
1328 /* A pointer type */
1329 case 'P':
1330 (*mangled)++;
1331 string_prepend (&decl, "*");
1332 break;
1333
1334 /* A reference type */
1335 case 'R':
1336 (*mangled)++;
1337 string_prepend (&decl, "&");
1338 break;
1339
1340 /* A back reference to a previously seen type */
1341 case 'T':
1342 (*mangled)++;
1343 if (!get_count (mangled, &n) || n >= work -> ntypes)
1344 {
1345 success = 0;
1346 }
1347 else
1348 {
1349 remembered_type = work -> typevec[n];
1350 mangled = &remembered_type;
1351 }
1352 break;
1353
1354 /* A function */
1355 case 'F':
1356 (*mangled)++;
1357 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1358 {
1359 string_prepend (&decl, "(");
1360 string_append (&decl, ")");
1361 }
1362 /* After picking off the function args, we expect to either find the
1363 function return type (preceded by an '_') or the end of the
1364 string. */
1365 if (!demangle_args (work, mangled, &decl)
1366 || (**mangled != '_' && **mangled != '\0'))
1367 {
1368 success = 0;
1369 }
1370 if (success && (**mangled == '_'))
1371 {
1372 (*mangled)++;
1373 }
1374 break;
1375
1376 case 'M':
1377 case 'O':
1378 {
1379 constp = 0;
1380 volatilep = 0;
1381
1382 member = **mangled == 'M';
1383 (*mangled)++;
1384 if (!isdigit (**mangled))
1385 {
1386 success = 0;
1387 break;
1388 }
1389 n = consume_count (mangled);
1390 if (strlen (*mangled) < n)
1391 {
1392 success = 0;
1393 break;
1394 }
1395 string_append (&decl, ")");
1396 string_prepend (&decl, "::");
1397 string_prependn (&decl, *mangled, n);
1398 string_prepend (&decl, "(");
1399 *mangled += n;
1400 if (member)
1401 {
1402 if (**mangled == 'C')
1403 {
1404 (*mangled)++;
1405 constp = 1;
1406 }
1407 if (**mangled == 'V')
1408 {
1409 (*mangled)++;
1410 volatilep = 1;
1411 }
1412 if (*(*mangled)++ != 'F')
1413 {
1414 success = 0;
1415 break;
1416 }
1417 }
1418 if ((member && !demangle_args (work, mangled, &decl))
1419 || **mangled != '_')
1420 {
1421 success = 0;
1422 break;
1423 }
1424 (*mangled)++;
1425 if (! PRINT_ANSI_QUALIFIERS)
1426 {
1427 break;
1428 }
1429 if (constp)
1430 {
1431 APPEND_BLANK (&decl);
1432 string_append (&decl, "const");
1433 }
1434 if (volatilep)
1435 {
1436 APPEND_BLANK (&decl);
1437 string_append (&decl, "volatile");
1438 }
1439 break;
1440 }
1441
1442 case 'C':
1443 if ((*mangled)[1] == 'P')
1444 {
1445 (*mangled)++;
1446 if (PRINT_ANSI_QUALIFIERS)
1447 {
1448 if (!STRING_EMPTY (&decl))
1449 {
1450 string_prepend (&decl, " ");
1451 }
1452 string_prepend (&decl, "const");
1453 }
1454 break;
1455 }
1456
1457 /* fall through */
1458 default:
1459 done = 1;
1460 break;
1461 }
1462 }
1463
1464 switch (**mangled)
1465 {
1466 /* A qualified name, such as "Outer::Inner". */
1467 case 'Q':
1468 success = demangle_qualified (work, mangled, result, 0);
1469 break;
1470
1471 default:
1472 success = demangle_fund_type (work, mangled, result);
1473 break;
1474 }
1475
1476 if (success)
1477 {
1478 if (!STRING_EMPTY (&decl))
1479 {
1480 string_append (result, " ");
1481 string_appends (result, &decl);
1482 }
1483 }
1484 else
1485 {
1486 string_delete (result);
1487 }
1488 string_delete (&decl);
1489 return (success);
1490 }
1491
1492 /* Given a pointer to a type string that represents a fundamental type
1493 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1494 string in which the demangled output is being built in RESULT, and
1495 the WORK structure, decode the types and add them to the result.
1496
1497 For example:
1498
1499 "Ci" => "const int"
1500 "Sl" => "signed long"
1501 "CUs" => "const unsigned short"
1502
1503 */
1504
1505 static int
1506 demangle_fund_type (work, mangled, result)
1507 struct work_stuff *work;
1508 const char **mangled;
1509 string *result;
1510 {
1511 int done = 0;
1512 int success = 1;
1513 int n;
1514
1515 /* First pick off any type qualifiers. There can be more than one. */
1516
1517 while (!done)
1518 {
1519 switch (**mangled)
1520 {
1521 case 'C':
1522 (*mangled)++;
1523 if (PRINT_ANSI_QUALIFIERS)
1524 {
1525 APPEND_BLANK (result);
1526 string_append (result, "const");
1527 }
1528 break;
1529 case 'U':
1530 (*mangled)++;
1531 APPEND_BLANK (result);
1532 string_append (result, "unsigned");
1533 break;
1534 case 'S': /* signed char only */
1535 (*mangled)++;
1536 APPEND_BLANK (result);
1537 string_append (result, "signed");
1538 break;
1539 case 'V':
1540 (*mangled)++;
1541 if (PRINT_ANSI_QUALIFIERS)
1542 {
1543 APPEND_BLANK (result);
1544 string_append (result, "volatile");
1545 }
1546 break;
1547 default:
1548 done = 1;
1549 break;
1550 }
1551 }
1552
1553 /* Now pick off the fundamental type. There can be only one. */
1554
1555 switch (**mangled)
1556 {
1557 case '\0':
1558 case '_':
1559 break;
1560 case 'v':
1561 (*mangled)++;
1562 APPEND_BLANK (result);
1563 string_append (result, "void");
1564 break;
1565 case 'x':
1566 (*mangled)++;
1567 APPEND_BLANK (result);
1568 string_append (result, "long long");
1569 break;
1570 case 'l':
1571 (*mangled)++;
1572 APPEND_BLANK (result);
1573 string_append (result, "long");
1574 break;
1575 case 'i':
1576 (*mangled)++;
1577 APPEND_BLANK (result);
1578 string_append (result, "int");
1579 break;
1580 case 's':
1581 (*mangled)++;
1582 APPEND_BLANK (result);
1583 string_append (result, "short");
1584 break;
1585 case 'c':
1586 (*mangled)++;
1587 APPEND_BLANK (result);
1588 string_append (result, "char");
1589 break;
1590 case 'r':
1591 (*mangled)++;
1592 APPEND_BLANK (result);
1593 string_append (result, "long double");
1594 break;
1595 case 'd':
1596 (*mangled)++;
1597 APPEND_BLANK (result);
1598 string_append (result, "double");
1599 break;
1600 case 'f':
1601 (*mangled)++;
1602 APPEND_BLANK (result);
1603 string_append (result, "float");
1604 break;
1605 case 'G':
1606 (*mangled)++;
1607 if (!isdigit (**mangled))
1608 {
1609 success = 0;
1610 break;
1611 }
1612 /* fall through */
1613 /* An explicit type, such as "6mytype" or "7integer" */
1614 case '0':
1615 case '1':
1616 case '2':
1617 case '3':
1618 case '4':
1619 case '5':
1620 case '6':
1621 case '7':
1622 case '8':
1623 case '9':
1624 n = consume_count (mangled);
1625 if (strlen (*mangled) < n)
1626 {
1627 success = 0;
1628 break;
1629 }
1630 APPEND_BLANK (result);
1631 string_appendn (result, *mangled, n);
1632 *mangled += n;
1633 break;
1634 default:
1635 success = 0;
1636 break;
1637 }
1638
1639 return (success);
1640 }
1641
1642 /* `result' will be initialized in do_type; it will be freed on failure */
1643
1644 static int
1645 do_arg (work, mangled, result)
1646 struct work_stuff *work;
1647 const char **mangled;
1648 string *result;
1649 {
1650 const char *start = *mangled;
1651
1652 if (!do_type (work, mangled, result))
1653 {
1654 return (0);
1655 }
1656 else
1657 {
1658 remember_type (work, start, *mangled - start);
1659 return (1);
1660 }
1661 }
1662
1663 static void
1664 remember_type (work, start, len)
1665 struct work_stuff *work;
1666 const char *start;
1667 int len;
1668 {
1669 char *tem;
1670
1671 if (work -> ntypes >= work -> typevec_size)
1672 {
1673 if (work -> typevec_size == 0)
1674 {
1675 work -> typevec_size = 3;
1676 work -> typevec =
1677 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
1678 }
1679 else
1680 {
1681 work -> typevec_size *= 2;
1682 work -> typevec =
1683 (char **) xrealloc ((char *)work -> typevec,
1684 sizeof (char *) * work -> typevec_size);
1685 }
1686 }
1687 tem = (char *) xmalloc (len + 1);
1688 memcpy (tem, start, len);
1689 tem[len] = '\0';
1690 work -> typevec[work -> ntypes++] = tem;
1691 }
1692
1693 /* Forget the remembered types, but not the type vector itself. */
1694
1695 static void
1696 forget_types (work)
1697 struct work_stuff *work;
1698 {
1699 int i;
1700
1701 while (work -> ntypes > 0)
1702 {
1703 i = --(work -> ntypes);
1704 if (work -> typevec[i] != NULL)
1705 {
1706 free (work -> typevec[i]);
1707 work -> typevec[i] = NULL;
1708 }
1709 }
1710 }
1711
1712 /* Process the argument list part of the signature, after any class spec
1713 has been consumed, as well as the first 'F' character (if any). For
1714 example:
1715
1716 "__als__3fooRT0" => process "RT0"
1717 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1718
1719 DECLP must be already initialised, usually non-empty. It won't be freed
1720 on failure.
1721
1722 Note that g++ differs significantly from cfront and lucid style mangling
1723 with regards to references to previously seen types. For example, given
1724 the source fragment:
1725
1726 class foo {
1727 public:
1728 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
1729 };
1730
1731 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
1732 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
1733
1734 g++ produces the names:
1735
1736 __3fooiRT0iT2iT2
1737 foo__FiR3fooiT1iT1
1738
1739 while lcc (and presumably cfront as well) produces:
1740
1741 foo__FiR3fooT1T2T1T2
1742 __ct__3fooFiR3fooT1T2T1T2
1743
1744 Note that g++ bases it's type numbers starting at zero and counts all
1745 previously seen types, while lucid/cfront bases it's type numbers starting
1746 at one and only considers types after it has seen the 'F' character
1747 indicating the start of the function args. For lucid/cfront style, we
1748 account for this difference by discarding any previously seen types when
1749 we see the 'F' character, and subtracting one from the type number
1750 reference.
1751
1752 */
1753
1754 static int
1755 demangle_args (work, mangled, declp)
1756 struct work_stuff *work;
1757 const char **mangled;
1758 string *declp;
1759 {
1760 string arg;
1761 int need_comma = 0;
1762 int r;
1763 int t;
1764 const char *tem;
1765 char temptype;
1766
1767 if (PRINT_ARG_TYPES)
1768 {
1769 string_append (declp, "(");
1770 if (**mangled == '\0')
1771 {
1772 string_append (declp, "void");
1773 }
1774 }
1775
1776 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
1777 {
1778 if ((**mangled == 'N') || (**mangled == 'T'))
1779 {
1780 temptype = *(*mangled)++;
1781
1782 if (temptype == 'N')
1783 {
1784 if (!get_count (mangled, &r))
1785 {
1786 return (0);
1787 }
1788 }
1789 else
1790 {
1791 r = 1;
1792 }
1793 if (!get_count (mangled, &t))
1794 {
1795 return (0);
1796 }
1797 if (LUCID_DEMANGLING || CFRONT_DEMANGLING)
1798 {
1799 t--;
1800 }
1801 /* Validate the type index. Protect against illegal indices from
1802 malformed type strings. */
1803 if ((t < 0) || (t >= work -> ntypes))
1804 {
1805 return (0);
1806 }
1807 while (--r >= 0)
1808 {
1809 tem = work -> typevec[t];
1810 if (need_comma && PRINT_ARG_TYPES)
1811 {
1812 string_append (declp, ", ");
1813 }
1814 if (!do_arg (work, &tem, &arg))
1815 {
1816 return (0);
1817 }
1818 if (PRINT_ARG_TYPES)
1819 {
1820 string_appends (declp, &arg);
1821 }
1822 string_delete (&arg);
1823 need_comma = 1;
1824 }
1825 }
1826 else
1827 {
1828 if (need_comma & PRINT_ARG_TYPES)
1829 {
1830 string_append (declp, ", ");
1831 }
1832 if (!do_arg (work, mangled, &arg))
1833 {
1834 return (0);
1835 }
1836 if (PRINT_ARG_TYPES)
1837 {
1838 string_appends (declp, &arg);
1839 }
1840 string_delete (&arg);
1841 need_comma = 1;
1842 }
1843 }
1844
1845 if (**mangled == 'e')
1846 {
1847 (*mangled)++;
1848 if (PRINT_ARG_TYPES)
1849 {
1850 if (need_comma)
1851 {
1852 string_append (declp, ",");
1853 }
1854 string_append (declp, "...");
1855 }
1856 }
1857
1858 if (PRINT_ARG_TYPES)
1859 {
1860 string_append (declp, ")");
1861 }
1862 return (1);
1863 }
1864
1865 static void
1866 demangle_function_name (work, mangled, declp, scan)
1867 struct work_stuff *work;
1868 const char **mangled;
1869 string *declp;
1870 const char *scan;
1871 {
1872 int i;
1873 int len;
1874 string type;
1875 const char *tem;
1876
1877 string_appendn (declp, (*mangled), scan - (*mangled));
1878 string_need (declp, 1);
1879 *(declp -> p) = '\0';
1880
1881 /* Consume the function name, including the "__" separating the name
1882 from the signature. We are guaranteed that SCAN points to the
1883 separator. */
1884
1885 (*mangled) = scan + 2;
1886
1887 if (LUCID_DEMANGLING || CFRONT_DEMANGLING)
1888 {
1889
1890 /* See if we have an ARM style constructor or destructor operator.
1891 If so, then just record it, clear the decl, and return.
1892 We can't build the actual constructor/destructor decl until later,
1893 when we recover the class name from the signature. */
1894
1895 if (strcmp (declp -> b, "__ct") == 0)
1896 {
1897 work -> constructor = 1;
1898 string_clear (declp);
1899 return;
1900 }
1901 else if (strcmp (declp -> b, "__dt") == 0)
1902 {
1903 work -> destructor = 1;
1904 string_clear (declp);
1905 return;
1906 }
1907 }
1908
1909 if (declp->p - declp->b >= 3
1910 && declp->b[0] == 'o'
1911 && declp->b[1] == 'p'
1912 && strchr (cplus_markers, declp->b[2]) != NULL)
1913 {
1914 /* see if it's an assignment expression */
1915 if (declp->p - declp->b >= 10 /* op$assign_ */
1916 && memcmp (declp->b + 3, "assign_", 7) == 0)
1917 {
1918 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1919 {
1920 len = declp->p - declp->b - 10;
1921 if (strlen (optable[i].in) == len
1922 && memcmp (optable[i].in, declp->b + 10, len) == 0)
1923 {
1924 string_clear (declp);
1925 string_append (declp, "operator");
1926 string_append (declp, optable[i].out);
1927 string_append (declp, "=");
1928 break;
1929 }
1930 }
1931 }
1932 else
1933 {
1934 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1935 {
1936 int len = declp->p - declp->b - 3;
1937 if (strlen (optable[i].in) == len
1938 && memcmp (optable[i].in, declp->b + 3, len) == 0)
1939 {
1940 string_clear (declp);
1941 string_append (declp, "operator");
1942 string_append (declp, optable[i].out);
1943 break;
1944 }
1945 }
1946 }
1947 }
1948 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type$", 5) == 0)
1949 {
1950 /* type conversion operator */
1951 tem = declp->b + 5;
1952 if (do_type (work, &tem, &type))
1953 {
1954 string_clear (declp);
1955 string_append (declp, "operator ");
1956 string_appends (declp, &type);
1957 string_delete (&type);
1958 }
1959 }
1960 else if (declp->b[2] == 'o' && declp->b[3] == 'p')
1961 {
1962 /* ANSI. */
1963 /* type conversion operator. */
1964 tem = declp->b + 4;
1965 if (do_type (work, &tem, &type))
1966 {
1967 string_clear (declp);
1968 string_append (declp, "operator ");
1969 string_appends (declp, &type);
1970 string_delete (&type);
1971 }
1972 }
1973 else if (declp->b[0] == '_' && declp->b[1] == '_'
1974 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
1975 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
1976 {
1977 if (declp->b[4] == '\0')
1978 {
1979 /* Operator. */
1980 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1981 {
1982 if (strlen (optable[i].in) == 2
1983 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
1984 {
1985 string_clear (declp);
1986 string_append (declp, "operator");
1987 string_append (declp, optable[i].out);
1988 break;
1989 }
1990 }
1991 }
1992 else
1993 {
1994 if (declp->b[2] == 'a' && declp->b[5] == '\0')
1995 {
1996 /* Assignment. */
1997 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1998 {
1999 if (strlen (optable[i].in) == 3
2000 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2001 {
2002 string_clear (declp);
2003 string_append (declp, "operator");
2004 string_append (declp, optable[i].out);
2005 break;
2006 }
2007 }
2008 }
2009 }
2010 }
2011 }
2012
2013 /* a mini string-handling package */
2014
2015 static void
2016 string_need (s, n)
2017 string *s;
2018 int n;
2019 {
2020 int tem;
2021
2022 if (s->b == NULL)
2023 {
2024 if (n < 32)
2025 {
2026 n = 32;
2027 }
2028 s->p = s->b = (char *) xmalloc (n);
2029 s->e = s->b + n;
2030 }
2031 else if (s->e - s->p < n)
2032 {
2033 tem = s->p - s->b;
2034 n += tem;
2035 n *= 2;
2036 s->b = (char *) xrealloc (s->b, n);
2037 s->p = s->b + tem;
2038 s->e = s->b + n;
2039 }
2040 }
2041
2042 static void
2043 string_delete (s)
2044 string *s;
2045 {
2046 if (s->b != NULL)
2047 {
2048 free (s->b);
2049 s->b = s->e = s->p = NULL;
2050 }
2051 }
2052
2053 static void
2054 string_init (s)
2055 string *s;
2056 {
2057 s->b = s->p = s->e = NULL;
2058 }
2059
2060 static void
2061 string_clear (s)
2062 string *s;
2063 {
2064 s->p = s->b;
2065 }
2066
2067 #if 0
2068
2069 static int
2070 string_empty (s)
2071 string *s;
2072 {
2073 return (s->b == s->p);
2074 }
2075
2076 #endif
2077
2078 static void
2079 string_append (p, s)
2080 string *p;
2081 const char *s;
2082 {
2083 int n;
2084 if (s == NULL || *s == '\0')
2085 return;
2086 n = strlen (s);
2087 string_need (p, n);
2088 memcpy (p->p, s, n);
2089 p->p += n;
2090 }
2091
2092 static void
2093 string_appends (p, s)
2094 string *p, *s;
2095 {
2096 int n;
2097
2098 if (s->b != s->p)
2099 {
2100 n = s->p - s->b;
2101 string_need (p, n);
2102 memcpy (p->p, s->b, n);
2103 p->p += n;
2104 }
2105 }
2106
2107 static void
2108 string_appendn (p, s, n)
2109 string *p;
2110 const char *s;
2111 int n;
2112 {
2113 if (n != 0)
2114 {
2115 string_need (p, n);
2116 memcpy (p->p, s, n);
2117 p->p += n;
2118 }
2119 }
2120
2121 static void
2122 string_prepend (p, s)
2123 string *p;
2124 const char *s;
2125 {
2126 if (s != NULL && *s != '\0')
2127 {
2128 string_prependn (p, s, strlen (s));
2129 }
2130 }
2131
2132 #if 0
2133
2134 static void
2135 string_prepends (p, s)
2136 string *p, *s;
2137 {
2138 if (s->b != s->p)
2139 {
2140 string_prependn (p, s->b, s->p - s->b);
2141 }
2142 }
2143
2144 #endif
2145
2146 static void
2147 string_prependn (p, s, n)
2148 string *p;
2149 const char *s;
2150 int n;
2151 {
2152 char *q;
2153
2154 if (n != 0)
2155 {
2156 string_need (p, n);
2157 for (q = p->p - 1; q >= p->b; q--)
2158 {
2159 q[n] = q[0];
2160 }
2161 memcpy (p->b, s, n);
2162 p->p += n;
2163 }
2164 }
2165
2166 /* To generate a standalone demangler program for testing purposes, just
2167 compile and link this file with -DMAIN. When run, it demangles each
2168 command line arg, or each stdin string, and prints the result on stdout. */
2169
2170 #ifdef MAIN
2171
2172 static void
2173 demangle_it (mangled_name)
2174 char *mangled_name;
2175 {
2176 char *result;
2177
2178 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2179 if (result == NULL)
2180 {
2181 printf ("%s\n", mangled_name);
2182 }
2183 else
2184 {
2185 printf ("%s\n", result);
2186 free (result);
2187 }
2188 }
2189
2190 PTR
2191 xmalloc (size)
2192 long size;
2193 {
2194 PTR newmem;
2195
2196 if ((newmem = malloc ((int) size)) == NULL)
2197 {
2198 fprintf (stderr, "\nCan't allocate %u bytes\n", size);
2199 exit (1);
2200 }
2201 return (newmem);
2202 }
2203
2204 PTR
2205 xrealloc (oldmem, size)
2206 PTR oldmem;
2207 long size;
2208 {
2209 PTR newmem;
2210
2211 if ((newmem = realloc ((char *) oldmem, (int) size)) == NULL)
2212 {
2213 fprintf (stderr, "\nCan't reallocate %u bytes\n", size);
2214 exit (1);
2215 }
2216 return (newmem);
2217 }
2218
2219 #include <stdio.h>
2220
2221 enum demangling_styles current_demangling_style = gnu_demangling;
2222
2223 main (argc, argv)
2224 int argc;
2225 char **argv;
2226 {
2227 char mangled_name[128];
2228 char *result;
2229 int c;
2230 extern char *optarg;
2231 extern int optind;
2232
2233 while ((c = getopt (argc, argv, "s:?")) != EOF)
2234 {
2235 switch (c)
2236 {
2237 case '?':
2238 fprintf (stderr, "usage: demangle [-s style] [arg1 [arg2]] ...\n");
2239 fprintf (stderr, "style = { gnu, lucid, cfront }\n");
2240 fprintf (stderr, "reads args from stdin if none supplied\n");
2241 exit (0);
2242 break;
2243 case 's':
2244 if (strcmp (optarg, "gnu") == 0)
2245 {
2246 current_demangling_style = gnu_demangling;
2247 }
2248 else if (strcmp (optarg, "lucid") == 0)
2249 {
2250 current_demangling_style = lucid_demangling;
2251 }
2252 else if (strcmp (optarg, "cfront") == 0)
2253 {
2254 current_demangling_style = cfront_demangling;
2255 }
2256 else
2257 {
2258 fprintf (stderr, "unknown demangling style `%s'\n", optarg);
2259 exit (1);
2260 }
2261 break;
2262 }
2263 }
2264 if (optind < argc)
2265 {
2266 for ( ; optind < argc; optind++)
2267 {
2268 demangle_it (argv[optind]);
2269 }
2270 }
2271 else
2272 {
2273 while (gets (mangled_name))
2274 {
2275 demangle_it (mangled_name);
2276 }
2277 }
2278 }
2279
2280 #endif /* main */
This page took 0.075936 seconds and 4 git commands to generate.