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