2018-06-01 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libiberty / d-demangle.c
blobfe29618f60f79fb3580f8519cdc49c2168aba575
1 /* Demangler for the D programming language
2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
3 Written by Iain Buclaw (ibuclaw@gdcproject.org)
5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 In addition to the permissions in the GNU Library General Public
12 License, the Free Software Foundation gives you unlimited permission
13 to link the compiled version of this file into combinations with other
14 programs, and to distribute those combinations without any restriction
15 coming from the use of this file. (The Library Public License
16 restrictions do apply in other respects; for example, they cover
17 modification of the file, and distribution when not linked into a
18 combined executable.)
20 Libiberty is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Library General Public License for more details.
25 You should have received a copy of the GNU Library General Public
26 License along with libiberty; see the file COPYING.LIB.
27 If not, see <http://www.gnu.org/licenses/>. */
29 /* This file exports one function; dlang_demangle. */
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
35 #include "safe-ctype.h"
37 #include <sys/types.h>
38 #include <string.h>
39 #include <stdio.h>
41 #ifdef HAVE_STDLIB_H
42 #include <stdlib.h>
43 #endif
45 #include <demangle.h>
46 #include "libiberty.h"
48 /* A mini string-handling package */
50 typedef struct string /* Beware: these aren't required to be */
51 { /* '\0' terminated. */
52 char *b; /* pointer to start of string */
53 char *p; /* pointer after last character */
54 char *e; /* pointer after end of allocated space */
55 } string;
57 static void
58 string_need (string *s, int n)
60 int tem;
62 if (s->b == NULL)
64 if (n < 32)
66 n = 32;
68 s->p = s->b = XNEWVEC (char, n);
69 s->e = s->b + n;
71 else if (s->e - s->p < n)
73 tem = s->p - s->b;
74 n += tem;
75 n *= 2;
76 s->b = XRESIZEVEC (char, s->b, n);
77 s->p = s->b + tem;
78 s->e = s->b + n;
82 static void
83 string_delete (string *s)
85 if (s->b != NULL)
87 XDELETEVEC (s->b);
88 s->b = s->e = s->p = NULL;
92 static void
93 string_init (string *s)
95 s->b = s->p = s->e = NULL;
98 static int
99 string_length (string *s)
101 if (s->p == s->b)
103 return 0;
105 return s->p - s->b;
108 static void
109 string_setlength (string *s, int n)
111 if (n - string_length (s) < 0)
113 s->p = s->b + n;
117 static void
118 string_append (string *p, const char *s)
120 int n = strlen (s);
121 string_need (p, n);
122 memcpy (p->p, s, n);
123 p->p += n;
126 static void
127 string_appendn (string *p, const char *s, int n)
129 if (n != 0)
131 string_need (p, n);
132 memcpy (p->p, s, n);
133 p->p += n;
137 static void
138 string_prependn (string *p, const char *s, int n)
140 char *q;
142 if (n != 0)
144 string_need (p, n);
145 for (q = p->p - 1; q >= p->b; q--)
147 q[n] = q[0];
149 memcpy (p->b, s, n);
150 p->p += n;
154 static void
155 string_prepend (string *p, const char *s)
157 if (s != NULL && *s != '\0')
159 string_prependn (p, s, strlen (s));
163 /* What kinds of symbol we could be parsing. */
164 enum dlang_symbol_kinds
166 /* Top-level symbol, needs it's type checked. */
167 dlang_top_level,
168 /* Function symbol, needs it's type checked. */
169 dlang_function,
170 /* Strongly typed name, such as for classes, structs and enums. */
171 dlang_type_name,
172 /* Template identifier. */
173 dlang_template_ident,
174 /* Template symbol parameter. */
175 dlang_template_param
178 /* Prototypes for forward referenced functions */
179 static const char *dlang_function_args (string *, const char *);
181 static const char *dlang_type (string *, const char *);
183 static const char *dlang_value (string *, const char *, const char *, char);
185 static const char *dlang_parse_qualified (string *, const char *,
186 enum dlang_symbol_kinds);
188 static const char *dlang_parse_mangle (string *, const char *,
189 enum dlang_symbol_kinds);
191 static const char *dlang_parse_tuple (string *, const char *);
193 static const char *dlang_parse_template (string *, const char *, long);
196 /* Extract the number from MANGLED, and assign the result to RET.
197 Return the remaining string on success or NULL on failure. */
198 static const char *
199 dlang_number (const char *mangled, long *ret)
201 /* Return NULL if trying to extract something that isn't a digit. */
202 if (mangled == NULL || !ISDIGIT (*mangled))
203 return NULL;
205 (*ret) = 0;
207 while (ISDIGIT (*mangled))
209 (*ret) *= 10;
211 /* If an overflow occured when multiplying by ten, the result
212 will not be a multiple of ten. */
213 if ((*ret % 10) != 0)
214 return NULL;
216 (*ret) += mangled[0] - '0';
217 mangled++;
220 if (*mangled == '\0' || *ret < 0)
221 return NULL;
223 return mangled;
226 /* Extract the hex-digit from MANGLED, and assign the result to RET.
227 Return the remaining string on success or NULL on failure. */
228 static const char *
229 dlang_hexdigit (const char *mangled, char *ret)
231 char c;
233 /* Return NULL if trying to extract something that isn't a hexdigit. */
234 if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1]))
235 return NULL;
237 c = mangled[0];
238 if (!ISDIGIT (c))
239 (*ret) = (c - (ISUPPER (c) ? 'A' : 'a') + 10);
240 else
241 (*ret) = (c - '0');
243 c = mangled[1];
244 if (!ISDIGIT (c))
245 (*ret) = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
246 else
247 (*ret) = (*ret << 4) | (c - '0');
249 mangled += 2;
251 return mangled;
254 /* Extract the function calling convention from MANGLED and
255 return 1 on success or 0 on failure. */
256 static int
257 dlang_call_convention_p (const char *mangled)
259 switch (*mangled)
261 case 'F': case 'U': case 'V':
262 case 'W': case 'R': case 'Y':
263 return 1;
265 default:
266 return 0;
270 /* Demangle the calling convention from MANGLED and append it to DECL.
271 Return the remaining string on success or NULL on failure. */
272 static const char *
273 dlang_call_convention (string *decl, const char *mangled)
275 if (mangled == NULL || *mangled == '\0')
276 return NULL;
278 switch (*mangled)
280 case 'F': /* (D) */
281 mangled++;
282 break;
283 case 'U': /* (C) */
284 mangled++;
285 string_append (decl, "extern(C) ");
286 break;
287 case 'W': /* (Windows) */
288 mangled++;
289 string_append (decl, "extern(Windows) ");
290 break;
291 case 'V': /* (Pascal) */
292 mangled++;
293 string_append (decl, "extern(Pascal) ");
294 break;
295 case 'R': /* (C++) */
296 mangled++;
297 string_append (decl, "extern(C++) ");
298 break;
299 case 'Y': /* (Objective-C) */
300 mangled++;
301 string_append (decl, "extern(Objective-C) ");
302 break;
303 default:
304 return NULL;
307 return mangled;
310 /* Extract the type modifiers from MANGLED and append them to DECL.
311 Returns the remaining signature on success or NULL on failure. */
312 static const char *
313 dlang_type_modifiers (string *decl, const char *mangled)
315 if (mangled == NULL || *mangled == '\0')
316 return NULL;
318 switch (*mangled)
320 case 'x': /* const */
321 mangled++;
322 string_append (decl, " const");
323 return mangled;
324 case 'y': /* immutable */
325 mangled++;
326 string_append (decl, " immutable");
327 return mangled;
328 case 'O': /* shared */
329 mangled++;
330 string_append (decl, " shared");
331 return dlang_type_modifiers (decl, mangled);
332 case 'N':
333 mangled++;
334 if (*mangled == 'g') /* wild */
336 mangled++;
337 string_append (decl, " inout");
338 return dlang_type_modifiers (decl, mangled);
340 else
341 return NULL;
343 default:
344 return mangled;
348 /* Demangle the D function attributes from MANGLED and append it to DECL.
349 Return the remaining string on success or NULL on failure. */
350 static const char *
351 dlang_attributes (string *decl, const char *mangled)
353 if (mangled == NULL || *mangled == '\0')
354 return NULL;
356 while (*mangled == 'N')
358 mangled++;
359 switch (*mangled)
361 case 'a': /* pure */
362 mangled++;
363 string_append (decl, "pure ");
364 continue;
365 case 'b': /* nothrow */
366 mangled++;
367 string_append (decl, "nothrow ");
368 continue;
369 case 'c': /* ref */
370 mangled++;
371 string_append (decl, "ref ");
372 continue;
373 case 'd': /* @property */
374 mangled++;
375 string_append (decl, "@property ");
376 continue;
377 case 'e': /* @trusted */
378 mangled++;
379 string_append (decl, "@trusted ");
380 continue;
381 case 'f': /* @safe */
382 mangled++;
383 string_append (decl, "@safe ");
384 continue;
385 case 'g':
386 case 'h':
387 case 'k':
388 /* inout parameter is represented as 'Ng'.
389 vector parameter is represented as 'Nh'.
390 return paramenter is represented as 'Nk'.
391 If we see this, then we know we're really in the
392 parameter list. Rewind and break. */
393 mangled--;
394 break;
395 case 'i': /* @nogc */
396 mangled++;
397 string_append (decl, "@nogc ");
398 continue;
399 case 'j': /* return */
400 mangled++;
401 string_append (decl, "return ");
402 continue;
403 case 'l': /* scope */
404 mangled++;
405 string_append (decl, "scope ");
406 continue;
408 default: /* unknown attribute */
409 return NULL;
411 break;
414 return mangled;
417 /* Demangle the function type from MANGLED and append it to DECL.
418 Return the remaining string on success or NULL on failure. */
419 static const char *
420 dlang_function_type (string *decl, const char *mangled)
422 string attr, args, type;
423 size_t szattr, szargs, sztype;
425 if (mangled == NULL || *mangled == '\0')
426 return NULL;
428 /* The order of the mangled string is:
429 CallConvention FuncAttrs Arguments ArgClose Type
431 The demangled string is re-ordered as:
432 CallConvention Type Arguments FuncAttrs
434 string_init (&attr);
435 string_init (&args);
436 string_init (&type);
438 /* Function call convention. */
439 mangled = dlang_call_convention (decl, mangled);
441 /* Function attributes. */
442 mangled = dlang_attributes (&attr, mangled);
443 szattr = string_length (&attr);
445 /* Function arguments. */
446 mangled = dlang_function_args (&args, mangled);
447 szargs = string_length (&args);
449 /* Function return type. */
450 mangled = dlang_type (&type, mangled);
451 sztype = string_length (&type);
453 /* Append to decl in order. */
454 string_appendn (decl, type.b, sztype);
455 string_append (decl, "(");
456 string_appendn (decl, args.b, szargs);
457 string_append (decl, ") ");
458 string_appendn (decl, attr.b, szattr);
460 string_delete (&attr);
461 string_delete (&args);
462 string_delete (&type);
463 return mangled;
466 /* Demangle the argument list from MANGLED and append it to DECL.
467 Return the remaining string on success or NULL on failure. */
468 static const char *
469 dlang_function_args (string *decl, const char *mangled)
471 size_t n = 0;
473 while (mangled && *mangled != '\0')
475 switch (*mangled)
477 case 'X': /* (variadic T t...) style. */
478 mangled++;
479 string_append (decl, "...");
480 return mangled;
481 case 'Y': /* (variadic T t, ...) style. */
482 mangled++;
483 if (n != 0)
484 string_append (decl, ", ");
485 string_append (decl, "...");
486 return mangled;
487 case 'Z': /* Normal function. */
488 mangled++;
489 return mangled;
492 if (n++)
493 string_append (decl, ", ");
495 if (*mangled == 'M') /* scope(T) */
497 mangled++;
498 string_append (decl, "scope ");
501 if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
503 mangled += 2;
504 string_append (decl, "return ");
507 switch (*mangled)
509 case 'J': /* out(T) */
510 mangled++;
511 string_append (decl, "out ");
512 break;
513 case 'K': /* ref(T) */
514 mangled++;
515 string_append (decl, "ref ");
516 break;
517 case 'L': /* lazy(T) */
518 mangled++;
519 string_append (decl, "lazy ");
520 break;
522 mangled = dlang_type (decl, mangled);
525 return mangled;
528 /* Demangle the type from MANGLED and append it to DECL.
529 Return the remaining string on success or NULL on failure. */
530 static const char *
531 dlang_type (string *decl, const char *mangled)
533 if (mangled == NULL || *mangled == '\0')
534 return NULL;
536 switch (*mangled)
538 case 'O': /* shared(T) */
539 mangled++;
540 string_append (decl, "shared(");
541 mangled = dlang_type (decl, mangled);
542 string_append (decl, ")");
543 return mangled;
544 case 'x': /* const(T) */
545 mangled++;
546 string_append (decl, "const(");
547 mangled = dlang_type (decl, mangled);
548 string_append (decl, ")");
549 return mangled;
550 case 'y': /* immutable(T) */
551 mangled++;
552 string_append (decl, "immutable(");
553 mangled = dlang_type (decl, mangled);
554 string_append (decl, ")");
555 return mangled;
556 case 'N':
557 mangled++;
558 if (*mangled == 'g') /* wild(T) */
560 mangled++;
561 string_append (decl, "inout(");
562 mangled = dlang_type (decl, mangled);
563 string_append (decl, ")");
564 return mangled;
566 else if (*mangled == 'h') /* vector(T) */
568 mangled++;
569 string_append (decl, "__vector(");
570 mangled = dlang_type (decl, mangled);
571 string_append (decl, ")");
572 return mangled;
574 else
575 return NULL;
576 case 'A': /* dynamic array (T[]) */
577 mangled++;
578 mangled = dlang_type (decl, mangled);
579 string_append (decl, "[]");
580 return mangled;
581 case 'G': /* static array (T[N]) */
583 const char *numptr;
584 size_t num = 0;
585 mangled++;
587 numptr = mangled;
588 while (ISDIGIT (*mangled))
590 num++;
591 mangled++;
593 mangled = dlang_type (decl, mangled);
594 string_append (decl, "[");
595 string_appendn (decl, numptr, num);
596 string_append (decl, "]");
597 return mangled;
599 case 'H': /* associative array (T[T]) */
601 string type;
602 size_t sztype;
603 mangled++;
605 string_init (&type);
606 mangled = dlang_type (&type, mangled);
607 sztype = string_length (&type);
609 mangled = dlang_type (decl, mangled);
610 string_append (decl, "[");
611 string_appendn (decl, type.b, sztype);
612 string_append (decl, "]");
614 string_delete (&type);
615 return mangled;
617 case 'P': /* pointer (T*) */
618 mangled++;
619 if (!dlang_call_convention_p (mangled))
621 mangled = dlang_type (decl, mangled);
622 string_append (decl, "*");
623 return mangled;
625 /* Fall through */
626 case 'F': /* function T (D) */
627 case 'U': /* function T (C) */
628 case 'W': /* function T (Windows) */
629 case 'V': /* function T (Pascal) */
630 case 'R': /* function T (C++) */
631 case 'Y': /* function T (Objective-C) */
632 /* Function pointer types don't include the trailing asterisk. */
633 mangled = dlang_function_type (decl, mangled);
634 string_append (decl, "function");
635 return mangled;
636 case 'I': /* ident T */
637 case 'C': /* class T */
638 case 'S': /* struct T */
639 case 'E': /* enum T */
640 case 'T': /* typedef T */
641 mangled++;
642 return dlang_parse_qualified (decl, mangled, dlang_type_name);
643 case 'D': /* delegate T */
645 string mods;
646 size_t szmods;
647 mangled++;
649 string_init (&mods);
650 mangled = dlang_type_modifiers (&mods, mangled);
651 szmods = string_length (&mods);
653 mangled = dlang_function_type (decl, mangled);
654 string_append (decl, "delegate");
655 string_appendn (decl, mods.b, szmods);
657 string_delete (&mods);
658 return mangled;
660 case 'B': /* tuple T */
661 mangled++;
662 return dlang_parse_tuple (decl, mangled);
664 /* Basic types */
665 case 'n':
666 mangled++;
667 string_append (decl, "none");
668 return mangled;
669 case 'v':
670 mangled++;
671 string_append (decl, "void");
672 return mangled;
673 case 'g':
674 mangled++;
675 string_append (decl, "byte");
676 return mangled;
677 case 'h':
678 mangled++;
679 string_append (decl, "ubyte");
680 return mangled;
681 case 's':
682 mangled++;
683 string_append (decl, "short");
684 return mangled;
685 case 't':
686 mangled++;
687 string_append (decl, "ushort");
688 return mangled;
689 case 'i':
690 mangled++;
691 string_append (decl, "int");
692 return mangled;
693 case 'k':
694 mangled++;
695 string_append (decl, "uint");
696 return mangled;
697 case 'l':
698 mangled++;
699 string_append (decl, "long");
700 return mangled;
701 case 'm':
702 mangled++;
703 string_append (decl, "ulong");
704 return mangled;
705 case 'f':
706 mangled++;
707 string_append (decl, "float");
708 return mangled;
709 case 'd':
710 mangled++;
711 string_append (decl, "double");
712 return mangled;
713 case 'e':
714 mangled++;
715 string_append (decl, "real");
716 return mangled;
718 /* Imaginary and Complex types */
719 case 'o':
720 mangled++;
721 string_append (decl, "ifloat");
722 return mangled;
723 case 'p':
724 mangled++;
725 string_append (decl, "idouble");
726 return mangled;
727 case 'j':
728 mangled++;
729 string_append (decl, "ireal");
730 return mangled;
731 case 'q':
732 mangled++;
733 string_append (decl, "cfloat");
734 return mangled;
735 case 'r':
736 mangled++;
737 string_append (decl, "cdouble");
738 return mangled;
739 case 'c':
740 mangled++;
741 string_append (decl, "creal");
742 return mangled;
744 /* Other types */
745 case 'b':
746 mangled++;
747 string_append (decl, "bool");
748 return mangled;
749 case 'a':
750 mangled++;
751 string_append (decl, "char");
752 return mangled;
753 case 'u':
754 mangled++;
755 string_append (decl, "wchar");
756 return mangled;
757 case 'w':
758 mangled++;
759 string_append (decl, "dchar");
760 return mangled;
761 case 'z':
762 mangled++;
763 switch (*mangled)
765 case 'i':
766 mangled++;
767 string_append (decl, "cent");
768 return mangled;
769 case 'k':
770 mangled++;
771 string_append (decl, "ucent");
772 return mangled;
774 return NULL;
776 default: /* unhandled */
777 return NULL;
781 /* Extract the identifier from MANGLED and append it to DECL.
782 Return the remaining string on success or NULL on failure. */
783 static const char *
784 dlang_identifier (string *decl, const char *mangled,
785 enum dlang_symbol_kinds kind)
787 long len;
788 const char *endptr = dlang_number (mangled, &len);
790 if (endptr == NULL || len == 0)
791 return NULL;
793 /* In template parameter symbols, the first character of the mangled
794 name can be a digit. This causes ambiguity issues because the
795 digits of the two numbers are adjacent. */
796 if (kind == dlang_template_param)
798 long psize = len;
799 const char *pend;
800 int saved = string_length (decl);
802 /* Work backwards until a match is found. */
803 for (pend = endptr; endptr != NULL; pend--)
805 mangled = pend;
807 /* Reached the beginning of the pointer to the name length,
808 try parsing the entire symbol. */
809 if (psize == 0)
811 psize = len;
812 pend = endptr;
813 endptr = NULL;
816 /* Check whether template parameter is a function with a valid
817 return type or an untyped identifier. */
818 if (ISDIGIT (*mangled))
819 mangled = dlang_parse_qualified (decl, mangled,
820 dlang_template_ident);
821 else if (strncmp (mangled, "_D", 2) == 0)
822 mangled = dlang_parse_mangle (decl, mangled, dlang_function);
824 /* Check for name length mismatch. */
825 if (mangled && (mangled - pend) == psize)
826 return mangled;
828 psize /= 10;
829 string_setlength (decl, saved);
832 /* No match on any combinations. */
833 return NULL;
835 else
837 if (strlen (endptr) < (size_t) len)
838 return NULL;
840 mangled = endptr;
842 /* May be a template instance. */
843 if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
844 && (mangled[2] == 'T' || mangled[2] == 'U'))
845 return dlang_parse_template (decl, mangled, len);
847 switch (len)
849 case 6:
850 if (strncmp (mangled, "__ctor", len) == 0)
852 /* Constructor symbol for a class/struct. */
853 string_append (decl, "this");
854 mangled += len;
855 return mangled;
857 else if (strncmp (mangled, "__dtor", len) == 0)
859 /* Destructor symbol for a class/struct. */
860 string_append (decl, "~this");
861 mangled += len;
862 return mangled;
864 else if (strncmp (mangled, "__initZ", len+1) == 0)
866 /* The static initialiser for a given symbol. */
867 string_prepend (decl, "initializer for ");
868 string_setlength (decl, string_length (decl) - 1);
869 mangled += len;
870 return mangled;
872 else if (strncmp (mangled, "__vtblZ", len+1) == 0)
874 /* The vtable symbol for a given class. */
875 string_prepend (decl, "vtable for ");
876 string_setlength (decl, string_length (decl) - 1);
877 mangled += len;
878 return mangled;
880 break;
882 case 7:
883 if (strncmp (mangled, "__ClassZ", len+1) == 0)
885 /* The classinfo symbol for a given class. */
886 string_prepend (decl, "ClassInfo for ");
887 string_setlength (decl, string_length (decl) - 1);
888 mangled += len;
889 return mangled;
891 break;
893 case 10:
894 if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
896 /* Postblit symbol for a struct. */
897 string_append (decl, "this(this)");
898 mangled += len + 3;
899 return mangled;
901 break;
903 case 11:
904 if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
906 /* The interface symbol for a given class. */
907 string_prepend (decl, "Interface for ");
908 string_setlength (decl, string_length (decl) - 1);
909 mangled += len;
910 return mangled;
912 break;
914 case 12:
915 if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
917 /* The ModuleInfo symbol for a given module. */
918 string_prepend (decl, "ModuleInfo for ");
919 string_setlength (decl, string_length (decl) - 1);
920 mangled += len;
921 return mangled;
923 break;
926 string_appendn (decl, mangled, len);
927 mangled += len;
930 return mangled;
933 /* Extract the integer value from MANGLED and append it to DECL,
934 where TYPE is the type it should be represented as.
935 Return the remaining string on success or NULL on failure. */
936 static const char *
937 dlang_parse_integer (string *decl, const char *mangled, char type)
939 if (type == 'a' || type == 'u' || type == 'w')
941 /* Parse character value. */
942 char value[10];
943 int pos = 10;
944 int width = 0;
945 long val;
947 mangled = dlang_number (mangled, &val);
948 if (mangled == NULL)
949 return NULL;
951 string_append (decl, "'");
953 if (type == 'a' && val >= 0x20 && val < 0x7F)
955 /* Represent as a character literal. */
956 char c = (char) val;
957 string_appendn (decl, &c, 1);
959 else
961 /* Represent as a hexadecimal value. */
962 switch (type)
964 case 'a': /* char */
965 string_append (decl, "\\x");
966 width = 2;
967 break;
968 case 'u': /* wchar */
969 string_append (decl, "\\u");
970 width = 4;
971 break;
972 case 'w': /* dchar */
973 string_append (decl, "\\U");
974 width = 8;
975 break;
978 while (val > 0)
980 int digit = val % 16;
982 if (digit < 10)
983 value[--pos] = (char)(digit + '0');
984 else
985 value[--pos] = (char)((digit - 10) + 'a');
987 val /= 16;
988 width--;
991 for (; width > 0; width--)
992 value[--pos] = '0';
994 string_appendn (decl, &(value[pos]), 10 - pos);
996 string_append (decl, "'");
998 else if (type == 'b')
1000 /* Parse boolean value. */
1001 long val;
1003 mangled = dlang_number (mangled, &val);
1004 if (mangled == NULL)
1005 return NULL;
1007 string_append (decl, val ? "true" : "false");
1009 else
1011 /* Parse integer value. */
1012 const char *numptr = mangled;
1013 size_t num = 0;
1015 if (! ISDIGIT (*mangled))
1016 return NULL;
1018 while (ISDIGIT (*mangled))
1020 num++;
1021 mangled++;
1023 string_appendn (decl, numptr, num);
1025 /* Append suffix. */
1026 switch (type)
1028 case 'h': /* ubyte */
1029 case 't': /* ushort */
1030 case 'k': /* uint */
1031 string_append (decl, "u");
1032 break;
1033 case 'l': /* long */
1034 string_append (decl, "L");
1035 break;
1036 case 'm': /* ulong */
1037 string_append (decl, "uL");
1038 break;
1042 return mangled;
1045 /* Extract the floating-point value from MANGLED and append it to DECL.
1046 Return the remaining string on success or NULL on failure. */
1047 static const char *
1048 dlang_parse_real (string *decl, const char *mangled)
1050 /* Handle NAN and +-INF. */
1051 if (strncmp (mangled, "NAN", 3) == 0)
1053 string_append (decl, "NaN");
1054 mangled += 3;
1055 return mangled;
1057 else if (strncmp (mangled, "INF", 3) == 0)
1059 string_append (decl, "Inf");
1060 mangled += 3;
1061 return mangled;
1063 else if (strncmp (mangled, "NINF", 4) == 0)
1065 string_append (decl, "-Inf");
1066 mangled += 4;
1067 return mangled;
1070 /* Hexadecimal prefix and leading bit. */
1071 if (*mangled == 'N')
1073 string_append (decl, "-");
1074 mangled++;
1077 if (!ISXDIGIT (*mangled))
1078 return NULL;
1080 string_append (decl, "0x");
1081 string_appendn (decl, mangled, 1);
1082 string_append (decl, ".");
1083 mangled++;
1085 /* Significand. */
1086 while (ISXDIGIT (*mangled))
1088 string_appendn (decl, mangled, 1);
1089 mangled++;
1092 /* Exponent. */
1093 if (*mangled != 'P')
1094 return NULL;
1096 string_append (decl, "p");
1097 mangled++;
1099 if (*mangled == 'N')
1101 string_append (decl, "-");
1102 mangled++;
1105 while (ISDIGIT (*mangled))
1107 string_appendn (decl, mangled, 1);
1108 mangled++;
1111 return mangled;
1114 /* Extract the string value from MANGLED and append it to DECL.
1115 Return the remaining string on success or NULL on failure. */
1116 static const char *
1117 dlang_parse_string (string *decl, const char *mangled)
1119 char type = *mangled;
1120 long len;
1122 mangled++;
1123 mangled = dlang_number (mangled, &len);
1124 if (mangled == NULL || *mangled != '_')
1125 return NULL;
1127 mangled++;
1128 string_append (decl, "\"");
1129 while (len--)
1131 char val;
1132 const char *endptr = dlang_hexdigit (mangled, &val);
1134 if (endptr == NULL)
1135 return NULL;
1137 /* Sanitize white and non-printable characters. */
1138 switch (val)
1140 case ' ':
1141 string_append (decl, " ");
1142 break;
1143 case '\t':
1144 string_append (decl, "\\t");
1145 break;
1146 case '\n':
1147 string_append (decl, "\\n");
1148 break;
1149 case '\r':
1150 string_append (decl, "\\r");
1151 break;
1152 case '\f':
1153 string_append (decl, "\\f");
1154 break;
1155 case '\v':
1156 string_append (decl, "\\v");
1157 break;
1159 default:
1160 if (ISPRINT (val))
1161 string_appendn (decl, &val, 1);
1162 else
1164 string_append (decl, "\\x");
1165 string_appendn (decl, mangled, 2);
1169 mangled = endptr;
1171 string_append (decl, "\"");
1173 if (type != 'a')
1174 string_appendn (decl, &type, 1);
1176 return mangled;
1179 /* Extract the static array value from MANGLED and append it to DECL.
1180 Return the remaining string on success or NULL on failure. */
1181 static const char *
1182 dlang_parse_arrayliteral (string *decl, const char *mangled)
1184 long elements;
1186 mangled = dlang_number (mangled, &elements);
1187 if (mangled == NULL)
1188 return NULL;
1190 string_append (decl, "[");
1191 while (elements--)
1193 mangled = dlang_value (decl, mangled, NULL, '\0');
1194 if (elements != 0)
1195 string_append (decl, ", ");
1198 string_append (decl, "]");
1199 return mangled;
1202 /* Extract the associative array value from MANGLED and append it to DECL.
1203 Return the remaining string on success or NULL on failure. */
1204 static const char *
1205 dlang_parse_assocarray (string *decl, const char *mangled)
1207 long elements;
1209 mangled = dlang_number (mangled, &elements);
1210 if (mangled == NULL)
1211 return NULL;
1213 string_append (decl, "[");
1214 while (elements--)
1216 mangled = dlang_value (decl, mangled, NULL, '\0');
1217 string_append (decl, ":");
1218 mangled = dlang_value (decl, mangled, NULL, '\0');
1220 if (elements != 0)
1221 string_append (decl, ", ");
1224 string_append (decl, "]");
1225 return mangled;
1228 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1229 Return the remaining string on success or NULL on failure. */
1230 static const char *
1231 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1233 long args;
1235 mangled = dlang_number (mangled, &args);
1236 if (mangled == NULL)
1237 return NULL;
1239 if (name != NULL)
1240 string_append (decl, name);
1242 string_append (decl, "(");
1243 while (args--)
1245 mangled = dlang_value (decl, mangled, NULL, '\0');
1246 if (args != 0)
1247 string_append (decl, ", ");
1250 string_append (decl, ")");
1251 return mangled;
1254 /* Extract the value from MANGLED and append it to DECL.
1255 Return the remaining string on success or NULL on failure. */
1256 static const char *
1257 dlang_value (string *decl, const char *mangled, const char *name, char type)
1259 if (mangled == NULL || *mangled == '\0')
1260 return NULL;
1262 switch (*mangled)
1264 /* Null value. */
1265 case 'n':
1266 mangled++;
1267 string_append (decl, "null");
1268 break;
1270 /* Integral values. */
1271 case 'N':
1272 mangled++;
1273 string_append (decl, "-");
1274 mangled = dlang_parse_integer (decl, mangled, type);
1275 break;
1277 case 'i':
1278 mangled++;
1279 /* Fall through */
1281 /* There really should always be an `i' before encoded numbers, but there
1282 wasn't in early versions of D2, so this case range must remain for
1283 backwards compatibility. */
1284 case '0': case '1': case '2': case '3': case '4':
1285 case '5': case '6': case '7': case '8': case '9':
1286 mangled = dlang_parse_integer (decl, mangled, type);
1287 break;
1289 /* Real value. */
1290 case 'e':
1291 mangled++;
1292 mangled = dlang_parse_real (decl, mangled);
1293 break;
1295 /* Complex value. */
1296 case 'c':
1297 mangled++;
1298 mangled = dlang_parse_real (decl, mangled);
1299 string_append (decl, "+");
1300 if (mangled == NULL || *mangled != 'c')
1301 return NULL;
1302 mangled++;
1303 mangled = dlang_parse_real (decl, mangled);
1304 string_append (decl, "i");
1305 break;
1307 /* String values. */
1308 case 'a': /* UTF8 */
1309 case 'w': /* UTF16 */
1310 case 'd': /* UTF32 */
1311 mangled = dlang_parse_string (decl, mangled);
1312 break;
1314 /* Array values. */
1315 case 'A':
1316 mangled++;
1317 if (type == 'H')
1318 mangled = dlang_parse_assocarray (decl, mangled);
1319 else
1320 mangled = dlang_parse_arrayliteral (decl, mangled);
1321 break;
1323 /* Struct values. */
1324 case 'S':
1325 mangled++;
1326 mangled = dlang_parse_structlit (decl, mangled, name);
1327 break;
1329 default:
1330 return NULL;
1333 return mangled;
1336 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1337 Returns the remaining signature on success or NULL on failure. */
1338 static const char *
1339 dlang_parse_mangle (string *decl, const char *mangled,
1340 enum dlang_symbol_kinds kind)
1342 /* A D mangled symbol is comprised of both scope and type information.
1344 MangleName:
1345 _D QualifiedName Type
1346 _D QualifiedName M Type
1347 _D QualifiedName Z
1349 The caller should have guaranteed that the start pointer is at the
1350 above location.
1352 mangled += 2;
1354 mangled = dlang_parse_qualified (decl, mangled, dlang_top_level);
1356 if (mangled != NULL)
1358 /* Artificial symbols end with 'Z' and have no type. */
1359 if (*mangled == 'Z')
1360 mangled++;
1361 else
1363 string mods;
1364 int saved;
1366 /* Skip over 'this' parameter. */
1367 if (*mangled == 'M')
1368 mangled++;
1370 /* Save the type modifiers for appending at the end if needed. */
1371 string_init (&mods);
1372 mangled = dlang_type_modifiers (&mods, mangled);
1374 if (mangled && dlang_call_convention_p (mangled))
1376 /* Skip over calling convention and attributes. */
1377 saved = string_length (decl);
1378 mangled = dlang_call_convention (decl, mangled);
1379 mangled = dlang_attributes (decl, mangled);
1380 string_setlength (decl, saved);
1382 string_append (decl, "(");
1383 mangled = dlang_function_args (decl, mangled);
1384 string_append (decl, ")");
1386 /* Add any const/immutable/shared modifier. */
1387 string_appendn (decl, mods.b, string_length (&mods));
1390 /* Consume the decl type of symbol. */
1391 saved = string_length (decl);
1392 mangled = dlang_type (decl, mangled);
1393 string_setlength (decl, saved);
1395 string_delete (&mods);
1399 /* Check that the entire symbol was successfully demangled. */
1400 if (kind == dlang_top_level)
1402 if (mangled == NULL || *mangled != '\0')
1403 return NULL;
1406 return mangled;
1409 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1410 Returns the remaining signature on success or NULL on failure. */
1411 static const char *
1412 dlang_parse_qualified (string *decl, const char *mangled,
1413 enum dlang_symbol_kinds kind)
1415 /* Qualified names are identifiers separated by their encoded length.
1416 Nested functions also encode their argument types without specifying
1417 what they return.
1419 QualifiedName:
1420 SymbolName
1421 SymbolName QualifiedName
1422 SymbolName TypeFunctionNoReturn QualifiedName
1423 SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName
1425 The start pointer should be at the above location.
1427 size_t n = 0;
1430 if (n++)
1431 string_append (decl, ".");
1433 /* Skip over anonymous symbols. */
1434 while (*mangled == '0')
1435 mangled++;
1437 mangled = dlang_identifier (decl, mangled, kind);
1439 /* Consume the encoded arguments. However if this is not followed by the
1440 next encoded length, then this is not a continuation of a qualified
1441 name, in which case we backtrack and return the current unconsumed
1442 position of the mangled decl. */
1443 if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1445 const char *start = mangled;
1446 int saved = string_length (decl);
1448 /* Skip over 'this' parameter and type modifiers. */
1449 if (*mangled == 'M')
1451 mangled++;
1452 mangled = dlang_type_modifiers (decl, mangled);
1453 string_setlength (decl, saved);
1456 /* The rule we expect to match in the mangled string is:
1458 TypeFunctionNoReturn:
1459 CallConvention FuncAttrs Arguments ArgClose
1461 The calling convention and function attributes are not included
1462 in the demangled string. */
1463 mangled = dlang_call_convention (decl, mangled);
1464 mangled = dlang_attributes (decl, mangled);
1465 string_setlength (decl, saved);
1467 string_append (decl, "(");
1468 mangled = dlang_function_args (decl, mangled);
1469 string_append (decl, ")");
1471 if (mangled == NULL || !ISDIGIT (*mangled))
1473 /* Did not match the rule we were looking for. */
1474 mangled = start;
1475 string_setlength (decl, saved);
1479 while (mangled && ISDIGIT (*mangled));
1481 return mangled;
1484 /* Demangle the tuple from MANGLED and append it to DECL.
1485 Return the remaining string on success or NULL on failure. */
1486 static const char *
1487 dlang_parse_tuple (string *decl, const char *mangled)
1489 long elements;
1491 mangled = dlang_number (mangled, &elements);
1492 if (mangled == NULL)
1493 return NULL;
1495 string_append (decl, "Tuple!(");
1497 while (elements--)
1499 mangled = dlang_type (decl, mangled);
1500 if (elements != 0)
1501 string_append (decl, ", ");
1504 string_append (decl, ")");
1505 return mangled;
1508 /* Demangle the argument list from MANGLED and append it to DECL.
1509 Return the remaining string on success or NULL on failure. */
1510 static const char *
1511 dlang_template_args (string *decl, const char *mangled)
1513 size_t n = 0;
1515 while (mangled && *mangled != '\0')
1517 switch (*mangled)
1519 case 'Z': /* End of parameter list. */
1520 mangled++;
1521 return mangled;
1524 if (n++)
1525 string_append (decl, ", ");
1527 /* Skip over specialised template prefix. */
1528 if (*mangled == 'H')
1529 mangled++;
1531 switch (*mangled)
1533 case 'S': /* Symbol parameter. */
1534 mangled++;
1535 mangled = dlang_identifier (decl, mangled, dlang_template_param);
1536 break;
1537 case 'T': /* Type parameter. */
1538 mangled++;
1539 mangled = dlang_type (decl, mangled);
1540 break;
1541 case 'V': /* Value parameter. */
1543 string name;
1544 char type;
1546 /* Peek at the type. */
1547 mangled++;
1548 type = *mangled;
1550 /* In the few instances where the type is actually desired in
1551 the output, it should precede the value from dlang_value. */
1552 string_init (&name);
1553 mangled = dlang_type (&name, mangled);
1554 string_need (&name, 1);
1555 *(name.p) = '\0';
1557 mangled = dlang_value (decl, mangled, name.b, type);
1558 string_delete (&name);
1559 break;
1562 default:
1563 return NULL;
1567 return mangled;
1570 /* Extract and demangle the template symbol in MANGLED, expected to
1571 be made up of LEN characters, and append it to DECL.
1572 Returns the remaining signature on success or NULL on failure. */
1573 static const char *
1574 dlang_parse_template (string *decl, const char *mangled, long len)
1576 const char *start = mangled;
1578 /* Template instance names have the types and values of its parameters
1579 encoded into it.
1581 TemplateInstanceName:
1582 Number __T LName TemplateArgs Z
1583 Number __U LName TemplateArgs Z
1585 The start pointer should be at the above location, and LEN should be
1586 the value of the decoded number.
1589 /* Template symbol. */
1590 if (!ISDIGIT (mangled[3]) || mangled[3] == '0')
1591 return NULL;
1593 mangled += 3;
1595 /* Template identifier. */
1596 mangled = dlang_identifier (decl, mangled, dlang_template_ident);
1598 /* Template arguments. */
1599 string_append (decl, "!(");
1600 mangled = dlang_template_args (decl, mangled);
1601 string_append (decl, ")");
1603 /* Check for template name length mismatch. */
1604 if (mangled && (mangled - start) != len)
1605 return NULL;
1607 return mangled;
1610 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1611 signature on success or NULL on failure. */
1613 char *
1614 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1616 string decl;
1617 char *demangled = NULL;
1619 if (mangled == NULL || *mangled == '\0')
1620 return NULL;
1622 if (strncmp (mangled, "_D", 2) != 0)
1623 return NULL;
1625 string_init (&decl);
1627 if (strcmp (mangled, "_Dmain") == 0)
1629 string_append (&decl, "D main");
1631 else
1633 if (dlang_parse_mangle (&decl, mangled, dlang_top_level) == NULL)
1634 string_delete (&decl);
1637 if (string_length (&decl) > 0)
1639 string_need (&decl, 1);
1640 *(decl.p) = '\0';
1641 demangled = decl.b;
1644 return demangled;