libiberty/ChangeLog:
[official-gcc.git] / libiberty / d-demangle.c
blob533653fde2f4e6679bb8258dd518a896a83a9f44
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 This file imports strtol for decoding mangled literals. */
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #include "safe-ctype.h"
39 #include <sys/types.h>
40 #include <string.h>
41 #include <stdio.h>
43 #ifdef HAVE_STDLIB_H
44 #include <stdlib.h>
45 #else
46 extern long strtol (const char *nptr, char **endptr, int base);
47 #endif
49 #include <demangle.h>
50 #include "libiberty.h"
52 /* A mini string-handling package */
54 typedef struct string /* Beware: these aren't required to be */
55 { /* '\0' terminated. */
56 char *b; /* pointer to start of string */
57 char *p; /* pointer after last character */
58 char *e; /* pointer after end of allocated space */
59 } string;
61 static void
62 string_need (string *s, int n)
64 int tem;
66 if (s->b == NULL)
68 if (n < 32)
70 n = 32;
72 s->p = s->b = XNEWVEC (char, n);
73 s->e = s->b + n;
75 else if (s->e - s->p < n)
77 tem = s->p - s->b;
78 n += tem;
79 n *= 2;
80 s->b = XRESIZEVEC (char, s->b, n);
81 s->p = s->b + tem;
82 s->e = s->b + n;
86 static void
87 string_delete (string *s)
89 if (s->b != NULL)
91 XDELETEVEC (s->b);
92 s->b = s->e = s->p = NULL;
96 static void
97 string_init (string *s)
99 s->b = s->p = s->e = NULL;
102 static int
103 string_length (string *s)
105 if (s->p == s->b)
107 return 0;
109 return s->p - s->b;
112 static void
113 string_setlength (string *s, int n)
115 if (n - string_length (s) < 0)
117 s->p = s->b + n;
121 static void
122 string_append (string *p, const char *s)
124 int n = strlen (s);
125 string_need (p, n);
126 memcpy (p->p, s, n);
127 p->p += n;
130 static void
131 string_appendn (string *p, const char *s, int n)
133 if (n != 0)
135 string_need (p, n);
136 memcpy (p->p, s, n);
137 p->p += n;
141 static void
142 string_prependn (string *p, const char *s, int n)
144 char *q;
146 if (n != 0)
148 string_need (p, n);
149 for (q = p->p - 1; q >= p->b; q--)
151 q[n] = q[0];
153 memcpy (p->b, s, n);
154 p->p += n;
158 static void
159 string_prepend (string *p, const char *s)
161 if (s != NULL && *s != '\0')
163 string_prependn (p, s, strlen (s));
167 /* What kinds of symbol we could be parsing. */
168 enum dlang_symbol_kinds
170 /* Top-level symbol, needs it's type checked. */
171 dlang_top_level,
172 /* Function symbol, needs it's type checked. */
173 dlang_function,
174 /* Strongly typed name, such as for classes, structs and enums. */
175 dlang_type_name,
176 /* Template identifier. */
177 dlang_template_ident,
178 /* Template symbol parameter. */
179 dlang_template_param
182 /* Prototypes for forward referenced functions */
183 static const char *dlang_function_args (string *, const char *);
185 static const char *dlang_type (string *, const char *);
187 static const char *dlang_value (string *, const char *, const char *, char);
189 static const char *dlang_parse_symbol (string *, const char *,
190 enum dlang_symbol_kinds);
192 static const char *dlang_parse_tuple (string *, const char *);
194 static const char *dlang_parse_template (string *, const char *, long);
197 /* Demangle the calling convention from MANGLED and append it to DECL.
198 Return the remaining string on success or NULL on failure. */
199 static const char *
200 dlang_call_convention (string *decl, const char *mangled)
202 if (mangled == NULL || *mangled == '\0')
203 return NULL;
205 switch (*mangled)
207 case 'F': /* (D) */
208 mangled++;
209 break;
210 case 'U': /* (C) */
211 mangled++;
212 string_append (decl, "extern(C) ");
213 break;
214 case 'W': /* (Windows) */
215 mangled++;
216 string_append (decl, "extern(Windows) ");
217 break;
218 case 'V': /* (Pascal) */
219 mangled++;
220 string_append (decl, "extern(Pascal) ");
221 break;
222 case 'R': /* (C++) */
223 mangled++;
224 string_append (decl, "extern(C++) ");
225 break;
226 case 'Y': /* (Objective-C) */
227 mangled++;
228 string_append (decl, "extern(Objective-C) ");
229 break;
230 default:
231 return NULL;
234 return mangled;
237 /* Extract the type modifiers from MANGLED and append them to DECL.
238 Returns the remaining signature on success or NULL on failure. */
239 static const char *
240 dlang_type_modifiers (string *decl, const char *mangled)
242 if (mangled == NULL || *mangled == '\0')
243 return NULL;
245 switch (*mangled)
247 case 'x': /* const */
248 mangled++;
249 string_append (decl, " const");
250 return mangled;
251 case 'y': /* immutable */
252 mangled++;
253 string_append (decl, " immutable");
254 return mangled;
255 case 'O': /* shared */
256 mangled++;
257 string_append (decl, " shared");
258 return dlang_type_modifiers (decl, mangled);
259 case 'N':
260 mangled++;
261 if (*mangled == 'g') /* wild */
263 mangled++;
264 string_append (decl, " inout");
265 return dlang_type_modifiers (decl, mangled);
267 else
268 return NULL;
270 default:
271 return mangled;
275 /* Demangle the D function attributes from MANGLED and append it to DECL.
276 Return the remaining string on success or NULL on failure. */
277 static const char *
278 dlang_attributes (string *decl, const char *mangled)
280 if (mangled == NULL || *mangled == '\0')
281 return NULL;
283 while (*mangled == 'N')
285 mangled++;
286 switch (*mangled)
288 case 'a': /* pure */
289 mangled++;
290 string_append (decl, "pure ");
291 continue;
292 case 'b': /* nothrow */
293 mangled++;
294 string_append (decl, "nothrow ");
295 continue;
296 case 'c': /* ref */
297 mangled++;
298 string_append (decl, "ref ");
299 continue;
300 case 'd': /* @property */
301 mangled++;
302 string_append (decl, "@property ");
303 continue;
304 case 'e': /* @trusted */
305 mangled++;
306 string_append (decl, "@trusted ");
307 continue;
308 case 'f': /* @safe */
309 mangled++;
310 string_append (decl, "@safe ");
311 continue;
312 case 'g':
313 case 'h':
314 case 'k':
315 /* inout parameter is represented as 'Ng'.
316 vector parameter is represented as 'Nh'.
317 return paramenter is represented as 'Nk'.
318 If we see this, then we know we're really in the
319 parameter list. Rewind and break. */
320 mangled--;
321 break;
322 case 'i': /* @nogc */
323 mangled++;
324 string_append (decl, "@nogc ");
325 continue;
326 case 'j': /* return */
327 mangled++;
328 string_append (decl, "return ");
329 continue;
330 case 'l': /* scope */
331 mangled++;
332 string_append (decl, "scope ");
333 continue;
335 default: /* unknown attribute */
336 return NULL;
338 break;
341 return mangled;
344 /* Demangle the function type from MANGLED and append it to DECL.
345 Return the remaining string on success or NULL on failure. */
346 static const char *
347 dlang_function_type (string *decl, const char *mangled)
349 string attr, args, type;
350 size_t szattr, szargs, sztype;
352 if (mangled == NULL || *mangled == '\0')
353 return NULL;
355 /* The order of the mangled string is:
356 CallConvention FuncAttrs Arguments ArgClose Type
358 The demangled string is re-ordered as:
359 CallConvention Type Arguments FuncAttrs
361 string_init (&attr);
362 string_init (&args);
363 string_init (&type);
365 /* Function call convention. */
366 mangled = dlang_call_convention (decl, mangled);
368 /* Function attributes. */
369 mangled = dlang_attributes (&attr, mangled);
370 szattr = string_length (&attr);
372 /* Function arguments. */
373 mangled = dlang_function_args (&args, mangled);
374 szargs = string_length (&args);
376 /* Function return type. */
377 mangled = dlang_type (&type, mangled);
378 sztype = string_length (&type);
380 /* Append to decl in order. */
381 string_appendn (decl, type.b, sztype);
382 string_append (decl, "(");
383 string_appendn (decl, args.b, szargs);
384 string_append (decl, ") ");
385 string_appendn (decl, attr.b, szattr);
387 string_delete (&attr);
388 string_delete (&args);
389 string_delete (&type);
390 return mangled;
393 /* Demangle the argument list from MANGLED and append it to DECL.
394 Return the remaining string on success or NULL on failure. */
395 static const char *
396 dlang_function_args (string *decl, const char *mangled)
398 size_t n = 0;
400 while (mangled && *mangled != '\0')
402 switch (*mangled)
404 case 'X': /* (variadic T t...) style. */
405 mangled++;
406 string_append (decl, "...");
407 return mangled;
408 case 'Y': /* (variadic T t, ...) style. */
409 mangled++;
410 if (n != 0)
411 string_append (decl, ", ");
412 string_append (decl, "...");
413 return mangled;
414 case 'Z': /* Normal function. */
415 mangled++;
416 return mangled;
419 if (n++)
420 string_append (decl, ", ");
422 if (*mangled == 'M') /* scope(T) */
424 mangled++;
425 string_append (decl, "scope ");
428 if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
430 mangled += 2;
431 string_append (decl, "return ");
434 switch (*mangled)
436 case 'J': /* out(T) */
437 mangled++;
438 string_append (decl, "out ");
439 break;
440 case 'K': /* ref(T) */
441 mangled++;
442 string_append (decl, "ref ");
443 break;
444 case 'L': /* lazy(T) */
445 mangled++;
446 string_append (decl, "lazy ");
447 break;
449 mangled = dlang_type (decl, mangled);
452 return mangled;
455 /* Demangle the type from MANGLED and append it to DECL.
456 Return the remaining string on success or NULL on failure. */
457 static const char *
458 dlang_type (string *decl, const char *mangled)
460 if (mangled == NULL || *mangled == '\0')
461 return NULL;
463 switch (*mangled)
465 case 'O': /* shared(T) */
466 mangled++;
467 string_append (decl, "shared(");
468 mangled = dlang_type (decl, mangled);
469 string_append (decl, ")");
470 return mangled;
471 case 'x': /* const(T) */
472 mangled++;
473 string_append (decl, "const(");
474 mangled = dlang_type (decl, mangled);
475 string_append (decl, ")");
476 return mangled;
477 case 'y': /* immutable(T) */
478 mangled++;
479 string_append (decl, "immutable(");
480 mangled = dlang_type (decl, mangled);
481 string_append (decl, ")");
482 return mangled;
483 case 'N':
484 mangled++;
485 if (*mangled == 'g') /* wild(T) */
487 mangled++;
488 string_append (decl, "inout(");
489 mangled = dlang_type (decl, mangled);
490 string_append (decl, ")");
491 return mangled;
493 else if (*mangled == 'h') /* vector(T) */
495 mangled++;
496 string_append (decl, "__vector(");
497 mangled = dlang_type (decl, mangled);
498 string_append (decl, ")");
499 return mangled;
501 else
502 return NULL;
503 case 'A': /* dynamic array (T[]) */
504 mangled++;
505 mangled = dlang_type (decl, mangled);
506 string_append (decl, "[]");
507 return mangled;
508 case 'G': /* static array (T[N]) */
510 const char *numptr;
511 size_t num = 0;
512 mangled++;
514 numptr = mangled;
515 while (ISDIGIT (*mangled))
517 num++;
518 mangled++;
520 mangled = dlang_type (decl, mangled);
521 string_append (decl, "[");
522 string_appendn (decl, numptr, num);
523 string_append (decl, "]");
524 return mangled;
526 case 'H': /* associative array (T[T]) */
528 string type;
529 size_t sztype;
530 mangled++;
532 string_init (&type);
533 mangled = dlang_type (&type, mangled);
534 sztype = string_length (&type);
536 mangled = dlang_type (decl, mangled);
537 string_append (decl, "[");
538 string_appendn (decl, type.b, sztype);
539 string_append (decl, "]");
541 string_delete (&type);
542 return mangled;
544 case 'P': /* pointer (T*) */
545 mangled++;
546 /* Function pointer types don't include the trailing asterisk. */
547 switch (*mangled)
549 case 'F': case 'U': case 'W':
550 case 'V': case 'R': case 'Y':
551 mangled = dlang_function_type (decl, mangled);
552 string_append (decl, "function");
553 return mangled;
555 mangled = dlang_type (decl, mangled);
556 string_append (decl, "*");
557 return mangled;
558 case 'I': /* ident T */
559 case 'C': /* class T */
560 case 'S': /* struct T */
561 case 'E': /* enum T */
562 case 'T': /* typedef T */
563 mangled++;
564 return dlang_parse_symbol (decl, mangled, dlang_type_name);
565 case 'D': /* delegate T */
567 string mods;
568 size_t szmods;
569 mangled++;
571 string_init (&mods);
572 mangled = dlang_type_modifiers (&mods, mangled);
573 szmods = string_length (&mods);
575 mangled = dlang_function_type (decl, mangled);
576 string_append (decl, "delegate");
577 string_appendn (decl, mods.b, szmods);
579 string_delete (&mods);
580 return mangled;
582 case 'B': /* tuple T */
583 mangled++;
584 return dlang_parse_tuple (decl, mangled);
586 /* Basic types */
587 case 'n':
588 mangled++;
589 string_append (decl, "none");
590 return mangled;
591 case 'v':
592 mangled++;
593 string_append (decl, "void");
594 return mangled;
595 case 'g':
596 mangled++;
597 string_append (decl, "byte");
598 return mangled;
599 case 'h':
600 mangled++;
601 string_append (decl, "ubyte");
602 return mangled;
603 case 's':
604 mangled++;
605 string_append (decl, "short");
606 return mangled;
607 case 't':
608 mangled++;
609 string_append (decl, "ushort");
610 return mangled;
611 case 'i':
612 mangled++;
613 string_append (decl, "int");
614 return mangled;
615 case 'k':
616 mangled++;
617 string_append (decl, "uint");
618 return mangled;
619 case 'l':
620 mangled++;
621 string_append (decl, "long");
622 return mangled;
623 case 'm':
624 mangled++;
625 string_append (decl, "ulong");
626 return mangled;
627 case 'f':
628 mangled++;
629 string_append (decl, "float");
630 return mangled;
631 case 'd':
632 mangled++;
633 string_append (decl, "double");
634 return mangled;
635 case 'e':
636 mangled++;
637 string_append (decl, "real");
638 return mangled;
640 /* Imaginary and Complex types */
641 case 'o':
642 mangled++;
643 string_append (decl, "ifloat");
644 return mangled;
645 case 'p':
646 mangled++;
647 string_append (decl, "idouble");
648 return mangled;
649 case 'j':
650 mangled++;
651 string_append (decl, "ireal");
652 return mangled;
653 case 'q':
654 mangled++;
655 string_append (decl, "cfloat");
656 return mangled;
657 case 'r':
658 mangled++;
659 string_append (decl, "cdouble");
660 return mangled;
661 case 'c':
662 mangled++;
663 string_append (decl, "creal");
664 return mangled;
666 /* Other types */
667 case 'b':
668 mangled++;
669 string_append (decl, "bool");
670 return mangled;
671 case 'a':
672 mangled++;
673 string_append (decl, "char");
674 return mangled;
675 case 'u':
676 mangled++;
677 string_append (decl, "wchar");
678 return mangled;
679 case 'w':
680 mangled++;
681 string_append (decl, "dchar");
682 return mangled;
683 case 'z':
684 mangled++;
685 switch (*mangled)
687 case 'i':
688 mangled++;
689 string_append (decl, "cent");
690 return mangled;
691 case 'k':
692 mangled++;
693 string_append (decl, "ucent");
694 return mangled;
696 return NULL;
698 default: /* unhandled */
699 return NULL;
703 /* Extract the identifier from MANGLED and append it to DECL.
704 Return the remaining string on success or NULL on failure. */
705 static const char *
706 dlang_identifier (string *decl, const char *mangled,
707 enum dlang_symbol_kinds kind)
709 char *endptr;
710 long len;
712 if (mangled == NULL || *mangled == '\0')
713 return NULL;
715 len = strtol (mangled, &endptr, 10);
717 if (endptr == NULL || len <= 0)
718 return NULL;
720 /* In template parameter symbols, the first character of the mangled
721 name can be a digit. This causes ambiguity issues because the
722 digits of the two numbers are adjacent. */
723 if (kind == dlang_template_param)
725 long psize = len;
726 char *pend;
727 int saved = string_length (decl);
729 /* Work backwards until a match is found. */
730 for (pend = endptr; endptr != NULL; pend--)
732 mangled = pend;
734 /* Reached the beginning of the pointer to the name length,
735 try parsing the entire symbol. */
736 if (psize == 0)
738 psize = len;
739 pend = endptr;
740 endptr = NULL;
743 /* Check whether template parameter is a function with a valid
744 return type or an untyped identifier. */
745 if (ISDIGIT (*mangled))
746 mangled = dlang_parse_symbol (decl, mangled, dlang_template_ident);
747 else if (strncmp (mangled, "_D", 2) == 0)
749 mangled += 2;
750 mangled = dlang_parse_symbol (decl, mangled, dlang_function);
753 /* Check for name length mismatch. */
754 if (mangled && (mangled - pend) == psize)
755 return mangled;
757 psize /= 10;
758 string_setlength (decl, saved);
761 /* No match on any combinations. */
762 return NULL;
764 else
766 if (strlen (endptr) < (size_t) len)
767 return NULL;
769 mangled = endptr;
771 /* May be a template instance. */
772 if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
773 && (mangled[2] == 'T' || mangled[2] == 'U'))
774 return dlang_parse_template (decl, mangled, len);
776 switch (len)
778 case 6:
779 if (strncmp (mangled, "__ctor", len) == 0)
781 /* Constructor symbol for a class/struct. */
782 string_append (decl, "this");
783 mangled += len;
784 return mangled;
786 else if (strncmp (mangled, "__dtor", len) == 0)
788 /* Destructor symbol for a class/struct. */
789 string_append (decl, "~this");
790 mangled += len;
791 return mangled;
793 else if (strncmp (mangled, "__initZ", len+1) == 0)
795 /* The static initialiser for a given symbol. */
796 string_append (decl, "init$");
797 mangled += len;
798 return mangled;
800 else if (strncmp (mangled, "__vtblZ", len+1) == 0)
802 /* The vtable symbol for a given class. */
803 string_prepend (decl, "vtable for ");
804 string_setlength (decl, string_length (decl) - 1);
805 mangled += len;
806 return mangled;
808 break;
810 case 7:
811 if (strncmp (mangled, "__ClassZ", len+1) == 0)
813 /* The classinfo symbol for a given class. */
814 string_prepend (decl, "ClassInfo for ");
815 string_setlength (decl, string_length (decl) - 1);
816 mangled += len;
817 return mangled;
819 break;
821 case 10:
822 if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
824 /* Postblit symbol for a struct. */
825 string_append (decl, "this(this)");
826 mangled += len + 3;
827 return mangled;
829 break;
831 case 11:
832 if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
834 /* The interface symbol for a given class. */
835 string_prepend (decl, "Interface for ");
836 string_setlength (decl, string_length (decl) - 1);
837 mangled += len;
838 return mangled;
840 break;
842 case 12:
843 if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
845 /* The ModuleInfo symbol for a given module. */
846 string_prepend (decl, "ModuleInfo for ");
847 string_setlength (decl, string_length (decl) - 1);
848 mangled += len;
849 return mangled;
851 break;
854 string_appendn (decl, mangled, len);
855 mangled += len;
858 return mangled;
861 /* Extract the integer value from MANGLED and append it to DECL,
862 where TYPE is the type it should be represented as.
863 Return the remaining string on success or NULL on failure. */
864 static const char *
865 dlang_parse_integer (string *decl, const char *mangled, char type)
867 if (type == 'a' || type == 'u' || type == 'w')
869 /* Parse character value. */
870 char value[10];
871 int pos = 10;
872 int width = 0;
873 char *endptr;
874 long val = strtol (mangled, &endptr, 10);
876 if (endptr == NULL || val < 0)
877 return NULL;
879 string_append (decl, "'");
881 if (type == 'a' && val >= 0x20 && val < 0x7F)
883 /* Represent as a character literal. */
884 char c = (char) val;
885 string_appendn (decl, &c, 1);
887 else
889 /* Represent as a hexadecimal value. */
890 switch (type)
892 case 'a': /* char */
893 string_append (decl, "\\x");
894 width = 2;
895 break;
896 case 'u': /* wchar */
897 string_append (decl, "\\u");
898 width = 4;
899 break;
900 case 'w': /* dchar */
901 string_append (decl, "\\U");
902 width = 8;
903 break;
906 while (val > 0)
908 int digit = val % 16;
910 if (digit < 10)
911 value[--pos] = (char)(digit + '0');
912 else
913 value[--pos] = (char)((digit - 10) + 'a');
915 val /= 16;
916 width--;
919 for (; width > 0; width--)
920 value[--pos] = '0';
922 string_appendn (decl, &(value[pos]), 10 - pos);
924 string_append (decl, "'");
925 mangled = endptr;
927 else if (type == 'b')
929 /* Parse boolean value. */
930 char *endptr;
931 long val = strtol (mangled, &endptr, 10);
933 if (endptr == NULL || val < 0)
934 return NULL;
936 string_append (decl, val ? "true" : "false");
937 mangled = endptr;
939 else
941 /* Parse integer value. */
942 const char *numptr = mangled;
943 size_t num = 0;
945 while (ISDIGIT (*mangled))
947 num++;
948 mangled++;
950 string_appendn (decl, numptr, num);
952 /* Append suffix. */
953 switch (type)
955 case 'h': /* ubyte */
956 case 't': /* ushort */
957 case 'k': /* uint */
958 string_append (decl, "u");
959 break;
960 case 'l': /* long */
961 string_append (decl, "L");
962 break;
963 case 'm': /* ulong */
964 string_append (decl, "uL");
965 break;
969 return mangled;
972 /* Extract the floating-point value from MANGLED and append it to DECL.
973 Return the remaining string on success or NULL on failure. */
974 static const char *
975 dlang_parse_real (string *decl, const char *mangled)
977 char buffer[64];
978 int len = 0;
980 /* Handle NAN and +-INF. */
981 if (strncmp (mangled, "NAN", 3) == 0)
983 string_append (decl, "NaN");
984 mangled += 3;
985 return mangled;
987 else if (strncmp (mangled, "INF", 3) == 0)
989 string_append (decl, "Inf");
990 mangled += 3;
991 return mangled;
993 else if (strncmp (mangled, "NINF", 4) == 0)
995 string_append (decl, "-Inf");
996 mangled += 4;
997 return mangled;
1000 /* Hexadecimal prefix and leading bit. */
1001 if (*mangled == 'N')
1003 buffer[len++] = '-';
1004 mangled++;
1007 if (!ISXDIGIT (*mangled))
1008 return NULL;
1010 buffer[len++] = '0';
1011 buffer[len++] = 'x';
1012 buffer[len++] = *mangled;
1013 buffer[len++] = '.';
1014 mangled++;
1016 /* Significand. */
1017 while (ISXDIGIT (*mangled))
1019 buffer[len++] = *mangled;
1020 mangled++;
1023 /* Exponent. */
1024 if (*mangled != 'P')
1025 return NULL;
1027 buffer[len++] = 'p';
1028 mangled++;
1030 if (*mangled == 'N')
1032 buffer[len++] = '-';
1033 mangled++;
1036 while (ISDIGIT (*mangled))
1038 buffer[len++] = *mangled;
1039 mangled++;
1042 /* Write out the demangled hexadecimal, rather than trying to
1043 convert the buffer into a floating-point value. */
1044 buffer[len] = '\0';
1045 len = strlen (buffer);
1046 string_appendn (decl, buffer, len);
1047 return mangled;
1050 /* Convert VAL from an ascii hexdigit to value. */
1051 static char
1052 ascii2hex (char val)
1054 if (val >= 'a' && val <= 'f')
1055 return (val - 'a' + 10);
1057 if (val >= 'A' && val <= 'F')
1058 return (val - 'A' + 10);
1060 if (val >= '0' && val <= '9')
1061 return (val - '0');
1063 return 0;
1066 /* Extract the string value from MANGLED and append it to DECL.
1067 Return the remaining string on success or NULL on failure. */
1068 static const char *
1069 dlang_parse_string (string *decl, const char *mangled)
1071 char type = *mangled;
1072 char *endptr;
1073 long len;
1075 mangled++;
1076 len = strtol (mangled, &endptr, 10);
1078 if (endptr == NULL || len < 0)
1079 return NULL;
1081 mangled = endptr;
1082 if (*mangled != '_')
1083 return NULL;
1085 mangled++;
1086 string_append (decl, "\"");
1087 while (len--)
1089 if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1]))
1091 char a = ascii2hex (mangled[0]);
1092 char b = ascii2hex (mangled[1]);
1093 char val = (a << 4) | b;
1095 /* Sanitize white and non-printable characters. */
1096 switch (val)
1098 case ' ':
1099 string_append (decl, " ");
1100 break;
1101 case '\t':
1102 string_append (decl, "\\t");
1103 break;
1104 case '\n':
1105 string_append (decl, "\\n");
1106 break;
1107 case '\r':
1108 string_append (decl, "\\r");
1109 break;
1110 case '\f':
1111 string_append (decl, "\\f");
1112 break;
1113 case '\v':
1114 string_append (decl, "\\v");
1115 break;
1117 default:
1118 if (ISPRINT (val))
1119 string_appendn (decl, &val, 1);
1120 else
1122 string_append (decl, "\\x");
1123 string_appendn (decl, mangled, 2);
1127 else
1128 return NULL;
1130 mangled += 2;
1132 string_append (decl, "\"");
1134 if (type != 'a')
1135 string_appendn (decl, &type, 1);
1137 return mangled;
1140 /* Extract the static array value from MANGLED and append it to DECL.
1141 Return the remaining string on success or NULL on failure. */
1142 static const char *
1143 dlang_parse_arrayliteral (string *decl, const char *mangled)
1145 char *endptr;
1146 long elements = strtol (mangled, &endptr, 10);
1148 if (endptr == NULL || elements < 0)
1149 return NULL;
1151 mangled = endptr;
1152 string_append (decl, "[");
1153 while (elements--)
1155 mangled = dlang_value (decl, mangled, NULL, '\0');
1156 if (elements != 0)
1157 string_append (decl, ", ");
1160 string_append (decl, "]");
1161 return mangled;
1164 /* Extract the associative array value from MANGLED and append it to DECL.
1165 Return the remaining string on success or NULL on failure. */
1166 static const char *
1167 dlang_parse_assocarray (string *decl, const char *mangled)
1169 char *endptr;
1170 long elements = strtol (mangled, &endptr, 10);
1172 if (endptr == NULL || elements < 0)
1173 return NULL;
1175 mangled = endptr;
1176 string_append (decl, "[");
1177 while (elements--)
1179 mangled = dlang_value (decl, mangled, NULL, '\0');
1180 string_append (decl, ":");
1181 mangled = dlang_value (decl, mangled, NULL, '\0');
1183 if (elements != 0)
1184 string_append (decl, ", ");
1187 string_append (decl, "]");
1188 return mangled;
1191 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1192 Return the remaining string on success or NULL on failure. */
1193 static const char *
1194 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1196 char *endptr;
1197 long args = strtol (mangled, &endptr, 10);
1199 if (endptr == NULL || args < 0)
1200 return NULL;
1202 mangled = endptr;
1203 if (name != NULL)
1204 string_append (decl, name);
1206 string_append (decl, "(");
1207 while (args--)
1209 mangled = dlang_value (decl, mangled, NULL, '\0');
1210 if (args != 0)
1211 string_append (decl, ", ");
1214 string_append (decl, ")");
1215 return mangled;
1218 /* Extract the value from MANGLED and append it to DECL.
1219 Return the remaining string on success or NULL on failure. */
1220 static const char *
1221 dlang_value (string *decl, const char *mangled, const char *name, char type)
1223 if (mangled == NULL || *mangled == '\0')
1224 return NULL;
1226 switch (*mangled)
1228 /* Null value. */
1229 case 'n':
1230 mangled++;
1231 string_append (decl, "null");
1232 break;
1234 /* Integral values. */
1235 case 'N':
1236 mangled++;
1237 string_append (decl, "-");
1238 mangled = dlang_parse_integer (decl, mangled, type);
1239 break;
1241 case 'i':
1242 mangled++;
1243 if (*mangled < '0' || *mangled > '9')
1244 return NULL;
1245 /* Fall through */
1246 case '0': case '1': case '2': case '3': case '4':
1247 case '5': case '6': case '7': case '8': case '9':
1248 mangled = dlang_parse_integer (decl, mangled, type);
1249 break;
1251 /* Real value. */
1252 case 'e':
1253 mangled++;
1254 mangled = dlang_parse_real (decl, mangled);
1255 break;
1257 /* Complex value. */
1258 case 'c':
1259 mangled++;
1260 mangled = dlang_parse_real (decl, mangled);
1261 string_append (decl, "+");
1262 if (mangled == NULL || *mangled != 'c')
1263 return NULL;
1264 mangled++;
1265 mangled = dlang_parse_real (decl, mangled);
1266 string_append (decl, "i");
1267 break;
1269 /* String values. */
1270 case 'a': /* UTF8 */
1271 case 'w': /* UTF16 */
1272 case 'd': /* UTF32 */
1273 mangled = dlang_parse_string (decl, mangled);
1274 break;
1276 /* Array values. */
1277 case 'A':
1278 mangled++;
1279 if (type == 'H')
1280 mangled = dlang_parse_assocarray (decl, mangled);
1281 else
1282 mangled = dlang_parse_arrayliteral (decl, mangled);
1283 break;
1285 /* Struct values. */
1286 case 'S':
1287 mangled++;
1288 mangled = dlang_parse_structlit (decl, mangled, name);
1289 break;
1291 default:
1292 return NULL;
1295 return mangled;
1298 /* Extract the type modifiers from MANGLED and return the string
1299 length that it consumes in MANGLED on success or 0 on failure. */
1300 static int
1301 dlang_type_modifier_p (const char *mangled)
1303 int i;
1305 switch (*mangled)
1307 case 'x': case 'y':
1308 return 1;
1310 case 'O':
1311 mangled++;
1312 i = dlang_type_modifier_p (mangled);
1313 return i + 1;
1315 case 'N':
1316 mangled++;
1317 if (*mangled == 'g')
1319 mangled++;
1320 i = dlang_type_modifier_p (mangled);
1321 return i + 2;
1325 return 0;
1328 /* Extract the function calling convention from MANGLED and
1329 return 1 on success or 0 on failure. */
1330 static int
1331 dlang_call_convention_p (const char *mangled)
1333 /* Prefix for functions needing 'this' */
1334 if (*mangled == 'M')
1336 mangled++;
1337 /* Also skip over any type modifiers. */
1338 mangled += dlang_type_modifier_p (mangled);
1341 switch (*mangled)
1343 case 'F': case 'U': case 'V':
1344 case 'W': case 'R': case 'Y':
1345 return 1;
1347 default:
1348 return 0;
1352 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1353 Returns the remaining signature on success or NULL on failure. */
1354 static const char *
1355 dlang_parse_symbol (string *decl, const char *mangled,
1356 enum dlang_symbol_kinds kind)
1358 int saved;
1359 size_t n = 0;
1362 if (n++)
1363 string_append (decl, ".");
1365 /* Skip over anonymous symbols. */
1366 while (*mangled == '0')
1367 mangled++;
1369 mangled = dlang_identifier (decl, mangled, kind);
1371 if (mangled && dlang_call_convention_p (mangled))
1373 string mods;
1374 const char *start = NULL;
1375 int checkpoint = 0;
1377 /* Skip over 'this' parameter. */
1378 if (*mangled == 'M')
1379 mangled++;
1381 /* We have reached here because we expect an extern(Pascal) function.
1382 However this is so rare, that it is more likely a template value
1383 parameter. Since this can't be assumed, first attempt parsing
1384 the symbol as a function, and then back out on failure. */
1385 if (*mangled == 'V')
1387 start = mangled;
1388 checkpoint = string_length (decl);
1391 /* Save the type modifiers for appending at the end. */
1392 string_init (&mods);
1393 mangled = dlang_type_modifiers (&mods, mangled);
1395 /* Skip over calling convention and attributes in qualified name. */
1396 saved = string_length (decl);
1397 mangled = dlang_call_convention (decl, mangled);
1398 mangled = dlang_attributes (decl, mangled);
1399 string_setlength (decl, saved);
1401 string_append (decl, "(");
1402 mangled = dlang_function_args (decl, mangled);
1403 string_append (decl, ")");
1405 /* Add any const/immutable/shared modifier. */
1406 string_appendn (decl, mods.b, string_length (&mods));
1407 string_delete (&mods);
1409 if (mangled == NULL && checkpoint != 0)
1411 mangled = start;
1412 string_setlength (decl, checkpoint);
1416 while (mangled && ISDIGIT (*mangled));
1418 /* Only top-level symbols or function template parameters have
1419 a type that needs checking. */
1420 if (kind == dlang_top_level || kind == dlang_function)
1422 /* Artificial symbols end with 'Z' and have no type. */
1423 if (mangled && *mangled == 'Z')
1424 mangled++;
1425 else
1427 saved = string_length (decl);
1428 mangled = dlang_type (decl, mangled);
1429 string_setlength (decl, saved);
1432 /* Check that the entire symbol was successfully demangled. */
1433 if (kind == dlang_top_level)
1435 if (mangled == NULL || *mangled != '\0')
1436 return NULL;
1440 return mangled;
1443 /* Demangle the tuple from MANGLED and append it to DECL.
1444 Return the remaining string on success or NULL on failure. */
1445 static const char *
1446 dlang_parse_tuple (string *decl, const char *mangled)
1448 char *endptr;
1449 long elements = strtol (mangled, &endptr, 10);
1451 if (endptr == NULL || elements < 0)
1452 return NULL;
1454 mangled = endptr;
1455 string_append (decl, "Tuple!(");
1457 while (elements--)
1459 mangled = dlang_type (decl, mangled);
1460 if (elements != 0)
1461 string_append (decl, ", ");
1464 string_append (decl, ")");
1465 return mangled;
1468 /* Demangle the argument list from MANGLED and append it to DECL.
1469 Return the remaining string on success or NULL on failure. */
1470 static const char *
1471 dlang_template_args (string *decl, const char *mangled)
1473 size_t n = 0;
1475 while (mangled && *mangled != '\0')
1477 switch (*mangled)
1479 case 'Z': /* End of parameter list. */
1480 mangled++;
1481 return mangled;
1484 if (n++)
1485 string_append (decl, ", ");
1487 /* Skip over specialised template prefix. */
1488 if (*mangled == 'H')
1489 mangled++;
1491 switch (*mangled)
1493 case 'S': /* Symbol parameter. */
1494 mangled++;
1495 mangled = dlang_parse_symbol (decl, mangled, dlang_template_param);
1496 break;
1497 case 'T': /* Type parameter. */
1498 mangled++;
1499 mangled = dlang_type (decl, mangled);
1500 break;
1501 case 'V': /* Value parameter. */
1503 string name;
1504 char type;
1506 /* Peek at the type. */
1507 mangled++;
1508 type = *mangled;
1510 /* In the few instances where the type is actually desired in
1511 the output, it should precede the value from dlang_value. */
1512 string_init (&name);
1513 mangled = dlang_type (&name, mangled);
1514 string_need (&name, 1);
1515 *(name.p) = '\0';
1517 mangled = dlang_value (decl, mangled, name.b, type);
1518 string_delete (&name);
1519 break;
1522 default:
1523 return NULL;
1527 return mangled;
1530 /* Extract and demangle the template symbol in MANGLED, expected to
1531 be made up of LEN characters, and append it to DECL.
1532 Returns the remaining signature on success or NULL on failure. */
1533 static const char *
1534 dlang_parse_template (string *decl, const char *mangled, long len)
1536 const char *start = mangled;
1538 /* Template instance names have the types and values of its parameters
1539 encoded into it.
1541 TemplateInstanceName:
1542 Number __T LName TemplateArgs Z
1543 Number __U LName TemplateArgs Z
1545 The start pointer should be at the above location, and LEN should be
1546 the value of the decoded number.
1549 /* Template symbol. */
1550 if (!ISDIGIT (mangled[3]) || mangled[3] == '0')
1551 return NULL;
1553 mangled += 3;
1555 /* Template identifier. */
1556 mangled = dlang_identifier (decl, mangled, dlang_template_ident);
1558 /* Template arguments. */
1559 string_append (decl, "!(");
1560 mangled = dlang_template_args (decl, mangled);
1561 string_append (decl, ")");
1563 /* Check for template name length mismatch. */
1564 if (mangled && (mangled - start) != len)
1565 return NULL;
1567 return mangled;
1570 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1571 signature on success or NULL on failure. */
1573 char *
1574 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1576 string decl;
1577 char *demangled = NULL;
1579 if (mangled == NULL || *mangled == '\0')
1580 return NULL;
1582 if (strncmp (mangled, "_D", 2) != 0)
1583 return NULL;
1585 string_init (&decl);
1587 if (strcmp (mangled, "_Dmain") == 0)
1589 string_append (&decl, "D main");
1591 else
1593 mangled += 2;
1595 if (dlang_parse_symbol (&decl, mangled, dlang_top_level) == NULL)
1596 string_delete (&decl);
1599 if (string_length (&decl) > 0)
1601 string_need (&decl, 1);
1602 *(decl.p) = '\0';
1603 demangled = decl.b;
1606 return demangled;