c++: _Complex template parameter [PR100634]
[official-gcc.git] / libiberty / d-demangle.c
blob822c7580782742bba534328e6f8bfbf47df01a65
1 /* Demangler for the D programming language
2 Copyright (C) 2014-2021 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
34 #ifdef HAVE_LIMITS_H
35 #include <limits.h>
36 #endif
38 #include "safe-ctype.h"
40 #include <sys/types.h>
41 #include <string.h>
42 #include <stdio.h>
44 #ifdef HAVE_STDLIB_H
45 #include <stdlib.h>
46 #endif
48 #include <demangle.h>
49 #include "libiberty.h"
51 #ifndef ULONG_MAX
52 #define ULONG_MAX (~0UL)
53 #endif
54 #ifndef UINT_MAX
55 #define UINT_MAX (~0U)
56 #endif
58 /* A mini string-handling package */
60 typedef struct string /* Beware: these aren't required to be */
61 { /* '\0' terminated. */
62 char *b; /* pointer to start of string */
63 char *p; /* pointer after last character */
64 char *e; /* pointer after end of allocated space */
65 } string;
67 static void
68 string_need (string *s, size_t n)
70 size_t tem;
72 if (s->b == NULL)
74 if (n < 32)
76 n = 32;
78 s->p = s->b = XNEWVEC (char, n);
79 s->e = s->b + n;
81 else if ((size_t) (s->e - s->p) < n)
83 tem = s->p - s->b;
84 n += tem;
85 n *= 2;
86 s->b = XRESIZEVEC (char, s->b, n);
87 s->p = s->b + tem;
88 s->e = s->b + n;
92 static void
93 string_delete (string *s)
95 if (s->b != NULL)
97 XDELETEVEC (s->b);
98 s->b = s->e = s->p = NULL;
102 static void
103 string_init (string *s)
105 s->b = s->p = s->e = NULL;
108 static int
109 string_length (string *s)
111 if (s->p == s->b)
113 return 0;
115 return s->p - s->b;
118 static void
119 string_setlength (string *s, int n)
121 if (n - string_length (s) < 0)
123 s->p = s->b + n;
127 static void
128 string_append (string *p, const char *s)
130 size_t n = strlen (s);
131 string_need (p, n);
132 memcpy (p->p, s, n);
133 p->p += n;
136 static void
137 string_appendn (string *p, const char *s, size_t n)
139 if (n != 0)
141 string_need (p, n);
142 memcpy (p->p, s, n);
143 p->p += n;
147 static void
148 string_prependn (string *p, const char *s, size_t n)
150 char *q;
152 if (n != 0)
154 string_need (p, n);
155 for (q = p->p - 1; q >= p->b; q--)
157 q[n] = q[0];
159 memcpy (p->b, s, n);
160 p->p += n;
164 static void
165 string_prepend (string *p, const char *s)
167 if (s != NULL && *s != '\0')
169 string_prependn (p, s, strlen (s));
173 /* Demangle information structure we pass around. */
174 struct dlang_info
176 /* The string we are demangling. */
177 const char *s;
178 /* The index of the last back reference. */
179 int last_backref;
182 /* Pass as the LEN to dlang_parse_template if symbol length is not known. */
183 #define TEMPLATE_LENGTH_UNKNOWN (-1UL)
185 /* Prototypes for forward referenced functions */
186 static const char *dlang_function_type (string *, const char *,
187 struct dlang_info *);
189 static const char *dlang_function_args (string *, const char *,
190 struct dlang_info *);
192 static const char *dlang_type (string *, const char *, struct dlang_info *);
194 static const char *dlang_value (string *, const char *, const char *, char);
196 static const char *dlang_parse_qualified (string *, const char *,
197 struct dlang_info *, int);
199 static const char *dlang_parse_mangle (string *, const char *,
200 struct dlang_info *);
202 static const char *dlang_parse_tuple (string *, const char *,
203 struct dlang_info *);
205 static const char *dlang_parse_template (string *, const char *,
206 struct dlang_info *, unsigned long);
208 static const char *dlang_lname (string *, const char *, unsigned long);
211 /* Extract the number from MANGLED, and assign the result to RET.
212 Return the remaining string on success or NULL on failure.
213 A result larger than UINT_MAX is considered a failure. */
214 static const char *
215 dlang_number (const char *mangled, unsigned long *ret)
217 /* Return NULL if trying to extract something that isn't a digit. */
218 if (mangled == NULL || !ISDIGIT (*mangled))
219 return NULL;
221 unsigned long val = 0;
223 while (ISDIGIT (*mangled))
225 unsigned long digit = mangled[0] - '0';
227 /* Check for overflow. */
228 if (val > (UINT_MAX - digit) / 10)
229 return NULL;
231 val = val * 10 + digit;
232 mangled++;
235 if (*mangled == '\0')
236 return NULL;
238 *ret = val;
239 return mangled;
242 /* Extract the hex-digit from MANGLED, and assign the result to RET.
243 Return the remaining string on success or NULL on failure. */
244 static const char *
245 dlang_hexdigit (const char *mangled, char *ret)
247 char c;
249 /* Return NULL if trying to extract something that isn't a hexdigit. */
250 if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1]))
251 return NULL;
253 c = mangled[0];
254 if (!ISDIGIT (c))
255 (*ret) = (c - (ISUPPER (c) ? 'A' : 'a') + 10);
256 else
257 (*ret) = (c - '0');
259 c = mangled[1];
260 if (!ISDIGIT (c))
261 (*ret) = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
262 else
263 (*ret) = (*ret << 4) | (c - '0');
265 mangled += 2;
267 return mangled;
270 /* Extract the function calling convention from MANGLED and
271 return 1 on success or 0 on failure. */
272 static int
273 dlang_call_convention_p (const char *mangled)
275 switch (*mangled)
277 case 'F': case 'U': case 'V':
278 case 'W': case 'R': case 'Y':
279 return 1;
281 default:
282 return 0;
286 /* Extract the back reference position from MANGLED, and assign the result
287 to RET. Return the remaining string on success or NULL on failure.
288 A result <= 0 is a failure. */
289 static const char *
290 dlang_decode_backref (const char *mangled, long *ret)
292 /* Return NULL if trying to extract something that isn't a digit. */
293 if (mangled == NULL || !ISALPHA (*mangled))
294 return NULL;
296 /* Any identifier or non-basic type that has been emitted to the mangled
297 symbol before will not be emitted again, but is referenced by a special
298 sequence encoding the relative position of the original occurrence in the
299 mangled symbol name.
301 Numbers in back references are encoded with base 26 by upper case letters
302 A-Z for higher digits but lower case letters a-z for the last digit.
304 NumberBackRef:
305 [a-z]
306 [A-Z] NumberBackRef
309 unsigned long val = 0;
311 while (ISALPHA (*mangled))
313 /* Check for overflow. */
314 if (val > (ULONG_MAX - 25) / 26)
315 break;
317 val *= 26;
319 if (mangled[0] >= 'a' && mangled[0] <= 'z')
321 val += mangled[0] - 'a';
322 if ((long) val <= 0)
323 break;
324 *ret = val;
325 return mangled + 1;
328 val += mangled[0] - 'A';
329 mangled++;
332 return NULL;
335 /* Extract the symbol pointed at by the back reference and assign the result
336 to RET. Return the remaining string on success or NULL on failure. */
337 static const char *
338 dlang_backref (const char *mangled, const char **ret, struct dlang_info *info)
340 (*ret) = NULL;
342 if (mangled == NULL || *mangled != 'Q')
343 return NULL;
345 /* Position of 'Q'. */
346 const char *qpos = mangled;
347 long refpos;
348 mangled++;
350 mangled = dlang_decode_backref (mangled, &refpos);
351 if (mangled == NULL)
352 return NULL;
354 if (refpos > qpos - info->s)
355 return NULL;
357 /* Set the position of the back reference. */
358 (*ret) = qpos - refpos;
360 return mangled;
363 /* Demangle a back referenced symbol from MANGLED and append it to DECL.
364 Return the remaining string on success or NULL on failure. */
365 static const char *
366 dlang_symbol_backref (string *decl, const char *mangled,
367 struct dlang_info *info)
369 /* An identifier back reference always points to a digit 0 to 9.
371 IdentifierBackRef:
372 Q NumberBackRef
375 const char *backref;
376 unsigned long len;
378 /* Get position of the back reference. */
379 mangled = dlang_backref (mangled, &backref, info);
381 /* Must point to a simple identifier. */
382 backref = dlang_number (backref, &len);
383 if (backref == NULL)
384 return NULL;
386 backref = dlang_lname (decl, backref, len);
387 if (backref == NULL)
388 return NULL;
390 return mangled;
393 /* Demangle a back referenced type from MANGLED and append it to DECL.
394 IS_FUNCTION is 1 if the back referenced type is expected to be a function.
395 Return the remaining string on success or NULL on failure. */
396 static const char *
397 dlang_type_backref (string *decl, const char *mangled, struct dlang_info *info,
398 int is_function)
400 /* A type back reference always points to a letter.
402 TypeBackRef:
403 Q NumberBackRef
406 const char *backref;
408 /* If we appear to be moving backwards through the mangle string, then
409 bail as this may be a recursive back reference. */
410 if (mangled - info->s >= info->last_backref)
411 return NULL;
413 int save_refpos = info->last_backref;
414 info->last_backref = mangled - info->s;
416 /* Get position of the back reference. */
417 mangled = dlang_backref (mangled, &backref, info);
419 /* Must point to a type. */
420 if (is_function)
421 backref = dlang_function_type (decl, backref, info);
422 else
423 backref = dlang_type (decl, backref, info);
425 info->last_backref = save_refpos;
427 if (backref == NULL)
428 return NULL;
430 return mangled;
433 /* Extract the beginning of a symbol name from MANGLED and
434 return 1 on success or 0 on failure. */
435 static int
436 dlang_symbol_name_p (const char *mangled, struct dlang_info *info)
438 long ret;
439 const char *qref = mangled;
441 if (ISDIGIT (*mangled))
442 return 1;
444 if (mangled[0] == '_' && mangled[1] == '_'
445 && (mangled[2] == 'T' || mangled[2] == 'U'))
446 return 1;
448 if (*mangled != 'Q')
449 return 0;
451 mangled = dlang_decode_backref (mangled + 1, &ret);
452 if (mangled == NULL || ret > qref - info->s)
453 return 0;
455 return ISDIGIT (qref[-ret]);
458 /* Demangle the calling convention from MANGLED and append it to DECL.
459 Return the remaining string on success or NULL on failure. */
460 static const char *
461 dlang_call_convention (string *decl, const char *mangled)
463 if (mangled == NULL || *mangled == '\0')
464 return NULL;
466 switch (*mangled)
468 case 'F': /* (D) */
469 mangled++;
470 break;
471 case 'U': /* (C) */
472 mangled++;
473 string_append (decl, "extern(C) ");
474 break;
475 case 'W': /* (Windows) */
476 mangled++;
477 string_append (decl, "extern(Windows) ");
478 break;
479 case 'V': /* (Pascal) */
480 mangled++;
481 string_append (decl, "extern(Pascal) ");
482 break;
483 case 'R': /* (C++) */
484 mangled++;
485 string_append (decl, "extern(C++) ");
486 break;
487 case 'Y': /* (Objective-C) */
488 mangled++;
489 string_append (decl, "extern(Objective-C) ");
490 break;
491 default:
492 return NULL;
495 return mangled;
498 /* Extract the type modifiers from MANGLED and append them to DECL.
499 Returns the remaining signature on success or NULL on failure. */
500 static const char *
501 dlang_type_modifiers (string *decl, const char *mangled)
503 if (mangled == NULL || *mangled == '\0')
504 return NULL;
506 switch (*mangled)
508 case 'x': /* const */
509 mangled++;
510 string_append (decl, " const");
511 return mangled;
512 case 'y': /* immutable */
513 mangled++;
514 string_append (decl, " immutable");
515 return mangled;
516 case 'O': /* shared */
517 mangled++;
518 string_append (decl, " shared");
519 return dlang_type_modifiers (decl, mangled);
520 case 'N':
521 mangled++;
522 if (*mangled == 'g') /* wild */
524 mangled++;
525 string_append (decl, " inout");
526 return dlang_type_modifiers (decl, mangled);
528 else
529 return NULL;
531 default:
532 return mangled;
536 /* Demangle the D function attributes from MANGLED and append it to DECL.
537 Return the remaining string on success or NULL on failure. */
538 static const char *
539 dlang_attributes (string *decl, const char *mangled)
541 if (mangled == NULL || *mangled == '\0')
542 return NULL;
544 while (*mangled == 'N')
546 mangled++;
547 switch (*mangled)
549 case 'a': /* pure */
550 mangled++;
551 string_append (decl, "pure ");
552 continue;
553 case 'b': /* nothrow */
554 mangled++;
555 string_append (decl, "nothrow ");
556 continue;
557 case 'c': /* ref */
558 mangled++;
559 string_append (decl, "ref ");
560 continue;
561 case 'd': /* @property */
562 mangled++;
563 string_append (decl, "@property ");
564 continue;
565 case 'e': /* @trusted */
566 mangled++;
567 string_append (decl, "@trusted ");
568 continue;
569 case 'f': /* @safe */
570 mangled++;
571 string_append (decl, "@safe ");
572 continue;
573 case 'g':
574 case 'h':
575 case 'k':
576 /* inout parameter is represented as 'Ng'.
577 vector parameter is represented as 'Nh'.
578 return paramenter is represented as 'Nk'.
579 If we see this, then we know we're really in the
580 parameter list. Rewind and break. */
581 mangled--;
582 break;
583 case 'i': /* @nogc */
584 mangled++;
585 string_append (decl, "@nogc ");
586 continue;
587 case 'j': /* return */
588 mangled++;
589 string_append (decl, "return ");
590 continue;
591 case 'l': /* scope */
592 mangled++;
593 string_append (decl, "scope ");
594 continue;
595 case 'm': /* @live */
596 mangled++;
597 string_append (decl, "@live ");
598 continue;
600 default: /* unknown attribute */
601 return NULL;
603 break;
606 return mangled;
609 /* Demangle the function type from MANGLED without the return type.
610 The arguments are appended to ARGS, the calling convention is appended
611 to CALL and attributes are appended to ATTR. Any of these can be NULL
612 to throw the information away. Return the remaining string on success
613 or NULL on failure. */
614 static const char *
615 dlang_function_type_noreturn (string *args, string *call, string *attr,
616 const char *mangled, struct dlang_info *info)
618 string dump;
619 string_init (&dump);
621 /* Skip over calling convention and attributes. */
622 mangled = dlang_call_convention (call ? call : &dump, mangled);
623 mangled = dlang_attributes (attr ? attr : &dump, mangled);
625 if (args)
626 string_append (args, "(");
628 mangled = dlang_function_args (args ? args : &dump, mangled, info);
629 if (args)
630 string_append (args, ")");
632 string_delete (&dump);
633 return mangled;
636 /* Demangle the function type from MANGLED and append it to DECL.
637 Return the remaining string on success or NULL on failure. */
638 static const char *
639 dlang_function_type (string *decl, const char *mangled, struct dlang_info *info)
641 string attr, args, type;
643 if (mangled == NULL || *mangled == '\0')
644 return NULL;
646 /* The order of the mangled string is:
647 CallConvention FuncAttrs Arguments ArgClose Type
649 The demangled string is re-ordered as:
650 CallConvention Type Arguments FuncAttrs
652 string_init (&attr);
653 string_init (&args);
654 string_init (&type);
656 mangled = dlang_function_type_noreturn (&args, decl, &attr, mangled, info);
658 /* Function return type. */
659 mangled = dlang_type (&type, mangled, info);
661 /* Append to decl in order. */
662 string_appendn (decl, type.b, string_length (&type));
663 string_appendn (decl, args.b, string_length (&args));
664 string_append (decl, " ");
665 string_appendn (decl, attr.b, string_length (&attr));
667 string_delete (&attr);
668 string_delete (&args);
669 string_delete (&type);
670 return mangled;
673 /* Demangle the argument list from MANGLED and append it to DECL.
674 Return the remaining string on success or NULL on failure. */
675 static const char *
676 dlang_function_args (string *decl, const char *mangled, struct dlang_info *info)
678 size_t n = 0;
680 while (mangled && *mangled != '\0')
682 switch (*mangled)
684 case 'X': /* (variadic T t...) style. */
685 mangled++;
686 string_append (decl, "...");
687 return mangled;
688 case 'Y': /* (variadic T t, ...) style. */
689 mangled++;
690 if (n != 0)
691 string_append (decl, ", ");
692 string_append (decl, "...");
693 return mangled;
694 case 'Z': /* Normal function. */
695 mangled++;
696 return mangled;
699 if (n++)
700 string_append (decl, ", ");
702 if (*mangled == 'M') /* scope(T) */
704 mangled++;
705 string_append (decl, "scope ");
708 if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
710 mangled += 2;
711 string_append (decl, "return ");
714 switch (*mangled)
716 case 'I': /* in(T) */
717 mangled++;
718 string_append (decl, "in ");
719 if (*mangled == 'K') /* in ref(T) */
721 mangled++;
722 string_append (decl, "ref ");
724 break;
725 case 'J': /* out(T) */
726 mangled++;
727 string_append (decl, "out ");
728 break;
729 case 'K': /* ref(T) */
730 mangled++;
731 string_append (decl, "ref ");
732 break;
733 case 'L': /* lazy(T) */
734 mangled++;
735 string_append (decl, "lazy ");
736 break;
738 mangled = dlang_type (decl, mangled, info);
741 return mangled;
744 /* Demangle the type from MANGLED and append it to DECL.
745 Return the remaining string on success or NULL on failure. */
746 static const char *
747 dlang_type (string *decl, const char *mangled, struct dlang_info *info)
749 if (mangled == NULL || *mangled == '\0')
750 return NULL;
752 switch (*mangled)
754 case 'O': /* shared(T) */
755 mangled++;
756 string_append (decl, "shared(");
757 mangled = dlang_type (decl, mangled, info);
758 string_append (decl, ")");
759 return mangled;
760 case 'x': /* const(T) */
761 mangled++;
762 string_append (decl, "const(");
763 mangled = dlang_type (decl, mangled, info);
764 string_append (decl, ")");
765 return mangled;
766 case 'y': /* immutable(T) */
767 mangled++;
768 string_append (decl, "immutable(");
769 mangled = dlang_type (decl, mangled, info);
770 string_append (decl, ")");
771 return mangled;
772 case 'N':
773 mangled++;
774 if (*mangled == 'g') /* wild(T) */
776 mangled++;
777 string_append (decl, "inout(");
778 mangled = dlang_type (decl, mangled, info);
779 string_append (decl, ")");
780 return mangled;
782 else if (*mangled == 'h') /* vector(T) */
784 mangled++;
785 string_append (decl, "__vector(");
786 mangled = dlang_type (decl, mangled, info);
787 string_append (decl, ")");
788 return mangled;
790 else
791 return NULL;
792 case 'A': /* dynamic array (T[]) */
793 mangled++;
794 mangled = dlang_type (decl, mangled, info);
795 string_append (decl, "[]");
796 return mangled;
797 case 'G': /* static array (T[N]) */
799 const char *numptr;
800 size_t num = 0;
801 mangled++;
803 numptr = mangled;
804 while (ISDIGIT (*mangled))
806 num++;
807 mangled++;
809 mangled = dlang_type (decl, mangled, info);
810 string_append (decl, "[");
811 string_appendn (decl, numptr, num);
812 string_append (decl, "]");
813 return mangled;
815 case 'H': /* associative array (T[T]) */
817 string type;
818 size_t sztype;
819 mangled++;
821 string_init (&type);
822 mangled = dlang_type (&type, mangled, info);
823 sztype = string_length (&type);
825 mangled = dlang_type (decl, mangled, info);
826 string_append (decl, "[");
827 string_appendn (decl, type.b, sztype);
828 string_append (decl, "]");
830 string_delete (&type);
831 return mangled;
833 case 'P': /* pointer (T*) */
834 mangled++;
835 if (!dlang_call_convention_p (mangled))
837 mangled = dlang_type (decl, mangled, info);
838 string_append (decl, "*");
839 return mangled;
841 /* Fall through */
842 case 'F': /* function T (D) */
843 case 'U': /* function T (C) */
844 case 'W': /* function T (Windows) */
845 case 'V': /* function T (Pascal) */
846 case 'R': /* function T (C++) */
847 case 'Y': /* function T (Objective-C) */
848 /* Function pointer types don't include the trailing asterisk. */
849 mangled = dlang_function_type (decl, mangled, info);
850 string_append (decl, "function");
851 return mangled;
852 case 'C': /* class T */
853 case 'S': /* struct T */
854 case 'E': /* enum T */
855 case 'T': /* typedef T */
856 mangled++;
857 return dlang_parse_qualified (decl, mangled, info, 0);
858 case 'D': /* delegate T */
860 string mods;
861 size_t szmods;
862 mangled++;
864 string_init (&mods);
865 mangled = dlang_type_modifiers (&mods, mangled);
866 szmods = string_length (&mods);
868 /* Back referenced function type. */
869 if (*mangled == 'Q')
870 mangled = dlang_type_backref (decl, mangled, info, 1);
871 else
872 mangled = dlang_function_type (decl, mangled, info);
874 string_append (decl, "delegate");
875 string_appendn (decl, mods.b, szmods);
877 string_delete (&mods);
878 return mangled;
880 case 'B': /* tuple T */
881 mangled++;
882 return dlang_parse_tuple (decl, mangled, info);
884 /* Basic types */
885 case 'n':
886 mangled++;
887 string_append (decl, "none");
888 return mangled;
889 case 'v':
890 mangled++;
891 string_append (decl, "void");
892 return mangled;
893 case 'g':
894 mangled++;
895 string_append (decl, "byte");
896 return mangled;
897 case 'h':
898 mangled++;
899 string_append (decl, "ubyte");
900 return mangled;
901 case 's':
902 mangled++;
903 string_append (decl, "short");
904 return mangled;
905 case 't':
906 mangled++;
907 string_append (decl, "ushort");
908 return mangled;
909 case 'i':
910 mangled++;
911 string_append (decl, "int");
912 return mangled;
913 case 'k':
914 mangled++;
915 string_append (decl, "uint");
916 return mangled;
917 case 'l':
918 mangled++;
919 string_append (decl, "long");
920 return mangled;
921 case 'm':
922 mangled++;
923 string_append (decl, "ulong");
924 return mangled;
925 case 'f':
926 mangled++;
927 string_append (decl, "float");
928 return mangled;
929 case 'd':
930 mangled++;
931 string_append (decl, "double");
932 return mangled;
933 case 'e':
934 mangled++;
935 string_append (decl, "real");
936 return mangled;
938 /* Imaginary and Complex types */
939 case 'o':
940 mangled++;
941 string_append (decl, "ifloat");
942 return mangled;
943 case 'p':
944 mangled++;
945 string_append (decl, "idouble");
946 return mangled;
947 case 'j':
948 mangled++;
949 string_append (decl, "ireal");
950 return mangled;
951 case 'q':
952 mangled++;
953 string_append (decl, "cfloat");
954 return mangled;
955 case 'r':
956 mangled++;
957 string_append (decl, "cdouble");
958 return mangled;
959 case 'c':
960 mangled++;
961 string_append (decl, "creal");
962 return mangled;
964 /* Other types */
965 case 'b':
966 mangled++;
967 string_append (decl, "bool");
968 return mangled;
969 case 'a':
970 mangled++;
971 string_append (decl, "char");
972 return mangled;
973 case 'u':
974 mangled++;
975 string_append (decl, "wchar");
976 return mangled;
977 case 'w':
978 mangled++;
979 string_append (decl, "dchar");
980 return mangled;
981 case 'z':
982 mangled++;
983 switch (*mangled)
985 case 'i':
986 mangled++;
987 string_append (decl, "cent");
988 return mangled;
989 case 'k':
990 mangled++;
991 string_append (decl, "ucent");
992 return mangled;
994 return NULL;
996 /* Back referenced type. */
997 case 'Q':
998 return dlang_type_backref (decl, mangled, info, 0);
1000 default: /* unhandled */
1001 return NULL;
1005 /* Extract the identifier from MANGLED and append it to DECL.
1006 Return the remaining string on success or NULL on failure. */
1007 static const char *
1008 dlang_identifier (string *decl, const char *mangled, struct dlang_info *info)
1010 unsigned long len;
1012 if (mangled == NULL || *mangled == '\0')
1013 return NULL;
1015 if (*mangled == 'Q')
1016 return dlang_symbol_backref (decl, mangled, info);
1018 /* May be a template instance without a length prefix. */
1019 if (mangled[0] == '_' && mangled[1] == '_'
1020 && (mangled[2] == 'T' || mangled[2] == 'U'))
1021 return dlang_parse_template (decl, mangled, info, TEMPLATE_LENGTH_UNKNOWN);
1023 const char *endptr = dlang_number (mangled, &len);
1025 if (endptr == NULL || len == 0)
1026 return NULL;
1028 if (strlen (endptr) < len)
1029 return NULL;
1031 mangled = endptr;
1033 /* May be a template instance with a length prefix. */
1034 if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
1035 && (mangled[2] == 'T' || mangled[2] == 'U'))
1036 return dlang_parse_template (decl, mangled, info, len);
1038 return dlang_lname (decl, mangled, len);
1041 /* Extract the plain identifier from MANGLED and prepend/append it to DECL
1042 with special treatment for some magic compiler generted symbols.
1043 Return the remaining string on success or NULL on failure. */
1044 static const char *
1045 dlang_lname (string *decl, const char *mangled, unsigned long len)
1047 switch (len)
1049 case 6:
1050 if (strncmp (mangled, "__ctor", len) == 0)
1052 /* Constructor symbol for a class/struct. */
1053 string_append (decl, "this");
1054 mangled += len;
1055 return mangled;
1057 else if (strncmp (mangled, "__dtor", len) == 0)
1059 /* Destructor symbol for a class/struct. */
1060 string_append (decl, "~this");
1061 mangled += len;
1062 return mangled;
1064 else if (strncmp (mangled, "__initZ", len + 1) == 0)
1066 /* The static initialiser for a given symbol. */
1067 string_prepend (decl, "initializer for ");
1068 string_setlength (decl, string_length (decl) - 1);
1069 mangled += len;
1070 return mangled;
1072 else if (strncmp (mangled, "__vtblZ", len + 1) == 0)
1074 /* The vtable symbol for a given class. */
1075 string_prepend (decl, "vtable for ");
1076 string_setlength (decl, string_length (decl) - 1);
1077 mangled += len;
1078 return mangled;
1080 break;
1082 case 7:
1083 if (strncmp (mangled, "__ClassZ", len + 1) == 0)
1085 /* The classinfo symbol for a given class. */
1086 string_prepend (decl, "ClassInfo for ");
1087 string_setlength (decl, string_length (decl) - 1);
1088 mangled += len;
1089 return mangled;
1091 break;
1093 case 10:
1094 if (strncmp (mangled, "__postblitMFZ", len + 3) == 0)
1096 /* Postblit symbol for a struct. */
1097 string_append (decl, "this(this)");
1098 mangled += len + 3;
1099 return mangled;
1101 break;
1103 case 11:
1104 if (strncmp (mangled, "__InterfaceZ", len + 1) == 0)
1106 /* The interface symbol for a given class. */
1107 string_prepend (decl, "Interface for ");
1108 string_setlength (decl, string_length (decl) - 1);
1109 mangled += len;
1110 return mangled;
1112 break;
1114 case 12:
1115 if (strncmp (mangled, "__ModuleInfoZ", len + 1) == 0)
1117 /* The ModuleInfo symbol for a given module. */
1118 string_prepend (decl, "ModuleInfo for ");
1119 string_setlength (decl, string_length (decl) - 1);
1120 mangled += len;
1121 return mangled;
1123 break;
1126 string_appendn (decl, mangled, len);
1127 mangled += len;
1129 return mangled;
1132 /* Extract the integer value from MANGLED and append it to DECL,
1133 where TYPE is the type it should be represented as.
1134 Return the remaining string on success or NULL on failure. */
1135 static const char *
1136 dlang_parse_integer (string *decl, const char *mangled, char type)
1138 if (type == 'a' || type == 'u' || type == 'w')
1140 /* Parse character value. */
1141 char value[20];
1142 int pos = sizeof(value);
1143 int width = 0;
1144 unsigned long val;
1146 mangled = dlang_number (mangled, &val);
1147 if (mangled == NULL)
1148 return NULL;
1150 string_append (decl, "'");
1152 if (type == 'a' && val >= 0x20 && val < 0x7F)
1154 /* Represent as a character literal. */
1155 char c = (char) val;
1156 string_appendn (decl, &c, 1);
1158 else
1160 /* Represent as a hexadecimal value. */
1161 switch (type)
1163 case 'a': /* char */
1164 string_append (decl, "\\x");
1165 width = 2;
1166 break;
1167 case 'u': /* wchar */
1168 string_append (decl, "\\u");
1169 width = 4;
1170 break;
1171 case 'w': /* dchar */
1172 string_append (decl, "\\U");
1173 width = 8;
1174 break;
1177 while (val > 0)
1179 int digit = val % 16;
1181 if (digit < 10)
1182 value[--pos] = (char)(digit + '0');
1183 else
1184 value[--pos] = (char)((digit - 10) + 'a');
1186 val /= 16;
1187 width--;
1190 for (; width > 0; width--)
1191 value[--pos] = '0';
1193 string_appendn (decl, &(value[pos]), sizeof(value) - pos);
1195 string_append (decl, "'");
1197 else if (type == 'b')
1199 /* Parse boolean value. */
1200 unsigned long val;
1202 mangled = dlang_number (mangled, &val);
1203 if (mangled == NULL)
1204 return NULL;
1206 string_append (decl, val ? "true" : "false");
1208 else
1210 /* Parse integer value. */
1211 const char *numptr = mangled;
1212 size_t num = 0;
1214 if (! ISDIGIT (*mangled))
1215 return NULL;
1217 while (ISDIGIT (*mangled))
1219 num++;
1220 mangled++;
1222 string_appendn (decl, numptr, num);
1224 /* Append suffix. */
1225 switch (type)
1227 case 'h': /* ubyte */
1228 case 't': /* ushort */
1229 case 'k': /* uint */
1230 string_append (decl, "u");
1231 break;
1232 case 'l': /* long */
1233 string_append (decl, "L");
1234 break;
1235 case 'm': /* ulong */
1236 string_append (decl, "uL");
1237 break;
1241 return mangled;
1244 /* Extract the floating-point value from MANGLED and append it to DECL.
1245 Return the remaining string on success or NULL on failure. */
1246 static const char *
1247 dlang_parse_real (string *decl, const char *mangled)
1249 /* Handle NAN and +-INF. */
1250 if (strncmp (mangled, "NAN", 3) == 0)
1252 string_append (decl, "NaN");
1253 mangled += 3;
1254 return mangled;
1256 else if (strncmp (mangled, "INF", 3) == 0)
1258 string_append (decl, "Inf");
1259 mangled += 3;
1260 return mangled;
1262 else if (strncmp (mangled, "NINF", 4) == 0)
1264 string_append (decl, "-Inf");
1265 mangled += 4;
1266 return mangled;
1269 /* Hexadecimal prefix and leading bit. */
1270 if (*mangled == 'N')
1272 string_append (decl, "-");
1273 mangled++;
1276 if (!ISXDIGIT (*mangled))
1277 return NULL;
1279 string_append (decl, "0x");
1280 string_appendn (decl, mangled, 1);
1281 string_append (decl, ".");
1282 mangled++;
1284 /* Significand. */
1285 while (ISXDIGIT (*mangled))
1287 string_appendn (decl, mangled, 1);
1288 mangled++;
1291 /* Exponent. */
1292 if (*mangled != 'P')
1293 return NULL;
1295 string_append (decl, "p");
1296 mangled++;
1298 if (*mangled == 'N')
1300 string_append (decl, "-");
1301 mangled++;
1304 while (ISDIGIT (*mangled))
1306 string_appendn (decl, mangled, 1);
1307 mangled++;
1310 return mangled;
1313 /* Extract the string value from MANGLED and append it to DECL.
1314 Return the remaining string on success or NULL on failure. */
1315 static const char *
1316 dlang_parse_string (string *decl, const char *mangled)
1318 char type = *mangled;
1319 unsigned long len;
1321 mangled++;
1322 mangled = dlang_number (mangled, &len);
1323 if (mangled == NULL || *mangled != '_')
1324 return NULL;
1326 mangled++;
1327 string_append (decl, "\"");
1328 while (len--)
1330 char val;
1331 const char *endptr = dlang_hexdigit (mangled, &val);
1333 if (endptr == NULL)
1334 return NULL;
1336 /* Sanitize white and non-printable characters. */
1337 switch (val)
1339 case ' ':
1340 string_append (decl, " ");
1341 break;
1342 case '\t':
1343 string_append (decl, "\\t");
1344 break;
1345 case '\n':
1346 string_append (decl, "\\n");
1347 break;
1348 case '\r':
1349 string_append (decl, "\\r");
1350 break;
1351 case '\f':
1352 string_append (decl, "\\f");
1353 break;
1354 case '\v':
1355 string_append (decl, "\\v");
1356 break;
1358 default:
1359 if (ISPRINT (val))
1360 string_appendn (decl, &val, 1);
1361 else
1363 string_append (decl, "\\x");
1364 string_appendn (decl, mangled, 2);
1368 mangled = endptr;
1370 string_append (decl, "\"");
1372 if (type != 'a')
1373 string_appendn (decl, &type, 1);
1375 return mangled;
1378 /* Extract the static array value from MANGLED and append it to DECL.
1379 Return the remaining string on success or NULL on failure. */
1380 static const char *
1381 dlang_parse_arrayliteral (string *decl, const char *mangled)
1383 unsigned long elements;
1385 mangled = dlang_number (mangled, &elements);
1386 if (mangled == NULL)
1387 return NULL;
1389 string_append (decl, "[");
1390 while (elements--)
1392 mangled = dlang_value (decl, mangled, NULL, '\0');
1393 if (mangled == NULL)
1394 return NULL;
1396 if (elements != 0)
1397 string_append (decl, ", ");
1400 string_append (decl, "]");
1401 return mangled;
1404 /* Extract the associative array value from MANGLED and append it to DECL.
1405 Return the remaining string on success or NULL on failure. */
1406 static const char *
1407 dlang_parse_assocarray (string *decl, const char *mangled)
1409 unsigned long elements;
1411 mangled = dlang_number (mangled, &elements);
1412 if (mangled == NULL)
1413 return NULL;
1415 string_append (decl, "[");
1416 while (elements--)
1418 mangled = dlang_value (decl, mangled, NULL, '\0');
1419 if (mangled == NULL)
1420 return NULL;
1422 string_append (decl, ":");
1423 mangled = dlang_value (decl, mangled, NULL, '\0');
1424 if (mangled == NULL)
1425 return NULL;
1427 if (elements != 0)
1428 string_append (decl, ", ");
1431 string_append (decl, "]");
1432 return mangled;
1435 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1436 Return the remaining string on success or NULL on failure. */
1437 static const char *
1438 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1440 unsigned long args;
1442 mangled = dlang_number (mangled, &args);
1443 if (mangled == NULL)
1444 return NULL;
1446 if (name != NULL)
1447 string_append (decl, name);
1449 string_append (decl, "(");
1450 while (args--)
1452 mangled = dlang_value (decl, mangled, NULL, '\0');
1453 if (mangled == NULL)
1454 return NULL;
1456 if (args != 0)
1457 string_append (decl, ", ");
1460 string_append (decl, ")");
1461 return mangled;
1464 /* Extract the value from MANGLED and append it to DECL.
1465 Return the remaining string on success or NULL on failure. */
1466 static const char *
1467 dlang_value (string *decl, const char *mangled, const char *name, char type)
1469 if (mangled == NULL || *mangled == '\0')
1470 return NULL;
1472 switch (*mangled)
1474 /* Null value. */
1475 case 'n':
1476 mangled++;
1477 string_append (decl, "null");
1478 break;
1480 /* Integral values. */
1481 case 'N':
1482 mangled++;
1483 string_append (decl, "-");
1484 mangled = dlang_parse_integer (decl, mangled, type);
1485 break;
1487 case 'i':
1488 mangled++;
1489 /* Fall through */
1491 /* There really should always be an `i' before encoded numbers, but there
1492 wasn't in early versions of D2, so this case range must remain for
1493 backwards compatibility. */
1494 case '0': case '1': case '2': case '3': case '4':
1495 case '5': case '6': case '7': case '8': case '9':
1496 mangled = dlang_parse_integer (decl, mangled, type);
1497 break;
1499 /* Real value. */
1500 case 'e':
1501 mangled++;
1502 mangled = dlang_parse_real (decl, mangled);
1503 break;
1505 /* Complex value. */
1506 case 'c':
1507 mangled++;
1508 mangled = dlang_parse_real (decl, mangled);
1509 string_append (decl, "+");
1510 if (mangled == NULL || *mangled != 'c')
1511 return NULL;
1512 mangled++;
1513 mangled = dlang_parse_real (decl, mangled);
1514 string_append (decl, "i");
1515 break;
1517 /* String values. */
1518 case 'a': /* UTF8 */
1519 case 'w': /* UTF16 */
1520 case 'd': /* UTF32 */
1521 mangled = dlang_parse_string (decl, mangled);
1522 break;
1524 /* Array values. */
1525 case 'A':
1526 mangled++;
1527 if (type == 'H')
1528 mangled = dlang_parse_assocarray (decl, mangled);
1529 else
1530 mangled = dlang_parse_arrayliteral (decl, mangled);
1531 break;
1533 /* Struct values. */
1534 case 'S':
1535 mangled++;
1536 mangled = dlang_parse_structlit (decl, mangled, name);
1537 break;
1539 default:
1540 return NULL;
1543 return mangled;
1546 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1547 Returns the remaining signature on success or NULL on failure. */
1548 static const char *
1549 dlang_parse_mangle (string *decl, const char *mangled, struct dlang_info *info)
1551 /* A D mangled symbol is comprised of both scope and type information.
1553 MangleName:
1554 _D QualifiedName Type
1555 _D QualifiedName Z
1557 The caller should have guaranteed that the start pointer is at the
1558 above location.
1559 Note that type is never a function type, but only the return type of
1560 a function or the type of a variable.
1562 mangled += 2;
1564 mangled = dlang_parse_qualified (decl, mangled, info, 1);
1566 if (mangled != NULL)
1568 /* Artificial symbols end with 'Z' and have no type. */
1569 if (*mangled == 'Z')
1570 mangled++;
1571 else
1573 /* Discard the declaration or return type. */
1574 string type;
1576 string_init (&type);
1577 mangled = dlang_type (&type, mangled, info);
1578 string_delete (&type);
1582 return mangled;
1585 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1586 SUFFIX_MODIFIERS is 1 if we are printing modifiers on this after the symbol.
1587 Returns the remaining signature on success or NULL on failure. */
1588 static const char *
1589 dlang_parse_qualified (string *decl, const char *mangled,
1590 struct dlang_info *info, int suffix_modifiers)
1592 /* Qualified names are identifiers separated by their encoded length.
1593 Nested functions also encode their argument types without specifying
1594 what they return.
1596 QualifiedName:
1597 SymbolFunctionName
1598 SymbolFunctionName QualifiedName
1601 SymbolFunctionName:
1602 SymbolName
1603 SymbolName TypeFunctionNoReturn
1604 SymbolName M TypeFunctionNoReturn
1605 SymbolName M TypeModifiers TypeFunctionNoReturn
1607 The start pointer should be at the above location.
1609 size_t n = 0;
1612 if (n++)
1613 string_append (decl, ".");
1615 /* Skip over anonymous symbols. */
1616 while (*mangled == '0')
1617 mangled++;
1619 mangled = dlang_identifier (decl, mangled, info);
1621 /* Consume the encoded arguments. However if this is not followed by the
1622 next encoded length or mangle type, then this is not a continuation of
1623 a qualified name, in which case we backtrack and return the current
1624 unconsumed position of the mangled decl. */
1625 if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1627 string mods;
1628 const char *start = mangled;
1629 int saved = string_length (decl);
1631 /* Save the type modifiers for appending at the end if needed. */
1632 string_init (&mods);
1634 /* Skip over 'this' parameter and type modifiers. */
1635 if (*mangled == 'M')
1637 mangled++;
1638 mangled = dlang_type_modifiers (&mods, mangled);
1639 string_setlength (decl, saved);
1642 mangled = dlang_function_type_noreturn (decl, NULL, NULL,
1643 mangled, info);
1644 if (suffix_modifiers)
1645 string_appendn (decl, mods.b, string_length (&mods));
1647 if (mangled == NULL || *mangled == '\0')
1649 /* Did not match the rule we were looking for. */
1650 mangled = start;
1651 string_setlength (decl, saved);
1654 string_delete (&mods);
1657 while (mangled && dlang_symbol_name_p (mangled, info));
1659 return mangled;
1662 /* Demangle the tuple from MANGLED and append it to DECL.
1663 Return the remaining string on success or NULL on failure. */
1664 static const char *
1665 dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info)
1667 unsigned long elements;
1669 mangled = dlang_number (mangled, &elements);
1670 if (mangled == NULL)
1671 return NULL;
1673 string_append (decl, "Tuple!(");
1675 while (elements--)
1677 mangled = dlang_type (decl, mangled, info);
1678 if (mangled == NULL)
1679 return NULL;
1681 if (elements != 0)
1682 string_append (decl, ", ");
1685 string_append (decl, ")");
1686 return mangled;
1689 /* Demangle the template symbol parameter from MANGLED and append it to DECL.
1690 Return the remaining string on success or NULL on failure. */
1691 static const char *
1692 dlang_template_symbol_param (string *decl, const char *mangled,
1693 struct dlang_info *info)
1695 if (strncmp (mangled, "_D", 2) == 0
1696 && dlang_symbol_name_p (mangled + 2, info))
1697 return dlang_parse_mangle (decl, mangled, info);
1699 if (*mangled == 'Q')
1700 return dlang_parse_qualified (decl, mangled, info, 0);
1702 unsigned long len;
1703 const char *endptr = dlang_number (mangled, &len);
1705 if (endptr == NULL || len == 0)
1706 return NULL;
1708 /* In template parameter symbols generated by the frontend up to 2.076,
1709 the symbol length is encoded and the first character of the mangled
1710 name can be a digit. This causes ambiguity issues because the digits
1711 of the two numbers are adjacent. */
1712 long psize = len;
1713 const char *pend;
1714 int saved = string_length (decl);
1716 /* Work backwards until a match is found. */
1717 for (pend = endptr; endptr != NULL; pend--)
1719 mangled = pend;
1721 /* Reached the beginning of the pointer to the name length,
1722 try parsing the entire symbol. */
1723 if (psize == 0)
1725 psize = len;
1726 pend = endptr;
1727 endptr = NULL;
1730 /* Check whether template parameter is a function with a valid
1731 return type or an untyped identifier. */
1732 if (dlang_symbol_name_p (mangled, info))
1733 mangled = dlang_parse_qualified (decl, mangled, info, 0);
1734 else if (strncmp (mangled, "_D", 2) == 0
1735 && dlang_symbol_name_p (mangled + 2, info))
1736 mangled = dlang_parse_mangle (decl, mangled, info);
1738 /* Check for name length mismatch. */
1739 if (mangled && (endptr == NULL || (mangled - pend) == psize))
1740 return mangled;
1742 psize /= 10;
1743 string_setlength (decl, saved);
1746 /* No match on any combinations. */
1747 return NULL;
1750 /* Demangle the argument list from MANGLED and append it to DECL.
1751 Return the remaining string on success or NULL on failure. */
1752 static const char *
1753 dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
1755 size_t n = 0;
1757 while (mangled && *mangled != '\0')
1759 switch (*mangled)
1761 case 'Z': /* End of parameter list. */
1762 mangled++;
1763 return mangled;
1766 if (n++)
1767 string_append (decl, ", ");
1769 /* Skip over specialised template prefix. */
1770 if (*mangled == 'H')
1771 mangled++;
1773 switch (*mangled)
1775 case 'S': /* Symbol parameter. */
1776 mangled++;
1777 mangled = dlang_template_symbol_param (decl, mangled, info);
1778 break;
1779 case 'T': /* Type parameter. */
1780 mangled++;
1781 mangled = dlang_type (decl, mangled, info);
1782 break;
1783 case 'V': /* Value parameter. */
1785 string name;
1786 char type;
1788 /* Peek at the type. */
1789 mangled++;
1790 type = *mangled;
1792 if (type == 'Q')
1794 /* Value type is a back reference, peek at the real type. */
1795 const char *backref;
1796 if (dlang_backref (mangled, &backref, info) == NULL)
1797 return NULL;
1799 type = *backref;
1802 /* In the few instances where the type is actually desired in
1803 the output, it should precede the value from dlang_value. */
1804 string_init (&name);
1805 mangled = dlang_type (&name, mangled, info);
1806 string_need (&name, 1);
1807 *(name.p) = '\0';
1809 mangled = dlang_value (decl, mangled, name.b, type);
1810 string_delete (&name);
1811 break;
1813 case 'X': /* Externally mangled parameter. */
1815 unsigned long len;
1816 const char *endptr;
1818 mangled++;
1819 endptr = dlang_number (mangled, &len);
1820 if (endptr == NULL || strlen (endptr) < len)
1821 return NULL;
1823 string_appendn (decl, endptr, len);
1824 mangled = endptr + len;
1825 break;
1827 default:
1828 return NULL;
1832 return mangled;
1835 /* Extract and demangle the template symbol in MANGLED, expected to
1836 be made up of LEN characters (-1 if unknown), and append it to DECL.
1837 Returns the remaining signature on success or NULL on failure. */
1838 static const char *
1839 dlang_parse_template (string *decl, const char *mangled,
1840 struct dlang_info *info, unsigned long len)
1842 const char *start = mangled;
1843 string args;
1845 /* Template instance names have the types and values of its parameters
1846 encoded into it.
1848 TemplateInstanceName:
1849 Number __T LName TemplateArgs Z
1850 Number __U LName TemplateArgs Z
1852 The start pointer should be at the above location, and LEN should be
1853 the value of the decoded number.
1856 /* Template symbol. */
1857 if (!dlang_symbol_name_p (mangled + 3, info) || mangled[3] == '0')
1858 return NULL;
1860 mangled += 3;
1862 /* Template identifier. */
1863 mangled = dlang_identifier (decl, mangled, info);
1865 /* Template arguments. */
1866 string_init (&args);
1867 mangled = dlang_template_args (&args, mangled, info);
1869 string_append (decl, "!(");
1870 string_appendn (decl, args.b, string_length (&args));
1871 string_append (decl, ")");
1873 string_delete (&args);
1875 /* Check for template name length mismatch. */
1876 if (len != TEMPLATE_LENGTH_UNKNOWN
1877 && mangled
1878 && (unsigned long) (mangled - start) != len)
1879 return NULL;
1881 return mangled;
1884 /* Initialize the information structure we use to pass around information. */
1885 static void
1886 dlang_demangle_init_info (const char *mangled, int last_backref,
1887 struct dlang_info *info)
1889 info->s = mangled;
1890 info->last_backref = last_backref;
1893 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1894 signature on success or NULL on failure. */
1896 char *
1897 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1899 string decl;
1900 char *demangled = NULL;
1902 if (mangled == NULL || *mangled == '\0')
1903 return NULL;
1905 if (strncmp (mangled, "_D", 2) != 0)
1906 return NULL;
1908 string_init (&decl);
1910 if (strcmp (mangled, "_Dmain") == 0)
1912 string_append (&decl, "D main");
1914 else
1916 struct dlang_info info;
1918 dlang_demangle_init_info (mangled, strlen (mangled), &info);
1919 mangled = dlang_parse_mangle (&decl, mangled, &info);
1921 /* Check that the entire symbol was successfully demangled. */
1922 if (mangled == NULL || *mangled != '\0')
1923 string_delete (&decl);
1926 if (string_length (&decl) > 0)
1928 string_need (&decl, 1);
1929 *(decl.p) = '\0';
1930 demangled = decl.b;
1933 return demangled;