[Ada] Fix small fallout of change for 'Pos and 'Val attributes
[official-gcc.git] / libiberty / d-demangle.c
blobf2d6946ecad69947d237c064dc836e28cfe9a876
1 /* Demangler for the D programming language
2 Copyright (C) 2014-2020 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 /* Demangle information structure we pass around. */
164 struct dlang_info
166 /* The string we are demangling. */
167 const char *s;
168 /* The index of the last back reference. */
169 int last_backref;
172 /* Pass as the LEN to dlang_parse_template if symbol length is not known. */
173 enum { TEMPLATE_LENGTH_UNKNOWN = -1 };
175 /* Prototypes for forward referenced functions */
176 static const char *dlang_function_type (string *, const char *,
177 struct dlang_info *);
179 static const char *dlang_function_args (string *, const char *,
180 struct dlang_info *);
182 static const char *dlang_type (string *, const char *, struct dlang_info *);
184 static const char *dlang_value (string *, const char *, const char *, char);
186 static const char *dlang_parse_qualified (string *, const char *,
187 struct dlang_info *, int);
189 static const char *dlang_parse_mangle (string *, const char *,
190 struct dlang_info *);
192 static const char *dlang_parse_tuple (string *, const char *,
193 struct dlang_info *);
195 static const char *dlang_parse_template (string *, const char *,
196 struct dlang_info *, long);
198 static const char *dlang_lname (string *, const char *, long);
201 /* Extract the number from MANGLED, and assign the result to RET.
202 Return the remaining string on success or NULL on failure. */
203 static const char *
204 dlang_number (const char *mangled, long *ret)
206 /* Return NULL if trying to extract something that isn't a digit. */
207 if (mangled == NULL || !ISDIGIT (*mangled))
208 return NULL;
210 (*ret) = 0;
212 while (ISDIGIT (*mangled))
214 (*ret) *= 10;
216 /* If an overflow occured when multiplying by ten, the result
217 will not be a multiple of ten. */
218 if ((*ret % 10) != 0)
219 return NULL;
221 (*ret) += mangled[0] - '0';
222 mangled++;
225 if (*mangled == '\0' || *ret < 0)
226 return NULL;
228 return mangled;
231 /* Extract the hex-digit from MANGLED, and assign the result to RET.
232 Return the remaining string on success or NULL on failure. */
233 static const char *
234 dlang_hexdigit (const char *mangled, char *ret)
236 char c;
238 /* Return NULL if trying to extract something that isn't a hexdigit. */
239 if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1]))
240 return NULL;
242 c = mangled[0];
243 if (!ISDIGIT (c))
244 (*ret) = (c - (ISUPPER (c) ? 'A' : 'a') + 10);
245 else
246 (*ret) = (c - '0');
248 c = mangled[1];
249 if (!ISDIGIT (c))
250 (*ret) = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
251 else
252 (*ret) = (*ret << 4) | (c - '0');
254 mangled += 2;
256 return mangled;
259 /* Extract the function calling convention from MANGLED and
260 return 1 on success or 0 on failure. */
261 static int
262 dlang_call_convention_p (const char *mangled)
264 switch (*mangled)
266 case 'F': case 'U': case 'V':
267 case 'W': case 'R': case 'Y':
268 return 1;
270 default:
271 return 0;
275 /* Extract the back reference position from MANGLED, and assign the result
276 to RET. Return the remaining string on success or NULL on failure. */
277 static const char *
278 dlang_decode_backref (const char *mangled, long *ret)
280 /* Return NULL if trying to extract something that isn't a digit. */
281 if (mangled == NULL || !ISALPHA (*mangled))
282 return NULL;
284 /* Any identifier or non-basic type that has been emitted to the mangled
285 symbol before will not be emitted again, but is referenced by a special
286 sequence encoding the relative position of the original occurrence in the
287 mangled symbol name.
289 Numbers in back references are encoded with base 26 by upper case letters
290 A-Z for higher digits but lower case letters a-z for the last digit.
292 NumberBackRef:
293 [a-z]
294 [A-Z] NumberBackRef
297 (*ret) = 0;
299 while (ISALPHA (*mangled))
301 (*ret) *= 26;
303 /* If an overflow occured when multiplying by 26, the result
304 will not be a multiple of 26. */
305 if ((*ret % 26) != 0)
306 return NULL;
308 if (mangled[0] >= 'a' && mangled[0] <= 'z')
310 (*ret) += mangled[0] - 'a';
311 return mangled + 1;
314 (*ret) += mangled[0] - 'A';
315 mangled++;
318 return NULL;
321 /* Extract the symbol pointed at by the back reference and assign the result
322 to RET. Return the remaining string on success or NULL on failure. */
323 static const char *
324 dlang_backref (const char *mangled, const char **ret, struct dlang_info *info)
326 (*ret) = NULL;
328 if (mangled == NULL || *mangled != 'Q')
329 return NULL;
331 /* Position of 'Q'. */
332 const char *qpos = mangled;
333 long refpos;
334 mangled++;
336 mangled = dlang_decode_backref (mangled, &refpos);
337 if (mangled == NULL)
338 return NULL;
340 if (refpos <= 0 || refpos > qpos - info->s)
341 return NULL;
343 /* Set the position of the back reference. */
344 (*ret) = qpos - refpos;
346 return mangled;
349 /* Demangle a back referenced symbol from MANGLED and append it to DECL.
350 Return the remaining string on success or NULL on failure. */
351 static const char *
352 dlang_symbol_backref (string *decl, const char *mangled,
353 struct dlang_info *info)
355 /* An identifier back reference always points to a digit 0 to 9.
357 IdentifierBackRef:
358 Q NumberBackRef
361 const char *backref;
362 long len;
364 /* Get position of the back reference. */
365 mangled = dlang_backref (mangled, &backref, info);
367 /* Must point to a simple identifier. */
368 backref = dlang_number (backref, &len);
369 if (backref == NULL)
370 return NULL;
372 backref = dlang_lname (decl, backref, len);
373 if (backref == NULL)
374 return NULL;
376 return mangled;
379 /* Demangle a back referenced type from MANGLED and append it to DECL.
380 IS_FUNCTION is 1 if the back referenced type is expected to be a function.
381 Return the remaining string on success or NULL on failure. */
382 static const char *
383 dlang_type_backref (string *decl, const char *mangled, struct dlang_info *info,
384 int is_function)
386 /* A type back reference always points to a letter.
388 TypeBackRef:
389 Q NumberBackRef
392 const char *backref;
394 /* If we appear to be moving backwards through the mangle string, then
395 bail as this may be a recursive back reference. */
396 if (mangled - info->s >= info->last_backref)
397 return NULL;
399 int save_refpos = info->last_backref;
400 info->last_backref = mangled - info->s;
402 /* Get position of the back reference. */
403 mangled = dlang_backref (mangled, &backref, info);
405 /* Must point to a type. */
406 if (is_function)
407 backref = dlang_function_type (decl, backref, info);
408 else
409 backref = dlang_type (decl, backref, info);
411 info->last_backref = save_refpos;
413 if (backref == NULL)
414 return NULL;
416 return mangled;
419 /* Extract the beginning of a symbol name from MANGLED and
420 return 1 on success or 0 on failure. */
421 static int
422 dlang_symbol_name_p (const char *mangled, struct dlang_info *info)
424 long ret;
425 const char *qref = mangled;
427 if (ISDIGIT (*mangled))
428 return 1;
430 if (mangled[0] == '_' && mangled[1] == '_'
431 && (mangled[2] == 'T' || mangled[2] == 'U'))
432 return 1;
434 if (*mangled != 'Q')
435 return 0;
437 mangled = dlang_decode_backref (mangled + 1, &ret);
438 if (mangled == NULL || ret <= 0 || ret > qref - info->s)
439 return 0;
441 return ISDIGIT (qref[-ret]);
444 /* Demangle the calling convention from MANGLED and append it to DECL.
445 Return the remaining string on success or NULL on failure. */
446 static const char *
447 dlang_call_convention (string *decl, const char *mangled)
449 if (mangled == NULL || *mangled == '\0')
450 return NULL;
452 switch (*mangled)
454 case 'F': /* (D) */
455 mangled++;
456 break;
457 case 'U': /* (C) */
458 mangled++;
459 string_append (decl, "extern(C) ");
460 break;
461 case 'W': /* (Windows) */
462 mangled++;
463 string_append (decl, "extern(Windows) ");
464 break;
465 case 'V': /* (Pascal) */
466 mangled++;
467 string_append (decl, "extern(Pascal) ");
468 break;
469 case 'R': /* (C++) */
470 mangled++;
471 string_append (decl, "extern(C++) ");
472 break;
473 case 'Y': /* (Objective-C) */
474 mangled++;
475 string_append (decl, "extern(Objective-C) ");
476 break;
477 default:
478 return NULL;
481 return mangled;
484 /* Extract the type modifiers from MANGLED and append them to DECL.
485 Returns the remaining signature on success or NULL on failure. */
486 static const char *
487 dlang_type_modifiers (string *decl, const char *mangled)
489 if (mangled == NULL || *mangled == '\0')
490 return NULL;
492 switch (*mangled)
494 case 'x': /* const */
495 mangled++;
496 string_append (decl, " const");
497 return mangled;
498 case 'y': /* immutable */
499 mangled++;
500 string_append (decl, " immutable");
501 return mangled;
502 case 'O': /* shared */
503 mangled++;
504 string_append (decl, " shared");
505 return dlang_type_modifiers (decl, mangled);
506 case 'N':
507 mangled++;
508 if (*mangled == 'g') /* wild */
510 mangled++;
511 string_append (decl, " inout");
512 return dlang_type_modifiers (decl, mangled);
514 else
515 return NULL;
517 default:
518 return mangled;
522 /* Demangle the D function attributes from MANGLED and append it to DECL.
523 Return the remaining string on success or NULL on failure. */
524 static const char *
525 dlang_attributes (string *decl, const char *mangled)
527 if (mangled == NULL || *mangled == '\0')
528 return NULL;
530 while (*mangled == 'N')
532 mangled++;
533 switch (*mangled)
535 case 'a': /* pure */
536 mangled++;
537 string_append (decl, "pure ");
538 continue;
539 case 'b': /* nothrow */
540 mangled++;
541 string_append (decl, "nothrow ");
542 continue;
543 case 'c': /* ref */
544 mangled++;
545 string_append (decl, "ref ");
546 continue;
547 case 'd': /* @property */
548 mangled++;
549 string_append (decl, "@property ");
550 continue;
551 case 'e': /* @trusted */
552 mangled++;
553 string_append (decl, "@trusted ");
554 continue;
555 case 'f': /* @safe */
556 mangled++;
557 string_append (decl, "@safe ");
558 continue;
559 case 'g':
560 case 'h':
561 case 'k':
562 /* inout parameter is represented as 'Ng'.
563 vector parameter is represented as 'Nh'.
564 return paramenter is represented as 'Nk'.
565 If we see this, then we know we're really in the
566 parameter list. Rewind and break. */
567 mangled--;
568 break;
569 case 'i': /* @nogc */
570 mangled++;
571 string_append (decl, "@nogc ");
572 continue;
573 case 'j': /* return */
574 mangled++;
575 string_append (decl, "return ");
576 continue;
577 case 'l': /* scope */
578 mangled++;
579 string_append (decl, "scope ");
580 continue;
581 case 'm': /* @live */
582 mangled++;
583 string_append (decl, "@live ");
584 continue;
586 default: /* unknown attribute */
587 return NULL;
589 break;
592 return mangled;
595 /* Demangle the function type from MANGLED without the return type.
596 The arguments are appended to ARGS, the calling convention is appended
597 to CALL and attributes are appended to ATTR. Any of these can be NULL
598 to throw the information away. Return the remaining string on success
599 or NULL on failure. */
600 static const char *
601 dlang_function_type_noreturn (string *args, string *call, string *attr,
602 const char *mangled, struct dlang_info *info)
604 string dump;
605 string_init (&dump);
607 /* Skip over calling convention and attributes. */
608 mangled = dlang_call_convention (call ? call : &dump, mangled);
609 mangled = dlang_attributes (attr ? attr : &dump, mangled);
611 if (args)
612 string_append (args, "(");
614 mangled = dlang_function_args (args ? args : &dump, mangled, info);
615 if (args)
616 string_append (args, ")");
618 string_delete (&dump);
619 return mangled;
622 /* Demangle the function type from MANGLED and append it to DECL.
623 Return the remaining string on success or NULL on failure. */
624 static const char *
625 dlang_function_type (string *decl, const char *mangled, struct dlang_info *info)
627 string attr, args, type;
629 if (mangled == NULL || *mangled == '\0')
630 return NULL;
632 /* The order of the mangled string is:
633 CallConvention FuncAttrs Arguments ArgClose Type
635 The demangled string is re-ordered as:
636 CallConvention Type Arguments FuncAttrs
638 string_init (&attr);
639 string_init (&args);
640 string_init (&type);
642 mangled = dlang_function_type_noreturn (&args, decl, &attr, mangled, info);
644 /* Function return type. */
645 mangled = dlang_type (&type, mangled, info);
647 /* Append to decl in order. */
648 string_appendn (decl, type.b, string_length (&type));
649 string_appendn (decl, args.b, string_length (&args));
650 string_append (decl, " ");
651 string_appendn (decl, attr.b, string_length (&attr));
653 string_delete (&attr);
654 string_delete (&args);
655 string_delete (&type);
656 return mangled;
659 /* Demangle the argument list from MANGLED and append it to DECL.
660 Return the remaining string on success or NULL on failure. */
661 static const char *
662 dlang_function_args (string *decl, const char *mangled, struct dlang_info *info)
664 size_t n = 0;
666 while (mangled && *mangled != '\0')
668 switch (*mangled)
670 case 'X': /* (variadic T t...) style. */
671 mangled++;
672 string_append (decl, "...");
673 return mangled;
674 case 'Y': /* (variadic T t, ...) style. */
675 mangled++;
676 if (n != 0)
677 string_append (decl, ", ");
678 string_append (decl, "...");
679 return mangled;
680 case 'Z': /* Normal function. */
681 mangled++;
682 return mangled;
685 if (n++)
686 string_append (decl, ", ");
688 if (*mangled == 'M') /* scope(T) */
690 mangled++;
691 string_append (decl, "scope ");
694 if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
696 mangled += 2;
697 string_append (decl, "return ");
700 switch (*mangled)
702 case 'J': /* out(T) */
703 mangled++;
704 string_append (decl, "out ");
705 break;
706 case 'K': /* ref(T) */
707 mangled++;
708 string_append (decl, "ref ");
709 break;
710 case 'L': /* lazy(T) */
711 mangled++;
712 string_append (decl, "lazy ");
713 break;
715 mangled = dlang_type (decl, mangled, info);
718 return mangled;
721 /* Demangle the type from MANGLED and append it to DECL.
722 Return the remaining string on success or NULL on failure. */
723 static const char *
724 dlang_type (string *decl, const char *mangled, struct dlang_info *info)
726 if (mangled == NULL || *mangled == '\0')
727 return NULL;
729 switch (*mangled)
731 case 'O': /* shared(T) */
732 mangled++;
733 string_append (decl, "shared(");
734 mangled = dlang_type (decl, mangled, info);
735 string_append (decl, ")");
736 return mangled;
737 case 'x': /* const(T) */
738 mangled++;
739 string_append (decl, "const(");
740 mangled = dlang_type (decl, mangled, info);
741 string_append (decl, ")");
742 return mangled;
743 case 'y': /* immutable(T) */
744 mangled++;
745 string_append (decl, "immutable(");
746 mangled = dlang_type (decl, mangled, info);
747 string_append (decl, ")");
748 return mangled;
749 case 'N':
750 mangled++;
751 if (*mangled == 'g') /* wild(T) */
753 mangled++;
754 string_append (decl, "inout(");
755 mangled = dlang_type (decl, mangled, info);
756 string_append (decl, ")");
757 return mangled;
759 else if (*mangled == 'h') /* vector(T) */
761 mangled++;
762 string_append (decl, "__vector(");
763 mangled = dlang_type (decl, mangled, info);
764 string_append (decl, ")");
765 return mangled;
767 else
768 return NULL;
769 case 'A': /* dynamic array (T[]) */
770 mangled++;
771 mangled = dlang_type (decl, mangled, info);
772 string_append (decl, "[]");
773 return mangled;
774 case 'G': /* static array (T[N]) */
776 const char *numptr;
777 size_t num = 0;
778 mangled++;
780 numptr = mangled;
781 while (ISDIGIT (*mangled))
783 num++;
784 mangled++;
786 mangled = dlang_type (decl, mangled, info);
787 string_append (decl, "[");
788 string_appendn (decl, numptr, num);
789 string_append (decl, "]");
790 return mangled;
792 case 'H': /* associative array (T[T]) */
794 string type;
795 size_t sztype;
796 mangled++;
798 string_init (&type);
799 mangled = dlang_type (&type, mangled, info);
800 sztype = string_length (&type);
802 mangled = dlang_type (decl, mangled, info);
803 string_append (decl, "[");
804 string_appendn (decl, type.b, sztype);
805 string_append (decl, "]");
807 string_delete (&type);
808 return mangled;
810 case 'P': /* pointer (T*) */
811 mangled++;
812 if (!dlang_call_convention_p (mangled))
814 mangled = dlang_type (decl, mangled, info);
815 string_append (decl, "*");
816 return mangled;
818 /* Fall through */
819 case 'F': /* function T (D) */
820 case 'U': /* function T (C) */
821 case 'W': /* function T (Windows) */
822 case 'V': /* function T (Pascal) */
823 case 'R': /* function T (C++) */
824 case 'Y': /* function T (Objective-C) */
825 /* Function pointer types don't include the trailing asterisk. */
826 mangled = dlang_function_type (decl, mangled, info);
827 string_append (decl, "function");
828 return mangled;
829 case 'I': /* ident T */
830 case 'C': /* class T */
831 case 'S': /* struct T */
832 case 'E': /* enum T */
833 case 'T': /* typedef T */
834 mangled++;
835 return dlang_parse_qualified (decl, mangled, info, 0);
836 case 'D': /* delegate T */
838 string mods;
839 size_t szmods;
840 mangled++;
842 string_init (&mods);
843 mangled = dlang_type_modifiers (&mods, mangled);
844 szmods = string_length (&mods);
846 /* Back referenced function type. */
847 if (*mangled == 'Q')
848 mangled = dlang_type_backref (decl, mangled, info, 1);
849 else
850 mangled = dlang_function_type (decl, mangled, info);
852 string_append (decl, "delegate");
853 string_appendn (decl, mods.b, szmods);
855 string_delete (&mods);
856 return mangled;
858 case 'B': /* tuple T */
859 mangled++;
860 return dlang_parse_tuple (decl, mangled, info);
862 /* Basic types */
863 case 'n':
864 mangled++;
865 string_append (decl, "none");
866 return mangled;
867 case 'v':
868 mangled++;
869 string_append (decl, "void");
870 return mangled;
871 case 'g':
872 mangled++;
873 string_append (decl, "byte");
874 return mangled;
875 case 'h':
876 mangled++;
877 string_append (decl, "ubyte");
878 return mangled;
879 case 's':
880 mangled++;
881 string_append (decl, "short");
882 return mangled;
883 case 't':
884 mangled++;
885 string_append (decl, "ushort");
886 return mangled;
887 case 'i':
888 mangled++;
889 string_append (decl, "int");
890 return mangled;
891 case 'k':
892 mangled++;
893 string_append (decl, "uint");
894 return mangled;
895 case 'l':
896 mangled++;
897 string_append (decl, "long");
898 return mangled;
899 case 'm':
900 mangled++;
901 string_append (decl, "ulong");
902 return mangled;
903 case 'f':
904 mangled++;
905 string_append (decl, "float");
906 return mangled;
907 case 'd':
908 mangled++;
909 string_append (decl, "double");
910 return mangled;
911 case 'e':
912 mangled++;
913 string_append (decl, "real");
914 return mangled;
916 /* Imaginary and Complex types */
917 case 'o':
918 mangled++;
919 string_append (decl, "ifloat");
920 return mangled;
921 case 'p':
922 mangled++;
923 string_append (decl, "idouble");
924 return mangled;
925 case 'j':
926 mangled++;
927 string_append (decl, "ireal");
928 return mangled;
929 case 'q':
930 mangled++;
931 string_append (decl, "cfloat");
932 return mangled;
933 case 'r':
934 mangled++;
935 string_append (decl, "cdouble");
936 return mangled;
937 case 'c':
938 mangled++;
939 string_append (decl, "creal");
940 return mangled;
942 /* Other types */
943 case 'b':
944 mangled++;
945 string_append (decl, "bool");
946 return mangled;
947 case 'a':
948 mangled++;
949 string_append (decl, "char");
950 return mangled;
951 case 'u':
952 mangled++;
953 string_append (decl, "wchar");
954 return mangled;
955 case 'w':
956 mangled++;
957 string_append (decl, "dchar");
958 return mangled;
959 case 'z':
960 mangled++;
961 switch (*mangled)
963 case 'i':
964 mangled++;
965 string_append (decl, "cent");
966 return mangled;
967 case 'k':
968 mangled++;
969 string_append (decl, "ucent");
970 return mangled;
972 return NULL;
974 /* Back referenced type. */
975 case 'Q':
976 return dlang_type_backref (decl, mangled, info, 0);
978 default: /* unhandled */
979 return NULL;
983 /* Extract the identifier from MANGLED and append it to DECL.
984 Return the remaining string on success or NULL on failure. */
985 static const char *
986 dlang_identifier (string *decl, const char *mangled, struct dlang_info *info)
988 long len;
990 if (mangled == NULL || *mangled == '\0')
991 return NULL;
993 if (*mangled == 'Q')
994 return dlang_symbol_backref (decl, mangled, info);
996 /* May be a template instance without a length prefix. */
997 if (mangled[0] == '_' && mangled[1] == '_'
998 && (mangled[2] == 'T' || mangled[2] == 'U'))
999 return dlang_parse_template (decl, mangled, info, TEMPLATE_LENGTH_UNKNOWN);
1001 const char *endptr = dlang_number (mangled, &len);
1003 if (endptr == NULL || len == 0)
1004 return NULL;
1006 if (strlen (endptr) < (size_t) len)
1007 return NULL;
1009 mangled = endptr;
1011 /* May be a template instance with a length prefix. */
1012 if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
1013 && (mangled[2] == 'T' || mangled[2] == 'U'))
1014 return dlang_parse_template (decl, mangled, info, len);
1016 return dlang_lname (decl, mangled, len);
1019 /* Extract the plain identifier from MANGLED and prepend/append it to DECL
1020 with special treatment for some magic compiler generted symbols.
1021 Return the remaining string on success or NULL on failure. */
1022 static const char *
1023 dlang_lname (string *decl, const char *mangled, long len)
1025 switch (len)
1027 case 6:
1028 if (strncmp (mangled, "__ctor", len) == 0)
1030 /* Constructor symbol for a class/struct. */
1031 string_append (decl, "this");
1032 mangled += len;
1033 return mangled;
1035 else if (strncmp (mangled, "__dtor", len) == 0)
1037 /* Destructor symbol for a class/struct. */
1038 string_append (decl, "~this");
1039 mangled += len;
1040 return mangled;
1042 else if (strncmp (mangled, "__initZ", len + 1) == 0)
1044 /* The static initialiser for a given symbol. */
1045 string_prepend (decl, "initializer for ");
1046 string_setlength (decl, string_length (decl) - 1);
1047 mangled += len;
1048 return mangled;
1050 else if (strncmp (mangled, "__vtblZ", len + 1) == 0)
1052 /* The vtable symbol for a given class. */
1053 string_prepend (decl, "vtable for ");
1054 string_setlength (decl, string_length (decl) - 1);
1055 mangled += len;
1056 return mangled;
1058 break;
1060 case 7:
1061 if (strncmp (mangled, "__ClassZ", len + 1) == 0)
1063 /* The classinfo symbol for a given class. */
1064 string_prepend (decl, "ClassInfo for ");
1065 string_setlength (decl, string_length (decl) - 1);
1066 mangled += len;
1067 return mangled;
1069 break;
1071 case 10:
1072 if (strncmp (mangled, "__postblitMFZ", len + 3) == 0)
1074 /* Postblit symbol for a struct. */
1075 string_append (decl, "this(this)");
1076 mangled += len + 3;
1077 return mangled;
1079 break;
1081 case 11:
1082 if (strncmp (mangled, "__InterfaceZ", len + 1) == 0)
1084 /* The interface symbol for a given class. */
1085 string_prepend (decl, "Interface for ");
1086 string_setlength (decl, string_length (decl) - 1);
1087 mangled += len;
1088 return mangled;
1090 break;
1092 case 12:
1093 if (strncmp (mangled, "__ModuleInfoZ", len + 1) == 0)
1095 /* The ModuleInfo symbol for a given module. */
1096 string_prepend (decl, "ModuleInfo for ");
1097 string_setlength (decl, string_length (decl) - 1);
1098 mangled += len;
1099 return mangled;
1101 break;
1104 string_appendn (decl, mangled, len);
1105 mangled += len;
1107 return mangled;
1110 /* Extract the integer value from MANGLED and append it to DECL,
1111 where TYPE is the type it should be represented as.
1112 Return the remaining string on success or NULL on failure. */
1113 static const char *
1114 dlang_parse_integer (string *decl, const char *mangled, char type)
1116 if (type == 'a' || type == 'u' || type == 'w')
1118 /* Parse character value. */
1119 char value[20];
1120 int pos = sizeof(value);
1121 int width = 0;
1122 long val;
1124 mangled = dlang_number (mangled, &val);
1125 if (mangled == NULL)
1126 return NULL;
1128 string_append (decl, "'");
1130 if (type == 'a' && val >= 0x20 && val < 0x7F)
1132 /* Represent as a character literal. */
1133 char c = (char) val;
1134 string_appendn (decl, &c, 1);
1136 else
1138 /* Represent as a hexadecimal value. */
1139 switch (type)
1141 case 'a': /* char */
1142 string_append (decl, "\\x");
1143 width = 2;
1144 break;
1145 case 'u': /* wchar */
1146 string_append (decl, "\\u");
1147 width = 4;
1148 break;
1149 case 'w': /* dchar */
1150 string_append (decl, "\\U");
1151 width = 8;
1152 break;
1155 while (val > 0)
1157 int digit = val % 16;
1159 if (digit < 10)
1160 value[--pos] = (char)(digit + '0');
1161 else
1162 value[--pos] = (char)((digit - 10) + 'a');
1164 val /= 16;
1165 width--;
1168 for (; width > 0; width--)
1169 value[--pos] = '0';
1171 string_appendn (decl, &(value[pos]), sizeof(value) - pos);
1173 string_append (decl, "'");
1175 else if (type == 'b')
1177 /* Parse boolean value. */
1178 long val;
1180 mangled = dlang_number (mangled, &val);
1181 if (mangled == NULL)
1182 return NULL;
1184 string_append (decl, val ? "true" : "false");
1186 else
1188 /* Parse integer value. */
1189 const char *numptr = mangled;
1190 size_t num = 0;
1192 if (! ISDIGIT (*mangled))
1193 return NULL;
1195 while (ISDIGIT (*mangled))
1197 num++;
1198 mangled++;
1200 string_appendn (decl, numptr, num);
1202 /* Append suffix. */
1203 switch (type)
1205 case 'h': /* ubyte */
1206 case 't': /* ushort */
1207 case 'k': /* uint */
1208 string_append (decl, "u");
1209 break;
1210 case 'l': /* long */
1211 string_append (decl, "L");
1212 break;
1213 case 'm': /* ulong */
1214 string_append (decl, "uL");
1215 break;
1219 return mangled;
1222 /* Extract the floating-point value from MANGLED and append it to DECL.
1223 Return the remaining string on success or NULL on failure. */
1224 static const char *
1225 dlang_parse_real (string *decl, const char *mangled)
1227 /* Handle NAN and +-INF. */
1228 if (strncmp (mangled, "NAN", 3) == 0)
1230 string_append (decl, "NaN");
1231 mangled += 3;
1232 return mangled;
1234 else if (strncmp (mangled, "INF", 3) == 0)
1236 string_append (decl, "Inf");
1237 mangled += 3;
1238 return mangled;
1240 else if (strncmp (mangled, "NINF", 4) == 0)
1242 string_append (decl, "-Inf");
1243 mangled += 4;
1244 return mangled;
1247 /* Hexadecimal prefix and leading bit. */
1248 if (*mangled == 'N')
1250 string_append (decl, "-");
1251 mangled++;
1254 if (!ISXDIGIT (*mangled))
1255 return NULL;
1257 string_append (decl, "0x");
1258 string_appendn (decl, mangled, 1);
1259 string_append (decl, ".");
1260 mangled++;
1262 /* Significand. */
1263 while (ISXDIGIT (*mangled))
1265 string_appendn (decl, mangled, 1);
1266 mangled++;
1269 /* Exponent. */
1270 if (*mangled != 'P')
1271 return NULL;
1273 string_append (decl, "p");
1274 mangled++;
1276 if (*mangled == 'N')
1278 string_append (decl, "-");
1279 mangled++;
1282 while (ISDIGIT (*mangled))
1284 string_appendn (decl, mangled, 1);
1285 mangled++;
1288 return mangled;
1291 /* Extract the string value from MANGLED and append it to DECL.
1292 Return the remaining string on success or NULL on failure. */
1293 static const char *
1294 dlang_parse_string (string *decl, const char *mangled)
1296 char type = *mangled;
1297 long len;
1299 mangled++;
1300 mangled = dlang_number (mangled, &len);
1301 if (mangled == NULL || *mangled != '_')
1302 return NULL;
1304 mangled++;
1305 string_append (decl, "\"");
1306 while (len--)
1308 char val;
1309 const char *endptr = dlang_hexdigit (mangled, &val);
1311 if (endptr == NULL)
1312 return NULL;
1314 /* Sanitize white and non-printable characters. */
1315 switch (val)
1317 case ' ':
1318 string_append (decl, " ");
1319 break;
1320 case '\t':
1321 string_append (decl, "\\t");
1322 break;
1323 case '\n':
1324 string_append (decl, "\\n");
1325 break;
1326 case '\r':
1327 string_append (decl, "\\r");
1328 break;
1329 case '\f':
1330 string_append (decl, "\\f");
1331 break;
1332 case '\v':
1333 string_append (decl, "\\v");
1334 break;
1336 default:
1337 if (ISPRINT (val))
1338 string_appendn (decl, &val, 1);
1339 else
1341 string_append (decl, "\\x");
1342 string_appendn (decl, mangled, 2);
1346 mangled = endptr;
1348 string_append (decl, "\"");
1350 if (type != 'a')
1351 string_appendn (decl, &type, 1);
1353 return mangled;
1356 /* Extract the static array value from MANGLED and append it to DECL.
1357 Return the remaining string on success or NULL on failure. */
1358 static const char *
1359 dlang_parse_arrayliteral (string *decl, const char *mangled)
1361 long elements;
1363 mangled = dlang_number (mangled, &elements);
1364 if (mangled == NULL)
1365 return NULL;
1367 string_append (decl, "[");
1368 while (elements--)
1370 mangled = dlang_value (decl, mangled, NULL, '\0');
1371 if (mangled == NULL)
1372 return NULL;
1374 if (elements != 0)
1375 string_append (decl, ", ");
1378 string_append (decl, "]");
1379 return mangled;
1382 /* Extract the associative array value from MANGLED and append it to DECL.
1383 Return the remaining string on success or NULL on failure. */
1384 static const char *
1385 dlang_parse_assocarray (string *decl, const char *mangled)
1387 long elements;
1389 mangled = dlang_number (mangled, &elements);
1390 if (mangled == NULL)
1391 return NULL;
1393 string_append (decl, "[");
1394 while (elements--)
1396 mangled = dlang_value (decl, mangled, NULL, '\0');
1397 if (mangled == NULL)
1398 return NULL;
1400 string_append (decl, ":");
1401 mangled = dlang_value (decl, mangled, NULL, '\0');
1402 if (mangled == NULL)
1403 return NULL;
1405 if (elements != 0)
1406 string_append (decl, ", ");
1409 string_append (decl, "]");
1410 return mangled;
1413 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1414 Return the remaining string on success or NULL on failure. */
1415 static const char *
1416 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1418 long args;
1420 mangled = dlang_number (mangled, &args);
1421 if (mangled == NULL)
1422 return NULL;
1424 if (name != NULL)
1425 string_append (decl, name);
1427 string_append (decl, "(");
1428 while (args--)
1430 mangled = dlang_value (decl, mangled, NULL, '\0');
1431 if (mangled == NULL)
1432 return NULL;
1434 if (args != 0)
1435 string_append (decl, ", ");
1438 string_append (decl, ")");
1439 return mangled;
1442 /* Extract the value from MANGLED and append it to DECL.
1443 Return the remaining string on success or NULL on failure. */
1444 static const char *
1445 dlang_value (string *decl, const char *mangled, const char *name, char type)
1447 if (mangled == NULL || *mangled == '\0')
1448 return NULL;
1450 switch (*mangled)
1452 /* Null value. */
1453 case 'n':
1454 mangled++;
1455 string_append (decl, "null");
1456 break;
1458 /* Integral values. */
1459 case 'N':
1460 mangled++;
1461 string_append (decl, "-");
1462 mangled = dlang_parse_integer (decl, mangled, type);
1463 break;
1465 case 'i':
1466 mangled++;
1467 /* Fall through */
1469 /* There really should always be an `i' before encoded numbers, but there
1470 wasn't in early versions of D2, so this case range must remain for
1471 backwards compatibility. */
1472 case '0': case '1': case '2': case '3': case '4':
1473 case '5': case '6': case '7': case '8': case '9':
1474 mangled = dlang_parse_integer (decl, mangled, type);
1475 break;
1477 /* Real value. */
1478 case 'e':
1479 mangled++;
1480 mangled = dlang_parse_real (decl, mangled);
1481 break;
1483 /* Complex value. */
1484 case 'c':
1485 mangled++;
1486 mangled = dlang_parse_real (decl, mangled);
1487 string_append (decl, "+");
1488 if (mangled == NULL || *mangled != 'c')
1489 return NULL;
1490 mangled++;
1491 mangled = dlang_parse_real (decl, mangled);
1492 string_append (decl, "i");
1493 break;
1495 /* String values. */
1496 case 'a': /* UTF8 */
1497 case 'w': /* UTF16 */
1498 case 'd': /* UTF32 */
1499 mangled = dlang_parse_string (decl, mangled);
1500 break;
1502 /* Array values. */
1503 case 'A':
1504 mangled++;
1505 if (type == 'H')
1506 mangled = dlang_parse_assocarray (decl, mangled);
1507 else
1508 mangled = dlang_parse_arrayliteral (decl, mangled);
1509 break;
1511 /* Struct values. */
1512 case 'S':
1513 mangled++;
1514 mangled = dlang_parse_structlit (decl, mangled, name);
1515 break;
1517 default:
1518 return NULL;
1521 return mangled;
1524 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1525 Returns the remaining signature on success or NULL on failure. */
1526 static const char *
1527 dlang_parse_mangle (string *decl, const char *mangled, struct dlang_info *info)
1529 /* A D mangled symbol is comprised of both scope and type information.
1531 MangleName:
1532 _D QualifiedName Type
1533 _D QualifiedName Z
1535 The caller should have guaranteed that the start pointer is at the
1536 above location.
1537 Note that type is never a function type, but only the return type of
1538 a function or the type of a variable.
1540 mangled += 2;
1542 mangled = dlang_parse_qualified (decl, mangled, info, 1);
1544 if (mangled != NULL)
1546 /* Artificial symbols end with 'Z' and have no type. */
1547 if (*mangled == 'Z')
1548 mangled++;
1549 else
1551 /* Discard the declaration or return type. */
1552 string type;
1554 string_init (&type);
1555 mangled = dlang_type (&type, mangled, info);
1556 string_delete (&type);
1560 return mangled;
1563 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1564 SUFFIX_MODIFIERS is 1 if we are printing modifiers on this after the symbol.
1565 Returns the remaining signature on success or NULL on failure. */
1566 static const char *
1567 dlang_parse_qualified (string *decl, const char *mangled,
1568 struct dlang_info *info, int suffix_modifiers)
1570 /* Qualified names are identifiers separated by their encoded length.
1571 Nested functions also encode their argument types without specifying
1572 what they return.
1574 QualifiedName:
1575 SymbolFunctionName
1576 SymbolFunctionName QualifiedName
1579 SymbolFunctionName:
1580 SymbolName
1581 SymbolName TypeFunctionNoReturn
1582 SymbolName M TypeFunctionNoReturn
1583 SymbolName M TypeModifiers TypeFunctionNoReturn
1585 The start pointer should be at the above location.
1587 size_t n = 0;
1590 if (n++)
1591 string_append (decl, ".");
1593 /* Skip over anonymous symbols. */
1594 while (*mangled == '0')
1595 mangled++;
1597 mangled = dlang_identifier (decl, mangled, info);
1599 /* Consume the encoded arguments. However if this is not followed by the
1600 next encoded length or mangle type, then this is not a continuation of
1601 a qualified name, in which case we backtrack and return the current
1602 unconsumed position of the mangled decl. */
1603 if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1605 string mods;
1606 const char *start = mangled;
1607 int saved = string_length (decl);
1609 /* Save the type modifiers for appending at the end if needed. */
1610 string_init (&mods);
1612 /* Skip over 'this' parameter and type modifiers. */
1613 if (*mangled == 'M')
1615 mangled++;
1616 mangled = dlang_type_modifiers (&mods, mangled);
1617 string_setlength (decl, saved);
1620 mangled = dlang_function_type_noreturn (decl, NULL, NULL,
1621 mangled, info);
1622 if (suffix_modifiers)
1623 string_appendn (decl, mods.b, string_length (&mods));
1625 if (mangled == NULL || *mangled == '\0')
1627 /* Did not match the rule we were looking for. */
1628 mangled = start;
1629 string_setlength (decl, saved);
1632 string_delete (&mods);
1635 while (mangled && dlang_symbol_name_p (mangled, info));
1637 return mangled;
1640 /* Demangle the tuple from MANGLED and append it to DECL.
1641 Return the remaining string on success or NULL on failure. */
1642 static const char *
1643 dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info)
1645 long elements;
1647 mangled = dlang_number (mangled, &elements);
1648 if (mangled == NULL)
1649 return NULL;
1651 string_append (decl, "Tuple!(");
1653 while (elements--)
1655 mangled = dlang_type (decl, mangled, info);
1656 if (mangled == NULL)
1657 return NULL;
1659 if (elements != 0)
1660 string_append (decl, ", ");
1663 string_append (decl, ")");
1664 return mangled;
1667 /* Demangle the template symbol parameter from MANGLED and append it to DECL.
1668 Return the remaining string on success or NULL on failure. */
1669 static const char *
1670 dlang_template_symbol_param (string *decl, const char *mangled,
1671 struct dlang_info *info)
1673 if (strncmp (mangled, "_D", 2) == 0
1674 && dlang_symbol_name_p (mangled + 2, info))
1675 return dlang_parse_mangle (decl, mangled, info);
1677 if (*mangled == 'Q')
1678 return dlang_parse_qualified (decl, mangled, info, 0);
1680 long len;
1681 const char *endptr = dlang_number (mangled, &len);
1683 if (endptr == NULL || len == 0)
1684 return NULL;
1686 /* In template parameter symbols generated by the frontend up to 2.076,
1687 the symbol length is encoded and the first character of the mangled
1688 name can be a digit. This causes ambiguity issues because the digits
1689 of the two numbers are adjacent. */
1690 long psize = len;
1691 const char *pend;
1692 int saved = string_length (decl);
1694 /* Work backwards until a match is found. */
1695 for (pend = endptr; endptr != NULL; pend--)
1697 mangled = pend;
1699 /* Reached the beginning of the pointer to the name length,
1700 try parsing the entire symbol. */
1701 if (psize == 0)
1703 psize = len;
1704 pend = endptr;
1705 endptr = NULL;
1708 /* Check whether template parameter is a function with a valid
1709 return type or an untyped identifier. */
1710 if (dlang_symbol_name_p (mangled, info))
1711 mangled = dlang_parse_qualified (decl, mangled, info, 0);
1712 else if (strncmp (mangled, "_D", 2) == 0
1713 && dlang_symbol_name_p (mangled + 2, info))
1714 mangled = dlang_parse_mangle (decl, mangled, info);
1716 /* Check for name length mismatch. */
1717 if (mangled && (endptr == NULL || (mangled - pend) == psize))
1718 return mangled;
1720 psize /= 10;
1721 string_setlength (decl, saved);
1724 /* No match on any combinations. */
1725 return NULL;
1728 /* Demangle the argument list from MANGLED and append it to DECL.
1729 Return the remaining string on success or NULL on failure. */
1730 static const char *
1731 dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
1733 size_t n = 0;
1735 while (mangled && *mangled != '\0')
1737 switch (*mangled)
1739 case 'Z': /* End of parameter list. */
1740 mangled++;
1741 return mangled;
1744 if (n++)
1745 string_append (decl, ", ");
1747 /* Skip over specialised template prefix. */
1748 if (*mangled == 'H')
1749 mangled++;
1751 switch (*mangled)
1753 case 'S': /* Symbol parameter. */
1754 mangled++;
1755 mangled = dlang_template_symbol_param (decl, mangled, info);
1756 break;
1757 case 'T': /* Type parameter. */
1758 mangled++;
1759 mangled = dlang_type (decl, mangled, info);
1760 break;
1761 case 'V': /* Value parameter. */
1763 string name;
1764 char type;
1766 /* Peek at the type. */
1767 mangled++;
1768 type = *mangled;
1770 if (type == 'Q')
1772 /* Value type is a back reference, peek at the real type. */
1773 const char *backref;
1774 if (dlang_backref (mangled, &backref, info) == NULL)
1775 return NULL;
1777 type = *backref;
1780 /* In the few instances where the type is actually desired in
1781 the output, it should precede the value from dlang_value. */
1782 string_init (&name);
1783 mangled = dlang_type (&name, mangled, info);
1784 string_need (&name, 1);
1785 *(name.p) = '\0';
1787 mangled = dlang_value (decl, mangled, name.b, type);
1788 string_delete (&name);
1789 break;
1791 case 'X': /* Externally mangled parameter. */
1793 long len;
1794 const char *endptr;
1796 mangled++;
1797 endptr = dlang_number (mangled, &len);
1798 if (endptr == NULL || strlen (endptr) < (size_t) len)
1799 return NULL;
1801 string_appendn (decl, endptr, len);
1802 mangled = endptr + len;
1803 break;
1805 default:
1806 return NULL;
1810 return mangled;
1813 /* Extract and demangle the template symbol in MANGLED, expected to
1814 be made up of LEN characters (-1 if unknown), and append it to DECL.
1815 Returns the remaining signature on success or NULL on failure. */
1816 static const char *
1817 dlang_parse_template (string *decl, const char *mangled,
1818 struct dlang_info *info, long len)
1820 const char *start = mangled;
1821 string args;
1823 /* Template instance names have the types and values of its parameters
1824 encoded into it.
1826 TemplateInstanceName:
1827 Number __T LName TemplateArgs Z
1828 Number __U LName TemplateArgs Z
1830 The start pointer should be at the above location, and LEN should be
1831 the value of the decoded number.
1834 /* Template symbol. */
1835 if (!dlang_symbol_name_p (mangled + 3, info) || mangled[3] == '0')
1836 return NULL;
1838 mangled += 3;
1840 /* Template identifier. */
1841 mangled = dlang_identifier (decl, mangled, info);
1843 /* Template arguments. */
1844 string_init (&args);
1845 mangled = dlang_template_args (&args, mangled, info);
1847 string_append (decl, "!(");
1848 string_appendn (decl, args.b, string_length (&args));
1849 string_append (decl, ")");
1851 string_delete (&args);
1853 /* Check for template name length mismatch. */
1854 if (len != TEMPLATE_LENGTH_UNKNOWN && mangled && (mangled - start) != len)
1855 return NULL;
1857 return mangled;
1860 /* Initialize the information structure we use to pass around information. */
1861 static void
1862 dlang_demangle_init_info (const char *mangled, int last_backref,
1863 struct dlang_info *info)
1865 info->s = mangled;
1866 info->last_backref = last_backref;
1869 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1870 signature on success or NULL on failure. */
1872 char *
1873 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1875 string decl;
1876 char *demangled = NULL;
1878 if (mangled == NULL || *mangled == '\0')
1879 return NULL;
1881 if (strncmp (mangled, "_D", 2) != 0)
1882 return NULL;
1884 string_init (&decl);
1886 if (strcmp (mangled, "_Dmain") == 0)
1888 string_append (&decl, "D main");
1890 else
1892 struct dlang_info info;
1894 dlang_demangle_init_info (mangled, strlen (mangled), &info);
1895 mangled = dlang_parse_mangle (&decl, mangled, &info);
1897 /* Check that the entire symbol was successfully demangled. */
1898 if (mangled == NULL || *mangled != '\0')
1899 string_delete (&decl);
1902 if (string_length (&decl) > 0)
1904 string_need (&decl, 1);
1905 *(decl.p) = '\0';
1906 demangled = decl.b;
1909 return demangled;