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