gcc_release (XZ): Default to xz --best.
[official-gcc.git] / libiberty / d-demangle.c
blobec5508e277737c9c2cd275f295abdeda6c0e76f9
1 /* Demangler for the D programming language
2 Copyright (C) 2014-2017 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 /* Demangle the calling convention from MANGLED and append it to DECL.
255 Return the remaining string on success or NULL on failure. */
256 static const char *
257 dlang_call_convention (string *decl, const char *mangled)
259 if (mangled == NULL || *mangled == '\0')
260 return NULL;
262 switch (*mangled)
264 case 'F': /* (D) */
265 mangled++;
266 break;
267 case 'U': /* (C) */
268 mangled++;
269 string_append (decl, "extern(C) ");
270 break;
271 case 'W': /* (Windows) */
272 mangled++;
273 string_append (decl, "extern(Windows) ");
274 break;
275 case 'V': /* (Pascal) */
276 mangled++;
277 string_append (decl, "extern(Pascal) ");
278 break;
279 case 'R': /* (C++) */
280 mangled++;
281 string_append (decl, "extern(C++) ");
282 break;
283 case 'Y': /* (Objective-C) */
284 mangled++;
285 string_append (decl, "extern(Objective-C) ");
286 break;
287 default:
288 return NULL;
291 return mangled;
294 /* Extract the type modifiers from MANGLED and append them to DECL.
295 Returns the remaining signature on success or NULL on failure. */
296 static const char *
297 dlang_type_modifiers (string *decl, const char *mangled)
299 if (mangled == NULL || *mangled == '\0')
300 return NULL;
302 switch (*mangled)
304 case 'x': /* const */
305 mangled++;
306 string_append (decl, " const");
307 return mangled;
308 case 'y': /* immutable */
309 mangled++;
310 string_append (decl, " immutable");
311 return mangled;
312 case 'O': /* shared */
313 mangled++;
314 string_append (decl, " shared");
315 return dlang_type_modifiers (decl, mangled);
316 case 'N':
317 mangled++;
318 if (*mangled == 'g') /* wild */
320 mangled++;
321 string_append (decl, " inout");
322 return dlang_type_modifiers (decl, mangled);
324 else
325 return NULL;
327 default:
328 return mangled;
332 /* Demangle the D function attributes from MANGLED and append it to DECL.
333 Return the remaining string on success or NULL on failure. */
334 static const char *
335 dlang_attributes (string *decl, const char *mangled)
337 if (mangled == NULL || *mangled == '\0')
338 return NULL;
340 while (*mangled == 'N')
342 mangled++;
343 switch (*mangled)
345 case 'a': /* pure */
346 mangled++;
347 string_append (decl, "pure ");
348 continue;
349 case 'b': /* nothrow */
350 mangled++;
351 string_append (decl, "nothrow ");
352 continue;
353 case 'c': /* ref */
354 mangled++;
355 string_append (decl, "ref ");
356 continue;
357 case 'd': /* @property */
358 mangled++;
359 string_append (decl, "@property ");
360 continue;
361 case 'e': /* @trusted */
362 mangled++;
363 string_append (decl, "@trusted ");
364 continue;
365 case 'f': /* @safe */
366 mangled++;
367 string_append (decl, "@safe ");
368 continue;
369 case 'g':
370 case 'h':
371 case 'k':
372 /* inout parameter is represented as 'Ng'.
373 vector parameter is represented as 'Nh'.
374 return paramenter is represented as 'Nk'.
375 If we see this, then we know we're really in the
376 parameter list. Rewind and break. */
377 mangled--;
378 break;
379 case 'i': /* @nogc */
380 mangled++;
381 string_append (decl, "@nogc ");
382 continue;
383 case 'j': /* return */
384 mangled++;
385 string_append (decl, "return ");
386 continue;
387 case 'l': /* scope */
388 mangled++;
389 string_append (decl, "scope ");
390 continue;
392 default: /* unknown attribute */
393 return NULL;
395 break;
398 return mangled;
401 /* Demangle the function type from MANGLED and append it to DECL.
402 Return the remaining string on success or NULL on failure. */
403 static const char *
404 dlang_function_type (string *decl, const char *mangled)
406 string attr, args, type;
407 size_t szattr, szargs, sztype;
409 if (mangled == NULL || *mangled == '\0')
410 return NULL;
412 /* The order of the mangled string is:
413 CallConvention FuncAttrs Arguments ArgClose Type
415 The demangled string is re-ordered as:
416 CallConvention Type Arguments FuncAttrs
418 string_init (&attr);
419 string_init (&args);
420 string_init (&type);
422 /* Function call convention. */
423 mangled = dlang_call_convention (decl, mangled);
425 /* Function attributes. */
426 mangled = dlang_attributes (&attr, mangled);
427 szattr = string_length (&attr);
429 /* Function arguments. */
430 mangled = dlang_function_args (&args, mangled);
431 szargs = string_length (&args);
433 /* Function return type. */
434 mangled = dlang_type (&type, mangled);
435 sztype = string_length (&type);
437 /* Append to decl in order. */
438 string_appendn (decl, type.b, sztype);
439 string_append (decl, "(");
440 string_appendn (decl, args.b, szargs);
441 string_append (decl, ") ");
442 string_appendn (decl, attr.b, szattr);
444 string_delete (&attr);
445 string_delete (&args);
446 string_delete (&type);
447 return mangled;
450 /* Demangle the argument list from MANGLED and append it to DECL.
451 Return the remaining string on success or NULL on failure. */
452 static const char *
453 dlang_function_args (string *decl, const char *mangled)
455 size_t n = 0;
457 while (mangled && *mangled != '\0')
459 switch (*mangled)
461 case 'X': /* (variadic T t...) style. */
462 mangled++;
463 string_append (decl, "...");
464 return mangled;
465 case 'Y': /* (variadic T t, ...) style. */
466 mangled++;
467 if (n != 0)
468 string_append (decl, ", ");
469 string_append (decl, "...");
470 return mangled;
471 case 'Z': /* Normal function. */
472 mangled++;
473 return mangled;
476 if (n++)
477 string_append (decl, ", ");
479 if (*mangled == 'M') /* scope(T) */
481 mangled++;
482 string_append (decl, "scope ");
485 if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
487 mangled += 2;
488 string_append (decl, "return ");
491 switch (*mangled)
493 case 'J': /* out(T) */
494 mangled++;
495 string_append (decl, "out ");
496 break;
497 case 'K': /* ref(T) */
498 mangled++;
499 string_append (decl, "ref ");
500 break;
501 case 'L': /* lazy(T) */
502 mangled++;
503 string_append (decl, "lazy ");
504 break;
506 mangled = dlang_type (decl, mangled);
509 return mangled;
512 /* Demangle the type from MANGLED and append it to DECL.
513 Return the remaining string on success or NULL on failure. */
514 static const char *
515 dlang_type (string *decl, const char *mangled)
517 if (mangled == NULL || *mangled == '\0')
518 return NULL;
520 switch (*mangled)
522 case 'O': /* shared(T) */
523 mangled++;
524 string_append (decl, "shared(");
525 mangled = dlang_type (decl, mangled);
526 string_append (decl, ")");
527 return mangled;
528 case 'x': /* const(T) */
529 mangled++;
530 string_append (decl, "const(");
531 mangled = dlang_type (decl, mangled);
532 string_append (decl, ")");
533 return mangled;
534 case 'y': /* immutable(T) */
535 mangled++;
536 string_append (decl, "immutable(");
537 mangled = dlang_type (decl, mangled);
538 string_append (decl, ")");
539 return mangled;
540 case 'N':
541 mangled++;
542 if (*mangled == 'g') /* wild(T) */
544 mangled++;
545 string_append (decl, "inout(");
546 mangled = dlang_type (decl, mangled);
547 string_append (decl, ")");
548 return mangled;
550 else if (*mangled == 'h') /* vector(T) */
552 mangled++;
553 string_append (decl, "__vector(");
554 mangled = dlang_type (decl, mangled);
555 string_append (decl, ")");
556 return mangled;
558 else
559 return NULL;
560 case 'A': /* dynamic array (T[]) */
561 mangled++;
562 mangled = dlang_type (decl, mangled);
563 string_append (decl, "[]");
564 return mangled;
565 case 'G': /* static array (T[N]) */
567 const char *numptr;
568 size_t num = 0;
569 mangled++;
571 numptr = mangled;
572 while (ISDIGIT (*mangled))
574 num++;
575 mangled++;
577 mangled = dlang_type (decl, mangled);
578 string_append (decl, "[");
579 string_appendn (decl, numptr, num);
580 string_append (decl, "]");
581 return mangled;
583 case 'H': /* associative array (T[T]) */
585 string type;
586 size_t sztype;
587 mangled++;
589 string_init (&type);
590 mangled = dlang_type (&type, mangled);
591 sztype = string_length (&type);
593 mangled = dlang_type (decl, mangled);
594 string_append (decl, "[");
595 string_appendn (decl, type.b, sztype);
596 string_append (decl, "]");
598 string_delete (&type);
599 return mangled;
601 case 'P': /* pointer (T*) */
602 mangled++;
603 /* Function pointer types don't include the trailing asterisk. */
604 switch (*mangled)
606 case 'F': case 'U': case 'W':
607 case 'V': case 'R': case 'Y':
608 mangled = dlang_function_type (decl, mangled);
609 string_append (decl, "function");
610 return mangled;
612 mangled = dlang_type (decl, mangled);
613 string_append (decl, "*");
614 return mangled;
615 case 'I': /* ident T */
616 case 'C': /* class T */
617 case 'S': /* struct T */
618 case 'E': /* enum T */
619 case 'T': /* typedef T */
620 mangled++;
621 return dlang_parse_qualified (decl, mangled, dlang_type_name);
622 case 'D': /* delegate T */
624 string mods;
625 size_t szmods;
626 mangled++;
628 string_init (&mods);
629 mangled = dlang_type_modifiers (&mods, mangled);
630 szmods = string_length (&mods);
632 mangled = dlang_function_type (decl, mangled);
633 string_append (decl, "delegate");
634 string_appendn (decl, mods.b, szmods);
636 string_delete (&mods);
637 return mangled;
639 case 'B': /* tuple T */
640 mangled++;
641 return dlang_parse_tuple (decl, mangled);
643 /* Basic types */
644 case 'n':
645 mangled++;
646 string_append (decl, "none");
647 return mangled;
648 case 'v':
649 mangled++;
650 string_append (decl, "void");
651 return mangled;
652 case 'g':
653 mangled++;
654 string_append (decl, "byte");
655 return mangled;
656 case 'h':
657 mangled++;
658 string_append (decl, "ubyte");
659 return mangled;
660 case 's':
661 mangled++;
662 string_append (decl, "short");
663 return mangled;
664 case 't':
665 mangled++;
666 string_append (decl, "ushort");
667 return mangled;
668 case 'i':
669 mangled++;
670 string_append (decl, "int");
671 return mangled;
672 case 'k':
673 mangled++;
674 string_append (decl, "uint");
675 return mangled;
676 case 'l':
677 mangled++;
678 string_append (decl, "long");
679 return mangled;
680 case 'm':
681 mangled++;
682 string_append (decl, "ulong");
683 return mangled;
684 case 'f':
685 mangled++;
686 string_append (decl, "float");
687 return mangled;
688 case 'd':
689 mangled++;
690 string_append (decl, "double");
691 return mangled;
692 case 'e':
693 mangled++;
694 string_append (decl, "real");
695 return mangled;
697 /* Imaginary and Complex types */
698 case 'o':
699 mangled++;
700 string_append (decl, "ifloat");
701 return mangled;
702 case 'p':
703 mangled++;
704 string_append (decl, "idouble");
705 return mangled;
706 case 'j':
707 mangled++;
708 string_append (decl, "ireal");
709 return mangled;
710 case 'q':
711 mangled++;
712 string_append (decl, "cfloat");
713 return mangled;
714 case 'r':
715 mangled++;
716 string_append (decl, "cdouble");
717 return mangled;
718 case 'c':
719 mangled++;
720 string_append (decl, "creal");
721 return mangled;
723 /* Other types */
724 case 'b':
725 mangled++;
726 string_append (decl, "bool");
727 return mangled;
728 case 'a':
729 mangled++;
730 string_append (decl, "char");
731 return mangled;
732 case 'u':
733 mangled++;
734 string_append (decl, "wchar");
735 return mangled;
736 case 'w':
737 mangled++;
738 string_append (decl, "dchar");
739 return mangled;
740 case 'z':
741 mangled++;
742 switch (*mangled)
744 case 'i':
745 mangled++;
746 string_append (decl, "cent");
747 return mangled;
748 case 'k':
749 mangled++;
750 string_append (decl, "ucent");
751 return mangled;
753 return NULL;
755 default: /* unhandled */
756 return NULL;
760 /* Extract the identifier from MANGLED and append it to DECL.
761 Return the remaining string on success or NULL on failure. */
762 static const char *
763 dlang_identifier (string *decl, const char *mangled,
764 enum dlang_symbol_kinds kind)
766 long len;
767 const char *endptr = dlang_number (mangled, &len);
769 if (endptr == NULL || len == 0)
770 return NULL;
772 /* In template parameter symbols, the first character of the mangled
773 name can be a digit. This causes ambiguity issues because the
774 digits of the two numbers are adjacent. */
775 if (kind == dlang_template_param)
777 long psize = len;
778 const char *pend;
779 int saved = string_length (decl);
781 /* Work backwards until a match is found. */
782 for (pend = endptr; endptr != NULL; pend--)
784 mangled = pend;
786 /* Reached the beginning of the pointer to the name length,
787 try parsing the entire symbol. */
788 if (psize == 0)
790 psize = len;
791 pend = endptr;
792 endptr = NULL;
795 /* Check whether template parameter is a function with a valid
796 return type or an untyped identifier. */
797 if (ISDIGIT (*mangled))
798 mangled = dlang_parse_qualified (decl, mangled,
799 dlang_template_ident);
800 else if (strncmp (mangled, "_D", 2) == 0)
801 mangled = dlang_parse_mangle (decl, mangled, dlang_function);
803 /* Check for name length mismatch. */
804 if (mangled && (mangled - pend) == psize)
805 return mangled;
807 psize /= 10;
808 string_setlength (decl, saved);
811 /* No match on any combinations. */
812 return NULL;
814 else
816 if (strlen (endptr) < (size_t) len)
817 return NULL;
819 mangled = endptr;
821 /* May be a template instance. */
822 if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
823 && (mangled[2] == 'T' || mangled[2] == 'U'))
824 return dlang_parse_template (decl, mangled, len);
826 switch (len)
828 case 6:
829 if (strncmp (mangled, "__ctor", len) == 0)
831 /* Constructor symbol for a class/struct. */
832 string_append (decl, "this");
833 mangled += len;
834 return mangled;
836 else if (strncmp (mangled, "__dtor", len) == 0)
838 /* Destructor symbol for a class/struct. */
839 string_append (decl, "~this");
840 mangled += len;
841 return mangled;
843 else if (strncmp (mangled, "__initZ", len+1) == 0)
845 /* The static initialiser for a given symbol. */
846 string_append (decl, "init$");
847 mangled += len;
848 return mangled;
850 else if (strncmp (mangled, "__vtblZ", len+1) == 0)
852 /* The vtable symbol for a given class. */
853 string_prepend (decl, "vtable for ");
854 string_setlength (decl, string_length (decl) - 1);
855 mangled += len;
856 return mangled;
858 break;
860 case 7:
861 if (strncmp (mangled, "__ClassZ", len+1) == 0)
863 /* The classinfo symbol for a given class. */
864 string_prepend (decl, "ClassInfo for ");
865 string_setlength (decl, string_length (decl) - 1);
866 mangled += len;
867 return mangled;
869 break;
871 case 10:
872 if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
874 /* Postblit symbol for a struct. */
875 string_append (decl, "this(this)");
876 mangled += len + 3;
877 return mangled;
879 break;
881 case 11:
882 if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
884 /* The interface symbol for a given class. */
885 string_prepend (decl, "Interface for ");
886 string_setlength (decl, string_length (decl) - 1);
887 mangled += len;
888 return mangled;
890 break;
892 case 12:
893 if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
895 /* The ModuleInfo symbol for a given module. */
896 string_prepend (decl, "ModuleInfo for ");
897 string_setlength (decl, string_length (decl) - 1);
898 mangled += len;
899 return mangled;
901 break;
904 string_appendn (decl, mangled, len);
905 mangled += len;
908 return mangled;
911 /* Extract the integer value from MANGLED and append it to DECL,
912 where TYPE is the type it should be represented as.
913 Return the remaining string on success or NULL on failure. */
914 static const char *
915 dlang_parse_integer (string *decl, const char *mangled, char type)
917 if (type == 'a' || type == 'u' || type == 'w')
919 /* Parse character value. */
920 char value[10];
921 int pos = 10;
922 int width = 0;
923 long val;
925 mangled = dlang_number (mangled, &val);
926 if (mangled == NULL)
927 return NULL;
929 string_append (decl, "'");
931 if (type == 'a' && val >= 0x20 && val < 0x7F)
933 /* Represent as a character literal. */
934 char c = (char) val;
935 string_appendn (decl, &c, 1);
937 else
939 /* Represent as a hexadecimal value. */
940 switch (type)
942 case 'a': /* char */
943 string_append (decl, "\\x");
944 width = 2;
945 break;
946 case 'u': /* wchar */
947 string_append (decl, "\\u");
948 width = 4;
949 break;
950 case 'w': /* dchar */
951 string_append (decl, "\\U");
952 width = 8;
953 break;
956 while (val > 0)
958 int digit = val % 16;
960 if (digit < 10)
961 value[--pos] = (char)(digit + '0');
962 else
963 value[--pos] = (char)((digit - 10) + 'a');
965 val /= 16;
966 width--;
969 for (; width > 0; width--)
970 value[--pos] = '0';
972 string_appendn (decl, &(value[pos]), 10 - pos);
974 string_append (decl, "'");
976 else if (type == 'b')
978 /* Parse boolean value. */
979 long val;
981 mangled = dlang_number (mangled, &val);
982 if (mangled == NULL)
983 return NULL;
985 string_append (decl, val ? "true" : "false");
987 else
989 /* Parse integer value. */
990 const char *numptr = mangled;
991 size_t num = 0;
993 if (! ISDIGIT (*mangled))
994 return NULL;
996 while (ISDIGIT (*mangled))
998 num++;
999 mangled++;
1001 string_appendn (decl, numptr, num);
1003 /* Append suffix. */
1004 switch (type)
1006 case 'h': /* ubyte */
1007 case 't': /* ushort */
1008 case 'k': /* uint */
1009 string_append (decl, "u");
1010 break;
1011 case 'l': /* long */
1012 string_append (decl, "L");
1013 break;
1014 case 'm': /* ulong */
1015 string_append (decl, "uL");
1016 break;
1020 return mangled;
1023 /* Extract the floating-point value from MANGLED and append it to DECL.
1024 Return the remaining string on success or NULL on failure. */
1025 static const char *
1026 dlang_parse_real (string *decl, const char *mangled)
1028 char buffer[64];
1029 int len = 0;
1031 /* Handle NAN and +-INF. */
1032 if (strncmp (mangled, "NAN", 3) == 0)
1034 string_append (decl, "NaN");
1035 mangled += 3;
1036 return mangled;
1038 else if (strncmp (mangled, "INF", 3) == 0)
1040 string_append (decl, "Inf");
1041 mangled += 3;
1042 return mangled;
1044 else if (strncmp (mangled, "NINF", 4) == 0)
1046 string_append (decl, "-Inf");
1047 mangled += 4;
1048 return mangled;
1051 /* Hexadecimal prefix and leading bit. */
1052 if (*mangled == 'N')
1054 buffer[len++] = '-';
1055 mangled++;
1058 if (!ISXDIGIT (*mangled))
1059 return NULL;
1061 buffer[len++] = '0';
1062 buffer[len++] = 'x';
1063 buffer[len++] = *mangled;
1064 buffer[len++] = '.';
1065 mangled++;
1067 /* Significand. */
1068 while (ISXDIGIT (*mangled))
1070 buffer[len++] = *mangled;
1071 mangled++;
1074 /* Exponent. */
1075 if (*mangled != 'P')
1076 return NULL;
1078 buffer[len++] = 'p';
1079 mangled++;
1081 if (*mangled == 'N')
1083 buffer[len++] = '-';
1084 mangled++;
1087 while (ISDIGIT (*mangled))
1089 buffer[len++] = *mangled;
1090 mangled++;
1093 /* Write out the demangled hexadecimal, rather than trying to
1094 convert the buffer into a floating-point value. */
1095 buffer[len] = '\0';
1096 len = strlen (buffer);
1097 string_appendn (decl, buffer, len);
1098 return mangled;
1101 /* Extract the string value from MANGLED and append it to DECL.
1102 Return the remaining string on success or NULL on failure. */
1103 static const char *
1104 dlang_parse_string (string *decl, const char *mangled)
1106 char type = *mangled;
1107 long len;
1109 mangled++;
1110 mangled = dlang_number (mangled, &len);
1111 if (mangled == NULL || *mangled != '_')
1112 return NULL;
1114 mangled++;
1115 string_append (decl, "\"");
1116 while (len--)
1118 char val;
1119 const char *endptr = dlang_hexdigit (mangled, &val);
1121 if (endptr == NULL)
1122 return NULL;
1124 /* Sanitize white and non-printable characters. */
1125 switch (val)
1127 case ' ':
1128 string_append (decl, " ");
1129 break;
1130 case '\t':
1131 string_append (decl, "\\t");
1132 break;
1133 case '\n':
1134 string_append (decl, "\\n");
1135 break;
1136 case '\r':
1137 string_append (decl, "\\r");
1138 break;
1139 case '\f':
1140 string_append (decl, "\\f");
1141 break;
1142 case '\v':
1143 string_append (decl, "\\v");
1144 break;
1146 default:
1147 if (ISPRINT (val))
1148 string_appendn (decl, &val, 1);
1149 else
1151 string_append (decl, "\\x");
1152 string_appendn (decl, mangled, 2);
1156 mangled = endptr;
1158 string_append (decl, "\"");
1160 if (type != 'a')
1161 string_appendn (decl, &type, 1);
1163 return mangled;
1166 /* Extract the static array value from MANGLED and append it to DECL.
1167 Return the remaining string on success or NULL on failure. */
1168 static const char *
1169 dlang_parse_arrayliteral (string *decl, const char *mangled)
1171 long elements;
1173 mangled = dlang_number (mangled, &elements);
1174 if (mangled == NULL)
1175 return NULL;
1177 string_append (decl, "[");
1178 while (elements--)
1180 mangled = dlang_value (decl, mangled, NULL, '\0');
1181 if (elements != 0)
1182 string_append (decl, ", ");
1185 string_append (decl, "]");
1186 return mangled;
1189 /* Extract the associative array value from MANGLED and append it to DECL.
1190 Return the remaining string on success or NULL on failure. */
1191 static const char *
1192 dlang_parse_assocarray (string *decl, const char *mangled)
1194 long elements;
1196 mangled = dlang_number (mangled, &elements);
1197 if (mangled == NULL)
1198 return NULL;
1200 string_append (decl, "[");
1201 while (elements--)
1203 mangled = dlang_value (decl, mangled, NULL, '\0');
1204 string_append (decl, ":");
1205 mangled = dlang_value (decl, mangled, NULL, '\0');
1207 if (elements != 0)
1208 string_append (decl, ", ");
1211 string_append (decl, "]");
1212 return mangled;
1215 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1216 Return the remaining string on success or NULL on failure. */
1217 static const char *
1218 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1220 long args;
1222 mangled = dlang_number (mangled, &args);
1223 if (mangled == NULL)
1224 return NULL;
1226 if (name != NULL)
1227 string_append (decl, name);
1229 string_append (decl, "(");
1230 while (args--)
1232 mangled = dlang_value (decl, mangled, NULL, '\0');
1233 if (args != 0)
1234 string_append (decl, ", ");
1237 string_append (decl, ")");
1238 return mangled;
1241 /* Extract the value from MANGLED and append it to DECL.
1242 Return the remaining string on success or NULL on failure. */
1243 static const char *
1244 dlang_value (string *decl, const char *mangled, const char *name, char type)
1246 if (mangled == NULL || *mangled == '\0')
1247 return NULL;
1249 switch (*mangled)
1251 /* Null value. */
1252 case 'n':
1253 mangled++;
1254 string_append (decl, "null");
1255 break;
1257 /* Integral values. */
1258 case 'N':
1259 mangled++;
1260 string_append (decl, "-");
1261 mangled = dlang_parse_integer (decl, mangled, type);
1262 break;
1264 case 'i':
1265 mangled++;
1266 /* Fall through */
1268 /* There really should always be an `i' before encoded numbers, but there
1269 wasn't in early versions of D2, so this case range must remain for
1270 backwards compatibility. */
1271 case '0': case '1': case '2': case '3': case '4':
1272 case '5': case '6': case '7': case '8': case '9':
1273 mangled = dlang_parse_integer (decl, mangled, type);
1274 break;
1276 /* Real value. */
1277 case 'e':
1278 mangled++;
1279 mangled = dlang_parse_real (decl, mangled);
1280 break;
1282 /* Complex value. */
1283 case 'c':
1284 mangled++;
1285 mangled = dlang_parse_real (decl, mangled);
1286 string_append (decl, "+");
1287 if (mangled == NULL || *mangled != 'c')
1288 return NULL;
1289 mangled++;
1290 mangled = dlang_parse_real (decl, mangled);
1291 string_append (decl, "i");
1292 break;
1294 /* String values. */
1295 case 'a': /* UTF8 */
1296 case 'w': /* UTF16 */
1297 case 'd': /* UTF32 */
1298 mangled = dlang_parse_string (decl, mangled);
1299 break;
1301 /* Array values. */
1302 case 'A':
1303 mangled++;
1304 if (type == 'H')
1305 mangled = dlang_parse_assocarray (decl, mangled);
1306 else
1307 mangled = dlang_parse_arrayliteral (decl, mangled);
1308 break;
1310 /* Struct values. */
1311 case 'S':
1312 mangled++;
1313 mangled = dlang_parse_structlit (decl, mangled, name);
1314 break;
1316 default:
1317 return NULL;
1320 return mangled;
1323 /* Extract the function calling convention from MANGLED and
1324 return 1 on success or 0 on failure. */
1325 static int
1326 dlang_call_convention_p (const char *mangled)
1328 switch (*mangled)
1330 case 'F': case 'U': case 'V':
1331 case 'W': case 'R': case 'Y':
1332 return 1;
1334 default:
1335 return 0;
1339 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1340 Returns the remaining signature on success or NULL on failure. */
1341 static const char *
1342 dlang_parse_mangle (string *decl, const char *mangled,
1343 enum dlang_symbol_kinds kind)
1345 /* A D mangled symbol is comprised of both scope and type information.
1347 MangleName:
1348 _D QualifiedName Type
1349 _D QualifiedName M Type
1350 _D QualifiedName Z
1352 The caller should have guaranteed that the start pointer is at the
1353 above location.
1355 mangled += 2;
1357 mangled = dlang_parse_qualified (decl, mangled, dlang_top_level);
1359 if (mangled != NULL)
1361 /* Artificial symbols end with 'Z' and have no type. */
1362 if (*mangled == 'Z')
1363 mangled++;
1364 else
1366 string mods;
1367 int saved;
1369 /* Skip over 'this' parameter. */
1370 if (*mangled == 'M')
1371 mangled++;
1373 /* Save the type modifiers for appending at the end if needed. */
1374 string_init (&mods);
1375 mangled = dlang_type_modifiers (&mods, mangled);
1377 if (mangled && dlang_call_convention_p (mangled))
1379 /* Skip over calling convention and attributes. */
1380 saved = string_length (decl);
1381 mangled = dlang_call_convention (decl, mangled);
1382 mangled = dlang_attributes (decl, mangled);
1383 string_setlength (decl, saved);
1385 string_append (decl, "(");
1386 mangled = dlang_function_args (decl, mangled);
1387 string_append (decl, ")");
1389 /* Add any const/immutable/shared modifier. */
1390 string_appendn (decl, mods.b, string_length (&mods));
1393 /* Consume the decl type of symbol. */
1394 saved = string_length (decl);
1395 mangled = dlang_type (decl, mangled);
1396 string_setlength (decl, saved);
1398 string_delete (&mods);
1402 /* Check that the entire symbol was successfully demangled. */
1403 if (kind == dlang_top_level)
1405 if (mangled == NULL || *mangled != '\0')
1406 return NULL;
1409 return mangled;
1412 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1413 Returns the remaining signature on success or NULL on failure. */
1414 static const char *
1415 dlang_parse_qualified (string *decl, const char *mangled,
1416 enum dlang_symbol_kinds kind)
1418 /* Qualified names are identifiers separated by their encoded length.
1419 Nested functions also encode their argument types without specifying
1420 what they return.
1422 QualifiedName:
1423 SymbolName
1424 SymbolName QualifiedName
1425 SymbolName TypeFunctionNoReturn QualifiedName
1426 SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName
1428 The start pointer should be at the above location.
1430 size_t n = 0;
1433 if (n++)
1434 string_append (decl, ".");
1436 /* Skip over anonymous symbols. */
1437 while (*mangled == '0')
1438 mangled++;
1440 mangled = dlang_identifier (decl, mangled, kind);
1442 /* Consume the encoded arguments. However if this is not followed by the
1443 next encoded length, then this is not a continuation of a qualified
1444 name, in which case we backtrack and return the current unconsumed
1445 position of the mangled decl. */
1446 if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1448 const char *start = mangled;
1449 int saved = string_length (decl);
1451 /* Skip over 'this' parameter and type modifiers. */
1452 if (*mangled == 'M')
1454 mangled++;
1455 mangled = dlang_type_modifiers (decl, mangled);
1456 string_setlength (decl, saved);
1459 /* The rule we expect to match in the mangled string is:
1461 TypeFunctionNoReturn:
1462 CallConvention FuncAttrs Arguments ArgClose
1464 The calling convention and function attributes are not included
1465 in the demangled string. */
1466 mangled = dlang_call_convention (decl, mangled);
1467 mangled = dlang_attributes (decl, mangled);
1468 string_setlength (decl, saved);
1470 string_append (decl, "(");
1471 mangled = dlang_function_args (decl, mangled);
1472 string_append (decl, ")");
1474 if (mangled == NULL || !ISDIGIT (*mangled))
1476 /* Did not match the rule we were looking for. */
1477 mangled = start;
1478 string_setlength (decl, saved);
1482 while (mangled && ISDIGIT (*mangled));
1484 return mangled;
1487 /* Demangle the tuple from MANGLED and append it to DECL.
1488 Return the remaining string on success or NULL on failure. */
1489 static const char *
1490 dlang_parse_tuple (string *decl, const char *mangled)
1492 long elements;
1494 mangled = dlang_number (mangled, &elements);
1495 if (mangled == NULL)
1496 return NULL;
1498 string_append (decl, "Tuple!(");
1500 while (elements--)
1502 mangled = dlang_type (decl, mangled);
1503 if (elements != 0)
1504 string_append (decl, ", ");
1507 string_append (decl, ")");
1508 return mangled;
1511 /* Demangle the argument list from MANGLED and append it to DECL.
1512 Return the remaining string on success or NULL on failure. */
1513 static const char *
1514 dlang_template_args (string *decl, const char *mangled)
1516 size_t n = 0;
1518 while (mangled && *mangled != '\0')
1520 switch (*mangled)
1522 case 'Z': /* End of parameter list. */
1523 mangled++;
1524 return mangled;
1527 if (n++)
1528 string_append (decl, ", ");
1530 /* Skip over specialised template prefix. */
1531 if (*mangled == 'H')
1532 mangled++;
1534 switch (*mangled)
1536 case 'S': /* Symbol parameter. */
1537 mangled++;
1538 mangled = dlang_identifier (decl, mangled, dlang_template_param);
1539 break;
1540 case 'T': /* Type parameter. */
1541 mangled++;
1542 mangled = dlang_type (decl, mangled);
1543 break;
1544 case 'V': /* Value parameter. */
1546 string name;
1547 char type;
1549 /* Peek at the type. */
1550 mangled++;
1551 type = *mangled;
1553 /* In the few instances where the type is actually desired in
1554 the output, it should precede the value from dlang_value. */
1555 string_init (&name);
1556 mangled = dlang_type (&name, mangled);
1557 string_need (&name, 1);
1558 *(name.p) = '\0';
1560 mangled = dlang_value (decl, mangled, name.b, type);
1561 string_delete (&name);
1562 break;
1565 default:
1566 return NULL;
1570 return mangled;
1573 /* Extract and demangle the template symbol in MANGLED, expected to
1574 be made up of LEN characters, and append it to DECL.
1575 Returns the remaining signature on success or NULL on failure. */
1576 static const char *
1577 dlang_parse_template (string *decl, const char *mangled, long len)
1579 const char *start = mangled;
1581 /* Template instance names have the types and values of its parameters
1582 encoded into it.
1584 TemplateInstanceName:
1585 Number __T LName TemplateArgs Z
1586 Number __U LName TemplateArgs Z
1588 The start pointer should be at the above location, and LEN should be
1589 the value of the decoded number.
1592 /* Template symbol. */
1593 if (!ISDIGIT (mangled[3]) || mangled[3] == '0')
1594 return NULL;
1596 mangled += 3;
1598 /* Template identifier. */
1599 mangled = dlang_identifier (decl, mangled, dlang_template_ident);
1601 /* Template arguments. */
1602 string_append (decl, "!(");
1603 mangled = dlang_template_args (decl, mangled);
1604 string_append (decl, ")");
1606 /* Check for template name length mismatch. */
1607 if (mangled && (mangled - start) != len)
1608 return NULL;
1610 return mangled;
1613 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1614 signature on success or NULL on failure. */
1616 char *
1617 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1619 string decl;
1620 char *demangled = NULL;
1622 if (mangled == NULL || *mangled == '\0')
1623 return NULL;
1625 if (strncmp (mangled, "_D", 2) != 0)
1626 return NULL;
1628 string_init (&decl);
1630 if (strcmp (mangled, "_Dmain") == 0)
1632 string_append (&decl, "D main");
1634 else
1636 if (dlang_parse_mangle (&decl, mangled, dlang_top_level) == NULL)
1637 string_delete (&decl);
1640 if (string_length (&decl) > 0)
1642 string_need (&decl, 1);
1643 *(decl.p) = '\0';
1644 demangled = decl.b;
1647 return demangled;