* stack.c (print_frame_info): When checking PC_IN_CALL_DUMMY,
[deliverable/binutils-gdb.git] / gas / config / cplus-dem.c
CommitLineData
355afbcd 1/* Demangler for GNU C++
01170860 2 Copyright (C) 1989, 1992 Free Software Foundation, Inc.
68a96e53 3 written by James Clark (jjc@jclark.uucp)
355afbcd 4
68a96e53
RP
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
6026cd06 7 the Free Software Foundation; either version 2, or (at your option)
68a96e53 8 any later version.
355afbcd 9
68a96e53
RP
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
355afbcd 14
68a96e53
RP
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19/* This is for g++ 1.36.1 (November 6 version). It will probably
20 require changes for any other version. */
21
22/* This file exports one function
355afbcd 23
68a96e53 24 char *cplus_demangle (const char *name)
355afbcd 25
68a96e53
RP
26 If `name' is a mangled function name produced by g++, then
27 a pointer to a malloced string giving a C++ representation
28 of the name will be returned; otherwise NULL will be returned.
29 It is the caller's responsibility to free the string which
30 is returned.
355afbcd 31
68a96e53 32 For example,
355afbcd 33
68a96e53 34 cplus_demangle ("_foo__1Ai")
355afbcd 35
68a96e53 36 returns
355afbcd 37
68a96e53 38 "A::foo(int)"
355afbcd 39
68a96e53
RP
40 This file imports xmalloc and xrealloc, which are like malloc and
41 realloc except that they generate a fatal error if there is no
42 available memory. */
43
44/* #define nounderscore 1 /* define this is names don't start with _ */
355afbcd 45
68a96e53
RP
46#include <stdio.h>
47#include <string.h>
48#include <ctype.h>
355afbcd 49
68a96e53
RP
50#if !defined(sequent) && !defined(NeXT)
51#include <memory.h>
52#else
355afbcd 53#define memcpy(s1, s2, n) strncpy(s1, s2, n)
68a96e53 54#define memcmp(s1, s2, n) strncmp(s1, s2, n)
355afbcd 55#define strchr(s, c) index(s, c)
68a96e53
RP
56#endif
57
a87b3269 58#if __STDC__ != 1
68a96e53
RP
59#define const
60#endif
61
a87b3269 62#if __STDC__ == 1
68a96e53
RP
63extern char *cplus_demangle (const char *type);
64#else
65extern char *cplus_demangle ();
66#endif
67
a87b3269 68#if __STDC__ == 1
68a96e53
RP
69extern char *xmalloc (int);
70extern char *xrealloc (char *, int);
71#else
72extern char *xmalloc ();
73extern char *xrealloc ();
74#endif
75
76static char **typevec = 0;
77static int ntypes = 0;
78static int typevec_size = 0;
79
355afbcd
KR
80static struct
81 {
82 const char *in;
83 const char *out;
84 }
85
86optable[] =
87{
88 "new", " new",
89 "delete", " delete",
90 "ne", "!=",
91 "eq", "==",
92 "ge", ">=",
93 "gt", ">",
94 "le", "<=",
95 "lt", "<",
96 "plus", "+",
97 "minus", "-",
98 "mult", "*",
99 "negate", "-",
100 "trunc_mod", "%",
101 "trunc_div", "/",
102 "truth_andif", "&&",
103 "truth_orif", "||",
104 "postincrement", "++",
105 "postdecrement", "--",
106 "bit_ior", "|",
107 "bit_xor", "^",
108 "bit_and", "&",
109 "bit_not", "~",
110 "call", "()",
111 "cond", "?:",
112 "alshift", "<<",
113 "arshift", ">>",
114 "component", "->",
115 "nop", "", /* for operator= */
68a96e53
RP
116};
117
118/* Beware: these aren't '\0' terminated. */
119
355afbcd
KR
120typedef struct
121 {
122 char *b; /* pointer to start of string */
123 char *p; /* pointer after last character */
124 char *e; /* pointer after end of allocated space */
125 }
126
127string;
68a96e53 128
a87b3269 129#if __STDC__ == 1
355afbcd
KR
130static void string_need (string * s, int n);
131static void string_delete (string * s);
132static void string_init (string * s);
133static void string_clear (string * s);
134static int string_empty (string * s);
135static void string_append (string * p, const char *s);
136static void string_appends (string * p, string * s);
137static void string_appendn (string * p, const char *s, int n);
138static void string_prepend (string * p, const char *s);
68a96e53 139#if 0
355afbcd 140static void string_prepends (string * p, string * s);
68a96e53 141#endif
355afbcd 142static void string_prependn (string * p, const char *s, int n);
68a96e53 143static int get_count (const char **type, int *count);
355afbcd
KR
144static int do_args (const char **type, string * decl);
145static int do_type (const char **type, string * result);
146static int do_arg (const char **type, string * result);
147static int do_args (const char **type, string * decl);
148static void munge_function_name (string * name);
68a96e53
RP
149#else
150static void string_need ();
151static void string_delete ();
152static void string_init ();
153static void string_clear ();
154static int string_empty ();
155static void string_append ();
156static void string_appends ();
157static void string_appendn ();
158static void string_prepend ();
159static void string_prepends ();
160static void string_prependn ();
161static int get_count ();
162static int do_args ();
163static int do_type ();
164static int do_arg ();
165static int do_args ();
166static void munge_function_name ();
167#endif
168
169char *
355afbcd
KR
170cplus_demangle (type)
171 const char *type;
68a96e53 172{
355afbcd
KR
173 string decl;
174 int n;
175 int success = 0;
176 int constructor = 0;
177 int const_flag = 0;
178 int i;
179 const char *p;
180
181 if (type == NULL || *type == '\0')
182 return NULL;
68a96e53 183#ifndef nounderscore
355afbcd
KR
184 if (*type++ != '_')
185 return NULL;
68a96e53 186#endif
355afbcd
KR
187 p = type;
188 while (*p != '\0' && !(*p == '_' && p[1] == '_'))
189 p++;
190 if (*p == '\0')
191 {
192 /* destructor */
193 if (type[0] == '_' && type[1] == '$' && type[2] == '_')
194 {
195 int n = (strlen (type) - 3) * 2 + 3 + 2 + 1;
196 char *tem = (char *) xmalloc (n);
197 strcpy (tem, type + 3);
198 strcat (tem, "::~");
199 strcat (tem, type + 3);
200 strcat (tem, "()");
201 return tem;
202 }
203 /* static data member */
204 if (*type != '_' && (p = strchr (type, '$')) != '\0')
205 {
206 int n = strlen (type) + 2;
207 char *tem = (char *) xmalloc (n);
208 memcpy (tem, type, p - type);
209 strcpy (tem + (p - type), "::");
210 strcpy (tem + (p - type) + 2, p + 1);
211 return tem;
212 }
213 return NULL;
214 }
215
216 string_init (&decl);
217
218 if (p == type)
219 {
220 if (!isdigit (p[2]))
221 {
222 string_delete (&decl);
223 return NULL;
224 }
225 constructor = 1;
226 }
227 else
228 {
229 string_appendn (&decl, type, p - type);
230 munge_function_name (&decl);
231 }
232 p += 2;
233
234 switch (*p)
235 {
236 case 'C':
237 /* a const member function */
238 if (!isdigit (p[1]))
239 {
240 string_delete (&decl);
241 return NULL;
242 }
243 p += 1;
244 const_flag = 1;
245 /* fall through */
246 case '0':
247 case '1':
248 case '2':
249 case '3':
250 case '4':
251 case '5':
252 case '6':
253 case '7':
254 case '8':
255 case '9':
256 n = 0;
257 do
258 {
259 n *= 10;
260 n += *p - '0';
261 p += 1;
262 }
263 while (isdigit (*p));
264 if (strlen (p) < n)
265 {
266 string_delete (&decl);
267 return NULL;
268 }
269 if (constructor)
270 {
271 string_appendn (&decl, p, n);
272 string_append (&decl, "::");
273 string_appendn (&decl, p, n);
274 }
275 else
276 {
277 string_prepend (&decl, "::");
278 string_prependn (&decl, p, n);
279 }
280 p += n;
281 success = do_args (&p, &decl);
282 if (const_flag)
283 string_append (&decl, " const");
284 break;
285 case 'F':
286 p += 1;
287 success = do_args (&p, &decl);
288 break;
289 }
290
291 for (i = 0; i < ntypes; i++)
292 if (typevec[i] != NULL)
293 free (typevec[i]);
294 ntypes = 0;
295 if (typevec != NULL)
296 {
297 free ((char *) typevec);
298 typevec = NULL;
299 typevec_size = 0;
300 }
301
302 if (success)
303 {
304 string_appendn (&decl, "", 1);
305 return decl.b;
306 }
307 else
308 {
309 string_delete (&decl);
310 return NULL;
311 }
68a96e53
RP
312}
313
314static int
355afbcd
KR
315get_count (type, count)
316 const char **type;
317 int *count;
68a96e53 318{
355afbcd
KR
319 if (!isdigit (**type))
320 return 0;
321 *count = **type - '0';
322 *type += 1;
323 /* see flush_repeats in cplus-method.c */
324 if (isdigit (**type))
325 {
326 const char *p = *type;
327 int n = *count;
328 do
329 {
330 n *= 10;
331 n += *p - '0';
332 p += 1;
333 }
334 while (isdigit (*p));
335 if (*p == '_')
336 {
337 *type = p + 1;
338 *count = n;
339 }
340 }
341 return 1;
68a96e53
RP
342}
343
344/* result will be initialised here; it will be freed on failure */
345
346static int
355afbcd
KR
347do_type (type, result)
348 const char **type;
349 string *result;
68a96e53 350{
355afbcd
KR
351 int n;
352 int done;
353 int non_empty;
354 int success;
355 string decl;
356 const char *remembered_type;
357
358 string_init (&decl);
359 string_init (result);
360
361 done = 0;
362 success = 1;
363 while (success && !done)
364 {
365 int member;
366 switch (**type)
367 {
368 case 'P':
369 *type += 1;
370 string_prepend (&decl, "*");
371 break;
372
373 case 'R':
374 *type += 1;
375 string_prepend (&decl, "&");
376 break;
377
378 case 'T':
379 *type += 1;
380 if (!get_count (type, &n) || n >= ntypes)
381 success = 0;
382 else
68a96e53 383 {
355afbcd
KR
384 remembered_type = typevec[n];
385 type = &remembered_type;
68a96e53 386 }
355afbcd
KR
387 break;
388
389 case 'F':
390 *type += 1;
391 if (!string_empty (&decl) && decl.b[0] == '*')
68a96e53 392 {
355afbcd
KR
393 string_prepend (&decl, "(");
394 string_append (&decl, ")");
a39116f1 395 }
355afbcd
KR
396 if (!do_args (type, &decl) || **type != '_')
397 success = 0;
398 else
399 *type += 1;
400 break;
401
402 case 'M':
403 case 'O':
404 {
405 int constp = 0;
406 int volatilep = 0;
407
408 member = **type == 'M';
409 *type += 1;
410 if (!isdigit (**type))
411 {
412 success = 0;
413 break;
414 }
415 n = 0;
416 do
417 {
418 n *= 10;
419 n += **type - '0';
420 *type += 1;
421 }
422 while (isdigit (**type));
423 if (strlen (*type) < n)
424 {
425 success = 0;
426 break;
427 }
428 string_append (&decl, ")");
429 string_prepend (&decl, "::");
430 string_prependn (&decl, *type, n);
431 string_prepend (&decl, "(");
432 *type += n;
433 if (member)
434 {
435 if (**type == 'C')
436 {
437 *type += 1;
438 constp = 1;
439 }
440 if (**type == 'V')
441 {
442 *type += 1;
443 volatilep = 1;
444 }
445 if (*(*type)++ != 'F')
446 {
447 success = 0;
448 break;
449 }
450 }
451 if ((member && !do_args (type, &decl)) || **type != '_')
452 {
453 success = 0;
454 break;
455 }
456 *type += 1;
457 if (constp)
458 {
459 if (non_empty)
460 string_append (&decl, " ");
461 else
462 non_empty = 1;
463 string_append (&decl, "const");
464 }
465 if (volatilep)
466 {
467 if (non_empty)
468 string_append (&decl, " ");
469 else
470 non_empty = 1;
471 string_append (&decl, "volatilep");
472 }
473 break;
474 }
475
476 case 'C':
477 if ((*type)[1] == 'P')
a39116f1 478 {
355afbcd
KR
479 *type += 1;
480 if (!string_empty (&decl))
481 string_prepend (&decl, " ");
482 string_prepend (&decl, "const");
483 break;
68a96e53 484 }
355afbcd
KR
485
486 /* fall through */
487 default:
488 done = 1;
489 break;
490 }
491 }
492
493 done = 0;
494 non_empty = 0;
495 while (success && !done)
496 {
497 switch (**type)
498 {
499 case 'C':
500 *type += 1;
501 if (non_empty)
502 string_append (result, " ");
503 else
504 non_empty = 1;
505 string_append (result, "const");
506 break;
507 case 'U':
508 *type += 1;
509 if (non_empty)
510 string_append (result, " ");
511 else
512 non_empty = 1;
513 string_append (result, "unsigned");
514 break;
515 case 'V':
516 *type += 1;
517 if (non_empty)
518 string_append (result, " ");
519 else
520 non_empty = 1;
521 string_append (result, "volatile");
522 break;
523 default:
524 done = 1;
525 break;
526 }
527 }
528
529 if (success)
530 switch (**type)
531 {
532 case '\0':
533 case '_':
534 break;
535 case 'v':
536 *type += 1;
537 if (non_empty)
538 string_append (result, " ");
539 string_append (result, "void");
540 break;
541 case 'l':
542 *type += 1;
543 if (non_empty)
544 string_append (result, " ");
545 string_append (result, "long");
546 break;
547 case 'i':
548 *type += 1;
549 if (non_empty)
550 string_append (result, " ");
551 string_append (result, "int");
552 break;
553 case 's':
554 *type += 1;
555 if (non_empty)
556 string_append (result, " ");
557 string_append (result, "short");
558 break;
559 case 'c':
560 *type += 1;
561 if (non_empty)
562 string_append (result, " ");
563 string_append (result, "char");
564 break;
565 case 'r':
566 *type += 1;
567 if (non_empty)
568 string_append (result, " ");
569 string_append (result, "long double");
570 break;
571 case 'd':
572 *type += 1;
573 if (non_empty)
574 string_append (result, " ");
575 string_append (result, "double");
576 break;
577 case 'f':
578 *type += 1;
579 if (non_empty)
580 string_append (result, " ");
581 string_append (result, "float");
582 break;
583 case 'G':
584 *type += 1;
585 if (!isdigit (**type))
586 {
587 success = 0;
588 break;
589 }
590 /* fall through */
591 case '0':
592 case '1':
593 case '2':
594 case '3':
595 case '4':
596 case '5':
597 case '6':
598 case '7':
599 case '8':
600 case '9':
601 n = 0;
602 do
603 {
604 n *= 10;
605 n += **type - '0';
606 *type += 1;
607 }
608 while (isdigit (**type));
609 if (strlen (*type) < n)
610 {
611 success = 0;
612 break;
613 }
614 if (non_empty)
615 string_append (result, " ");
616 string_appendn (result, *type, n);
617 *type += n;
618 break;
619 default:
620 success = 0;
621 break;
622 }
623
624 if (success)
625 {
626 if (!string_empty (&decl))
627 {
628 string_append (result, " ");
629 string_appends (result, &decl);
630 }
631 string_delete (&decl);
632 return 1;
633 }
634 else
635 {
636 string_delete (&decl);
637 string_delete (result);
638 return 0;
639 }
68a96e53
RP
640}
641
642/* `result' will be initialised in do_type; it will be freed on failure */
643
644static int
355afbcd
KR
645do_arg (type, result)
646 const char **type;
647 string *result;
68a96e53 648{
355afbcd
KR
649 char *tem;
650 int len;
651 const char *start;
652 const char *end;
653
654 start = *type;
655 if (!do_type (type, result))
656 return 0;
657 end = *type;
658 if (ntypes >= typevec_size)
659 {
660 if (typevec_size == 0)
661 {
662 typevec_size = 3;
663 typevec = (char **) xmalloc (sizeof (char *) * typevec_size);
664 }
665 else
666 {
667 typevec_size *= 2;
668 typevec = (char **) xrealloc ((char *) typevec, sizeof (char *) * typevec_size);
669 }
670 }
671 len = end - start;
672 tem = (char *) xmalloc (len + 1);
673 memcpy (tem, start, len);
674 tem[len] = '\0';
675 typevec[ntypes++] = tem;
676 return 1;
68a96e53
RP
677}
678
679/* `decl' must be already initialised, usually non-empty;
680 it won't be freed on failure */
681
682static int
355afbcd
KR
683do_args (type, decl)
684 const char **type;
685 string *decl;
68a96e53 686{
355afbcd
KR
687 string arg;
688 int need_comma = 0;
689
690 string_append (decl, "(");
691
692 while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
693 {
694 if (**type == 'N')
695 {
696 int r;
697 int t;
698 *type += 1;
699 if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
700 return 0;
701 while (--r >= 0)
a39116f1 702 {
355afbcd
KR
703 const char *tem = typevec[t];
704 if (need_comma)
705 string_append (decl, ", ");
706 if (!do_arg (&tem, &arg))
707 return 0;
708 string_appends (decl, &arg);
709 string_delete (&arg);
710 need_comma = 1;
a39116f1 711 }
355afbcd
KR
712 }
713 else
714 {
715 if (need_comma)
716 string_append (decl, ", ");
717 if (!do_arg (type, &arg))
718 return 0;
719 string_appends (decl, &arg);
720 string_delete (&arg);
721 need_comma = 1;
722 }
723 }
724
725 if (**type == 'v')
726 *type += 1;
727 else if (**type == 'e')
728 {
729 *type += 1;
730 if (need_comma)
731 string_append (decl, ",");
732 string_append (decl, "...");
733 }
734
735 string_append (decl, ")");
736 return 1;
68a96e53
RP
737}
738
739static void
355afbcd
KR
740munge_function_name (name)
741 string *name;
68a96e53 742{
355afbcd
KR
743 if (!string_empty (name) && name->p - name->b >= 3
744 && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$')
745 {
746 int i;
747 /* see if it's an assignment expression */
748 if (name->p - name->b >= 10 /* op$assign_ */
749 && memcmp (name->b + 3, "assign_", 7) == 0)
750 {
751 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
68a96e53 752 {
355afbcd
KR
753 int len = name->p - name->b - 10;
754 if (strlen (optable[i].in) == len
755 && memcmp (optable[i].in, name->b + 10, len) == 0)
756 {
757 string_clear (name);
758 string_append (name, "operator");
759 string_append (name, optable[i].out);
760 string_append (name, "=");
761 return;
762 }
68a96e53 763 }
355afbcd
KR
764 }
765 else
766 {
767 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
68a96e53 768 {
355afbcd
KR
769 int len = name->p - name->b - 3;
770 if (strlen (optable[i].in) == len
771 && memcmp (optable[i].in, name->b + 3, len) == 0)
772 {
773 string_clear (name);
774 string_append (name, "operator");
775 string_append (name, optable[i].out);
776 return;
777 }
68a96e53 778 }
355afbcd
KR
779 }
780 return;
781 }
782 else if (!string_empty (name) && name->p - name->b >= 5
783 && memcmp (name->b, "type$", 5) == 0)
784 {
785 /* type conversion operator */
786 string type;
787 const char *tem = name->b + 5;
788 if (do_type (&tem, &type))
789 {
790 string_clear (name);
791 string_append (name, "operator ");
792 string_appends (name, &type);
793 string_delete (&type);
794 return;
795 }
796 }
68a96e53
RP
797}
798
799/* a mini string-handling package */
800
801static void
355afbcd
KR
802string_need (s, n)
803 string *s;
804 int n;
68a96e53 805{
355afbcd
KR
806 if (s->b == NULL)
807 {
808 if (n < 32)
809 n = 32;
810 s->p = s->b = (char *) xmalloc (n);
811 s->e = s->b + n;
812 }
813 else if (s->e - s->p < n)
814 {
815 int tem = s->p - s->b;
816 n += tem;
817 n *= 2;
818 s->b = (char *) xrealloc (s->b, n);
819 s->p = s->b + tem;
820 s->e = s->b + n;
821 }
68a96e53
RP
822}
823
824static void
355afbcd
KR
825string_delete (s)
826 string *s;
68a96e53 827{
355afbcd
KR
828 if (s->b != NULL)
829 {
830 free (s->b);
831 s->b = s->e = s->p = NULL;
832 }
68a96e53
RP
833}
834
835static void
355afbcd
KR
836string_init (s)
837 string *s;
68a96e53 838{
355afbcd 839 s->b = s->p = s->e = NULL;
68a96e53
RP
840}
841
355afbcd
KR
842static void
843string_clear (s)
844 string *s;
68a96e53 845{
355afbcd 846 s->p = s->b;
68a96e53
RP
847}
848
849static int
355afbcd
KR
850string_empty (s)
851 string *s;
68a96e53 852{
355afbcd 853 return s->b == s->p;
68a96e53
RP
854}
855
856static void
355afbcd
KR
857string_append (p, s)
858 string *p;
859 const char *s;
68a96e53 860{
355afbcd
KR
861 int n;
862 if (s == NULL || *s == '\0')
863 return;
864 n = strlen (s);
865 string_need (p, n);
866 memcpy (p->p, s, n);
867 p->p += n;
68a96e53
RP
868}
869
870static void
355afbcd
KR
871string_appends (p, s)
872 string *p, *s;
68a96e53 873{
355afbcd
KR
874 int n;
875 if (s->b == s->p)
876 return;
877 n = s->p - s->b;
878 string_need (p, n);
879 memcpy (p->p, s->b, n);
880 p->p += n;
68a96e53
RP
881}
882
883static void
355afbcd
KR
884string_appendn (p, s, n)
885 string *p;
886 const char *s;
887 int n;
68a96e53 888{
355afbcd
KR
889 if (n == 0)
890 return;
891 string_need (p, n);
892 memcpy (p->p, s, n);
893 p->p += n;
68a96e53
RP
894}
895
896static void
355afbcd
KR
897string_prepend (p, s)
898 string *p;
899 const char *s;
68a96e53 900{
355afbcd
KR
901 if (s == NULL || *s == '\0')
902 return;
903 string_prependn (p, s, strlen (s));
68a96e53
RP
904}
905
906#if 0
907static void
355afbcd
KR
908string_prepends (p, s)
909 string *p, *s;
68a96e53 910{
355afbcd
KR
911 if (s->b == s->p)
912 return;
913 string_prependn (p, s->b, s->p - s->b);
68a96e53 914}
355afbcd 915
68a96e53
RP
916#endif
917
918static void
355afbcd
KR
919string_prependn (p, s, n)
920 string *p;
921 const char *s;
922 int n;
68a96e53 923{
355afbcd
KR
924 char *q;
925
926 if (n == 0)
927 return;
928 string_need (p, n);
929 for (q = p->p - 1; q >= p->b; q--)
930 q[n] = q[0];
931 memcpy (p->b, s, n);
932 p->p += n;
68a96e53 933}
a39116f1
RP
934
935/* end of cplus-dem.c */
This page took 0.111144 seconds and 4 git commands to generate.