Automatic date update in version.in
[external/binutils.git] / libiberty / d-demangle.c
1 /* Demangler for the D programming language
2    Copyright (C) 2014-2018 Free Software Foundation, Inc.
3    Written by Iain Buclaw (ibuclaw@gdcproject.org)
4
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.
10
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.)
19
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.
24
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/>.  */
28
29 /* This file exports one function; dlang_demangle.  */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include "safe-ctype.h"
36
37 #include <sys/types.h>
38 #include <string.h>
39 #include <stdio.h>
40
41 #ifdef HAVE_STDLIB_H
42 #include <stdlib.h>
43 #endif
44
45 #include <demangle.h>
46 #include "libiberty.h"
47
48 /* A mini string-handling package */
49
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;
56
57 static void
58 string_need (string *s, int n)
59 {
60   int tem;
61
62   if (s->b == NULL)
63     {
64       if (n < 32)
65         {
66           n = 32;
67         }
68       s->p = s->b = XNEWVEC (char, n);
69       s->e = s->b + n;
70     }
71   else if (s->e - s->p < n)
72     {
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;
79     }
80 }
81
82 static void
83 string_delete (string *s)
84 {
85   if (s->b != NULL)
86     {
87       XDELETEVEC (s->b);
88       s->b = s->e = s->p = NULL;
89     }
90 }
91
92 static void
93 string_init (string *s)
94 {
95   s->b = s->p = s->e = NULL;
96 }
97
98 static int
99 string_length (string *s)
100 {
101   if (s->p == s->b)
102     {
103       return 0;
104     }
105   return s->p - s->b;
106 }
107
108 static void
109 string_setlength (string *s, int n)
110 {
111   if (n - string_length (s) < 0)
112     {
113       s->p = s->b + n;
114     }
115 }
116
117 static void
118 string_append (string *p, const char *s)
119 {
120   int n = strlen (s);
121   string_need (p, n);
122   memcpy (p->p, s, n);
123   p->p += n;
124 }
125
126 static void
127 string_appendn (string *p, const char *s, int n)
128 {
129   if (n != 0)
130     {
131       string_need (p, n);
132       memcpy (p->p, s, n);
133       p->p += n;
134     }
135 }
136
137 static void
138 string_prependn (string *p, const char *s, int n)
139 {
140   char *q;
141
142   if (n != 0)
143     {
144       string_need (p, n);
145       for (q = p->p - 1; q >= p->b; q--)
146         {
147           q[n] = q[0];
148         }
149       memcpy (p->b, s, n);
150       p->p += n;
151     }
152 }
153
154 static void
155 string_prepend (string *p, const char *s)
156 {
157   if (s != NULL && *s != '\0')
158     {
159       string_prependn (p, s, strlen (s));
160     }
161 }
162
163 /* What kinds of symbol we could be parsing.  */
164 enum dlang_symbol_kinds
165 {
166   /* Top-level symbol, needs it's type checked.  */
167   dlang_top_level,
168   /* Function symbol, needs it's type checked.   */
169   dlang_function,
170   /* Strongly typed name, such as for classes, structs and enums.  */
171   dlang_type_name,
172   /* Template identifier.  */
173   dlang_template_ident,
174   /* Template symbol parameter.  */
175   dlang_template_param
176 };
177
178 /* Prototypes for forward referenced functions */
179 static const char *dlang_function_args (string *, const char *);
180
181 static const char *dlang_type (string *, const char *);
182
183 static const char *dlang_value (string *, const char *, const char *, char);
184
185 static const char *dlang_parse_qualified (string *, const char *,
186                                           enum dlang_symbol_kinds);
187
188 static const char *dlang_parse_mangle (string *, const char *,
189                                        enum dlang_symbol_kinds);
190
191 static const char *dlang_parse_tuple (string *, const char *);
192
193 static const char *dlang_parse_template (string *, const char *, long);
194
195
196 /* Extract the number from MANGLED, and assign the result to RET.
197    Return the remaining string on success or NULL on failure.  */
198 static const char *
199 dlang_number (const char *mangled, long *ret)
200 {
201   /* Return NULL if trying to extract something that isn't a digit.  */
202   if (mangled == NULL || !ISDIGIT (*mangled))
203     return NULL;
204
205   (*ret) = 0;
206
207   while (ISDIGIT (*mangled))
208     {
209       (*ret) *= 10;
210
211       /* If an overflow occured when multiplying by ten, the result
212          will not be a multiple of ten.  */
213       if ((*ret % 10) != 0)
214         return NULL;
215
216       (*ret) += mangled[0] - '0';
217       mangled++;
218     }
219
220   if (*mangled == '\0' || *ret < 0)
221     return NULL;
222
223   return mangled;
224 }
225
226 /* Extract the hex-digit from MANGLED, and assign the result to RET.
227    Return the remaining string on success or NULL on failure.  */
228 static const char *
229 dlang_hexdigit (const char *mangled, char *ret)
230 {
231   char c;
232
233   /* Return NULL if trying to extract something that isn't a hexdigit.  */
234   if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1]))
235     return NULL;
236
237   c = mangled[0];
238   if (!ISDIGIT (c))
239     (*ret) = (c - (ISUPPER (c) ? 'A' : 'a') + 10);
240   else
241     (*ret) = (c - '0');
242
243   c = mangled[1];
244   if (!ISDIGIT (c))
245     (*ret) = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
246   else
247     (*ret) = (*ret << 4) | (c - '0');
248
249   mangled += 2;
250
251   return mangled;
252 }
253
254 /* Extract the function calling convention from MANGLED and
255    return 1 on success or 0 on failure.  */
256 static int
257 dlang_call_convention_p (const char *mangled)
258 {
259   switch (*mangled)
260     {
261     case 'F': case 'U': case 'V':
262     case 'W': case 'R': case 'Y':
263       return 1;
264
265     default:
266       return 0;
267     }
268 }
269
270 /* Demangle the calling convention from MANGLED and append it to DECL.
271    Return the remaining string on success or NULL on failure.  */
272 static const char *
273 dlang_call_convention (string *decl, const char *mangled)
274 {
275   if (mangled == NULL || *mangled == '\0')
276     return NULL;
277
278   switch (*mangled)
279     {
280     case 'F': /* (D) */
281       mangled++;
282       break;
283     case 'U': /* (C) */
284       mangled++;
285       string_append (decl, "extern(C) ");
286       break;
287     case 'W': /* (Windows) */
288       mangled++;
289       string_append (decl, "extern(Windows) ");
290       break;
291     case 'V': /* (Pascal) */
292       mangled++;
293       string_append (decl, "extern(Pascal) ");
294       break;
295     case 'R': /* (C++) */
296       mangled++;
297       string_append (decl, "extern(C++) ");
298       break;
299     case 'Y': /* (Objective-C) */
300       mangled++;
301       string_append (decl, "extern(Objective-C) ");
302       break;
303     default:
304       return NULL;
305     }
306
307   return mangled;
308 }
309
310 /* Extract the type modifiers from MANGLED and append them to DECL.
311    Returns the remaining signature on success or NULL on failure.  */
312 static const char *
313 dlang_type_modifiers (string *decl, const char *mangled)
314 {
315   if (mangled == NULL || *mangled == '\0')
316     return NULL;
317
318   switch (*mangled)
319     {
320     case 'x': /* const */
321       mangled++;
322       string_append (decl, " const");
323       return mangled;
324     case 'y': /* immutable */
325       mangled++;
326       string_append (decl, " immutable");
327       return mangled;
328     case 'O': /* shared */
329       mangled++;
330       string_append (decl, " shared");
331       return dlang_type_modifiers (decl, mangled);
332     case 'N':
333       mangled++;
334       if (*mangled == 'g') /* wild */
335         {
336           mangled++;
337           string_append (decl, " inout");
338           return dlang_type_modifiers (decl, mangled);
339         }
340       else
341         return NULL;
342
343     default:
344       return mangled;
345     }
346 }
347
348 /* Demangle the D function attributes from MANGLED and append it to DECL.
349    Return the remaining string on success or NULL on failure.  */
350 static const char *
351 dlang_attributes (string *decl, const char *mangled)
352 {
353   if (mangled == NULL || *mangled == '\0')
354     return NULL;
355
356   while (*mangled == 'N')
357     {
358       mangled++;
359       switch (*mangled)
360         {
361         case 'a': /* pure */
362           mangled++;
363           string_append (decl, "pure ");
364           continue;
365         case 'b': /* nothrow */
366           mangled++;
367           string_append (decl, "nothrow ");
368           continue;
369         case 'c': /* ref */
370           mangled++;
371           string_append (decl, "ref ");
372           continue;
373         case 'd': /* @property */
374           mangled++;
375           string_append (decl, "@property ");
376           continue;
377         case 'e': /* @trusted */
378           mangled++;
379           string_append (decl, "@trusted ");
380           continue;
381         case 'f': /* @safe */
382           mangled++;
383           string_append (decl, "@safe ");
384           continue;
385         case 'g':
386         case 'h':
387         case 'k':
388           /* inout parameter is represented as 'Ng'.
389              vector parameter is represented as 'Nh'.
390              return paramenter is represented as 'Nk'.
391              If we see this, then we know we're really in the
392              parameter list.  Rewind and break.  */
393           mangled--;
394           break;
395         case 'i': /* @nogc */
396           mangled++;
397           string_append (decl, "@nogc ");
398           continue;
399         case 'j': /* return */
400           mangled++;
401           string_append (decl, "return ");
402           continue;
403         case 'l': /* scope */
404           mangled++;
405           string_append (decl, "scope ");
406           continue;
407
408         default: /* unknown attribute */
409           return NULL;
410         }
411       break;
412     }
413
414   return mangled;
415 }
416
417 /* Demangle the function type from MANGLED and append it to DECL.
418    Return the remaining string on success or NULL on failure.  */
419 static const char *
420 dlang_function_type (string *decl, const char *mangled)
421 {
422   string attr, args, type;
423   size_t szattr, szargs, sztype;
424
425   if (mangled == NULL || *mangled == '\0')
426     return NULL;
427
428   /* The order of the mangled string is:
429         CallConvention FuncAttrs Arguments ArgClose Type
430
431      The demangled string is re-ordered as:
432         CallConvention Type Arguments FuncAttrs
433    */
434   string_init (&attr);
435   string_init (&args);
436   string_init (&type);
437
438   /* Function call convention.  */
439   mangled = dlang_call_convention (decl, mangled);
440
441   /* Function attributes.  */
442   mangled = dlang_attributes (&attr, mangled);
443   szattr = string_length (&attr);
444
445   /* Function arguments.  */
446   mangled = dlang_function_args (&args, mangled);
447   szargs = string_length (&args);
448
449   /* Function return type.  */
450   mangled = dlang_type (&type, mangled);
451   sztype = string_length (&type);
452
453   /* Append to decl in order. */
454   string_appendn (decl, type.b, sztype);
455   string_append (decl, "(");
456   string_appendn (decl, args.b, szargs);
457   string_append (decl, ") ");
458   string_appendn (decl, attr.b, szattr);
459
460   string_delete (&attr);
461   string_delete (&args);
462   string_delete (&type);
463   return mangled;
464 }
465
466 /* Demangle the argument list from MANGLED and append it to DECL.
467    Return the remaining string on success or NULL on failure.  */
468 static const char *
469 dlang_function_args (string *decl, const char *mangled)
470 {
471   size_t n = 0;
472
473   while (mangled && *mangled != '\0')
474     {
475       switch (*mangled)
476         {
477         case 'X': /* (variadic T t...) style.  */
478           mangled++;
479           string_append (decl, "...");
480           return mangled;
481         case 'Y': /* (variadic T t, ...) style.  */
482           mangled++;
483           if (n != 0)
484             string_append (decl, ", ");
485           string_append (decl, "...");
486           return mangled;
487         case 'Z': /* Normal function.  */
488           mangled++;
489           return mangled;
490         }
491
492       if (n++)
493         string_append (decl, ", ");
494
495       if (*mangled == 'M') /* scope(T) */
496         {
497           mangled++;
498           string_append (decl, "scope ");
499         }
500
501       if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */
502         {
503           mangled += 2;
504           string_append (decl, "return ");
505         }
506
507       switch (*mangled)
508         {
509         case 'J': /* out(T) */
510           mangled++;
511           string_append (decl, "out ");
512           break;
513         case 'K': /* ref(T) */
514           mangled++;
515           string_append (decl, "ref ");
516           break;
517         case 'L': /* lazy(T) */
518           mangled++;
519           string_append (decl, "lazy ");
520           break;
521         }
522       mangled = dlang_type (decl, mangled);
523     }
524
525   return mangled;
526 }
527
528 /* Demangle the type from MANGLED and append it to DECL.
529    Return the remaining string on success or NULL on failure.  */
530 static const char *
531 dlang_type (string *decl, const char *mangled)
532 {
533   if (mangled == NULL || *mangled == '\0')
534     return NULL;
535
536   switch (*mangled)
537     {
538     case 'O': /* shared(T) */
539       mangled++;
540       string_append (decl, "shared(");
541       mangled = dlang_type (decl, mangled);
542       string_append (decl, ")");
543       return mangled;
544     case 'x': /* const(T) */
545       mangled++;
546       string_append (decl, "const(");
547       mangled = dlang_type (decl, mangled);
548       string_append (decl, ")");
549       return mangled;
550     case 'y': /* immutable(T) */
551       mangled++;
552       string_append (decl, "immutable(");
553       mangled = dlang_type (decl, mangled);
554       string_append (decl, ")");
555       return mangled;
556     case 'N':
557       mangled++;
558       if (*mangled == 'g') /* wild(T) */
559         {
560           mangled++;
561           string_append (decl, "inout(");
562           mangled = dlang_type (decl, mangled);
563           string_append (decl, ")");
564           return mangled;
565         }
566       else if (*mangled == 'h') /* vector(T) */
567         {
568           mangled++;
569           string_append (decl, "__vector(");
570           mangled = dlang_type (decl, mangled);
571           string_append (decl, ")");
572           return mangled;
573         }
574       else
575         return NULL;
576     case 'A': /* dynamic array (T[]) */
577       mangled++;
578       mangled = dlang_type (decl, mangled);
579       string_append (decl, "[]");
580       return mangled;
581     case 'G': /* static array (T[N]) */
582     {
583       const char *numptr;
584       size_t num = 0;
585       mangled++;
586
587       numptr = mangled;
588       while (ISDIGIT (*mangled))
589         {
590           num++;
591           mangled++;
592         }
593       mangled = dlang_type (decl, mangled);
594       string_append (decl, "[");
595       string_appendn (decl, numptr, num);
596       string_append (decl, "]");
597       return mangled;
598     }
599     case 'H': /* associative array (T[T]) */
600     {
601       string type;
602       size_t sztype;
603       mangled++;
604
605       string_init (&type);
606       mangled = dlang_type (&type, mangled);
607       sztype = string_length (&type);
608
609       mangled = dlang_type (decl, mangled);
610       string_append (decl, "[");
611       string_appendn (decl, type.b, sztype);
612       string_append (decl, "]");
613
614       string_delete (&type);
615       return mangled;
616     }
617     case 'P': /* pointer (T*) */
618       mangled++;
619       if (!dlang_call_convention_p (mangled))
620         {
621           mangled = dlang_type (decl, mangled);
622           string_append (decl, "*");
623           return mangled;
624         }
625       /* Fall through */
626     case 'F': /* function T (D) */
627     case 'U': /* function T (C) */
628     case 'W': /* function T (Windows) */
629     case 'V': /* function T (Pascal) */
630     case 'R': /* function T (C++) */
631     case 'Y': /* function T (Objective-C) */
632       /* Function pointer types don't include the trailing asterisk.  */
633       mangled = dlang_function_type (decl, mangled);
634       string_append (decl, "function");
635       return mangled;
636     case 'I': /* ident T */
637     case 'C': /* class T */
638     case 'S': /* struct T */
639     case 'E': /* enum T */
640     case 'T': /* typedef T */
641       mangled++;
642       return dlang_parse_qualified (decl, mangled, dlang_type_name);
643     case 'D': /* delegate T */
644     {
645       string mods;
646       size_t szmods;
647       mangled++;
648
649       string_init (&mods);
650       mangled = dlang_type_modifiers (&mods, mangled);
651       szmods = string_length (&mods);
652
653       mangled = dlang_function_type (decl, mangled);
654       string_append (decl, "delegate");
655       string_appendn (decl, mods.b, szmods);
656
657       string_delete (&mods);
658       return mangled;
659     }
660     case 'B': /* tuple T */
661       mangled++;
662       return dlang_parse_tuple (decl, mangled);
663
664     /* Basic types */
665     case 'n':
666       mangled++;
667       string_append (decl, "none");
668       return mangled;
669     case 'v':
670       mangled++;
671       string_append (decl, "void");
672       return mangled;
673     case 'g':
674       mangled++;
675       string_append (decl, "byte");
676       return mangled;
677     case 'h':
678       mangled++;
679       string_append (decl, "ubyte");
680       return mangled;
681     case 's':
682       mangled++;
683       string_append (decl, "short");
684       return mangled;
685     case 't':
686       mangled++;
687       string_append (decl, "ushort");
688       return mangled;
689     case 'i':
690       mangled++;
691       string_append (decl, "int");
692       return mangled;
693     case 'k':
694       mangled++;
695       string_append (decl, "uint");
696       return mangled;
697     case 'l':
698       mangled++;
699       string_append (decl, "long");
700       return mangled;
701     case 'm':
702       mangled++;
703       string_append (decl, "ulong");
704       return mangled;
705     case 'f':
706       mangled++;
707       string_append (decl, "float");
708       return mangled;
709     case 'd':
710       mangled++;
711       string_append (decl, "double");
712       return mangled;
713     case 'e':
714       mangled++;
715       string_append (decl, "real");
716       return mangled;
717
718     /* Imaginary and Complex types */
719     case 'o':
720       mangled++;
721       string_append (decl, "ifloat");
722       return mangled;
723     case 'p':
724       mangled++;
725       string_append (decl, "idouble");
726       return mangled;
727     case 'j':
728       mangled++;
729       string_append (decl, "ireal");
730       return mangled;
731     case 'q':
732       mangled++;
733       string_append (decl, "cfloat");
734       return mangled;
735     case 'r':
736       mangled++;
737       string_append (decl, "cdouble");
738       return mangled;
739     case 'c':
740       mangled++;
741       string_append (decl, "creal");
742       return mangled;
743
744     /* Other types */
745     case 'b':
746       mangled++;
747       string_append (decl, "bool");
748       return mangled;
749     case 'a':
750       mangled++;
751       string_append (decl, "char");
752       return mangled;
753     case 'u':
754       mangled++;
755       string_append (decl, "wchar");
756       return mangled;
757     case 'w':
758       mangled++;
759       string_append (decl, "dchar");
760       return mangled;
761     case 'z':
762       mangled++;
763       switch (*mangled)
764         {
765         case 'i':
766           mangled++;
767           string_append (decl, "cent");
768           return mangled;
769         case 'k':
770           mangled++;
771           string_append (decl, "ucent");
772           return mangled;
773         }
774       return NULL;
775
776     default: /* unhandled */
777       return NULL;
778     }
779 }
780
781 /* Extract the identifier from MANGLED and append it to DECL.
782    Return the remaining string on success or NULL on failure.  */
783 static const char *
784 dlang_identifier (string *decl, const char *mangled,
785                   enum dlang_symbol_kinds kind)
786 {
787   long len;
788   const char *endptr = dlang_number (mangled, &len);
789
790   if (endptr == NULL || len == 0)
791     return NULL;
792
793   /* In template parameter symbols, the first character of the mangled
794      name can be a digit.  This causes ambiguity issues because the
795      digits of the two numbers are adjacent.  */
796   if (kind == dlang_template_param)
797     {
798       long psize = len;
799       const char *pend;
800       int saved = string_length (decl);
801
802       /* Work backwards until a match is found.  */
803       for (pend = endptr; endptr != NULL; pend--)
804         {
805           mangled = pend;
806
807           /* Reached the beginning of the pointer to the name length,
808              try parsing the entire symbol.  */
809           if (psize == 0)
810             {
811               psize = len;
812               pend = endptr;
813               endptr = NULL;
814             }
815
816           /* Check whether template parameter is a function with a valid
817              return type or an untyped identifier.  */
818           if (ISDIGIT (*mangled))
819             mangled = dlang_parse_qualified (decl, mangled,
820                                              dlang_template_ident);
821           else if (strncmp (mangled, "_D", 2) == 0)
822             mangled = dlang_parse_mangle (decl, mangled, dlang_function);
823
824           /* Check for name length mismatch.  */
825           if (mangled && (mangled - pend) == psize)
826             return mangled;
827
828           psize /= 10;
829           string_setlength (decl, saved);
830         }
831
832       /* No match on any combinations.  */
833       return NULL;
834     }
835   else
836     {
837       if (strlen (endptr) < (size_t) len)
838         return NULL;
839
840       mangled = endptr;
841
842       /* May be a template instance.  */
843       if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
844           && (mangled[2] == 'T' || mangled[2] == 'U'))
845         return dlang_parse_template (decl, mangled, len);
846
847       switch (len)
848         {
849         case 6:
850           if (strncmp (mangled, "__ctor", len) == 0)
851             {
852               /* Constructor symbol for a class/struct.  */
853               string_append (decl, "this");
854               mangled += len;
855               return mangled;
856             }
857           else if (strncmp (mangled, "__dtor", len) == 0)
858             {
859               /* Destructor symbol for a class/struct.  */
860               string_append (decl, "~this");
861               mangled += len;
862               return mangled;
863             }
864           else if (strncmp (mangled, "__initZ", len+1) == 0)
865             {
866               /* The static initialiser for a given symbol.  */
867               string_prepend (decl, "initializer for ");
868               string_setlength (decl, string_length (decl) - 1);
869               mangled += len;
870               return mangled;
871             }
872           else if (strncmp (mangled, "__vtblZ", len+1) == 0)
873             {
874               /* The vtable symbol for a given class.  */
875               string_prepend (decl, "vtable for ");
876               string_setlength (decl, string_length (decl) - 1);
877               mangled += len;
878               return mangled;
879             }
880           break;
881
882         case 7:
883           if (strncmp (mangled, "__ClassZ", len+1) == 0)
884             {
885               /* The classinfo symbol for a given class.  */
886               string_prepend (decl, "ClassInfo for ");
887               string_setlength (decl, string_length (decl) - 1);
888               mangled += len;
889               return mangled;
890             }
891           break;
892
893         case 10:
894           if (strncmp (mangled, "__postblitMFZ", len+3) == 0)
895             {
896               /* Postblit symbol for a struct.  */
897               string_append (decl, "this(this)");
898               mangled += len + 3;
899               return mangled;
900             }
901           break;
902
903         case 11:
904           if (strncmp (mangled, "__InterfaceZ", len+1) == 0)
905             {
906               /* The interface symbol for a given class.  */
907               string_prepend (decl, "Interface for ");
908               string_setlength (decl, string_length (decl) - 1);
909               mangled += len;
910               return mangled;
911             }
912           break;
913
914         case 12:
915           if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0)
916             {
917               /* The ModuleInfo symbol for a given module.  */
918               string_prepend (decl, "ModuleInfo for ");
919               string_setlength (decl, string_length (decl) - 1);
920               mangled += len;
921               return mangled;
922             }
923           break;
924         }
925
926       string_appendn (decl, mangled, len);
927       mangled += len;
928     }
929
930   return mangled;
931 }
932
933 /* Extract the integer value from MANGLED and append it to DECL,
934    where TYPE is the type it should be represented as.
935    Return the remaining string on success or NULL on failure.  */
936 static const char *
937 dlang_parse_integer (string *decl, const char *mangled, char type)
938 {
939   if (type == 'a' || type == 'u' || type == 'w')
940     {
941       /* Parse character value.  */
942       char value[10];
943       int pos = 10;
944       int width = 0;
945       long val;
946
947       mangled = dlang_number (mangled, &val);
948       if (mangled == NULL)
949         return NULL;
950
951       string_append (decl, "'");
952
953       if (type == 'a' && val >= 0x20 && val < 0x7F)
954         {
955           /* Represent as a character literal.  */
956           char c = (char) val;
957           string_appendn (decl, &c, 1);
958         }
959       else
960         {
961           /* Represent as a hexadecimal value.  */
962           switch (type)
963             {
964             case 'a': /* char */
965               string_append (decl, "\\x");
966               width = 2;
967               break;
968             case 'u': /* wchar */
969               string_append (decl, "\\u");
970               width = 4;
971               break;
972             case 'w': /* dchar */
973               string_append (decl, "\\U");
974               width = 8;
975               break;
976             }
977
978           while (val > 0)
979             {
980               int digit = val % 16;
981
982               if (digit < 10)
983                 value[--pos] = (char)(digit + '0');
984               else
985                 value[--pos] = (char)((digit - 10) + 'a');
986
987               val /= 16;
988               width--;
989             }
990
991           for (; width > 0; width--)
992             value[--pos] = '0';
993
994           string_appendn (decl, &(value[pos]), 10 - pos);
995         }
996       string_append (decl, "'");
997     }
998   else if (type == 'b')
999     {
1000       /* Parse boolean value.  */
1001       long val;
1002
1003       mangled = dlang_number (mangled, &val);
1004       if (mangled == NULL)
1005         return NULL;
1006
1007       string_append (decl, val ? "true" : "false");
1008     }
1009   else
1010     {
1011       /* Parse integer value.  */
1012       const char *numptr = mangled;
1013       size_t num = 0;
1014
1015       if (! ISDIGIT (*mangled))
1016         return NULL;
1017
1018       while (ISDIGIT (*mangled))
1019         {
1020           num++;
1021           mangled++;
1022         }
1023       string_appendn (decl, numptr, num);
1024
1025       /* Append suffix.  */
1026       switch (type)
1027         {
1028         case 'h': /* ubyte */
1029         case 't': /* ushort */
1030         case 'k': /* uint */
1031           string_append (decl, "u");
1032           break;
1033         case 'l': /* long */
1034           string_append (decl, "L");
1035           break;
1036         case 'm': /* ulong */
1037           string_append (decl, "uL");
1038           break;
1039         }
1040     }
1041
1042   return mangled;
1043 }
1044
1045 /* Extract the floating-point value from MANGLED and append it to DECL.
1046    Return the remaining string on success or NULL on failure.  */
1047 static const char *
1048 dlang_parse_real (string *decl, const char *mangled)
1049 {
1050   /* Handle NAN and +-INF.  */
1051   if (strncmp (mangled, "NAN", 3) == 0)
1052     {
1053       string_append (decl, "NaN");
1054       mangled += 3;
1055       return mangled;
1056     }
1057   else if (strncmp (mangled, "INF", 3) == 0)
1058     {
1059       string_append (decl, "Inf");
1060       mangled += 3;
1061       return mangled;
1062     }
1063   else if (strncmp (mangled, "NINF", 4) == 0)
1064     {
1065       string_append (decl, "-Inf");
1066       mangled += 4;
1067       return mangled;
1068     }
1069
1070   /* Hexadecimal prefix and leading bit.  */
1071   if (*mangled == 'N')
1072     {
1073       string_append (decl, "-");
1074       mangled++;
1075     }
1076
1077   if (!ISXDIGIT (*mangled))
1078     return NULL;
1079
1080   string_append (decl, "0x");
1081   string_appendn (decl, mangled, 1);
1082   string_append (decl, ".");
1083   mangled++;
1084
1085   /* Significand.  */
1086   while (ISXDIGIT (*mangled))
1087     {
1088       string_appendn (decl, mangled, 1);
1089       mangled++;
1090     }
1091
1092   /* Exponent.  */
1093   if (*mangled != 'P')
1094     return NULL;
1095
1096   string_append (decl, "p");
1097   mangled++;
1098
1099   if (*mangled == 'N')
1100     {
1101       string_append (decl, "-");
1102       mangled++;
1103     }
1104
1105   while (ISDIGIT (*mangled))
1106     {
1107       string_appendn (decl, mangled, 1);
1108       mangled++;
1109     }
1110
1111   return mangled;
1112 }
1113
1114 /* Extract the string value from MANGLED and append it to DECL.
1115    Return the remaining string on success or NULL on failure.  */
1116 static const char *
1117 dlang_parse_string (string *decl, const char *mangled)
1118 {
1119   char type = *mangled;
1120   long len;
1121
1122   mangled++;
1123   mangled = dlang_number (mangled, &len);
1124   if (mangled == NULL || *mangled != '_')
1125     return NULL;
1126
1127   mangled++;
1128   string_append (decl, "\"");
1129   while (len--)
1130     {
1131       char val;
1132       const char *endptr = dlang_hexdigit (mangled, &val);
1133
1134       if (endptr == NULL)
1135         return NULL;
1136
1137       /* Sanitize white and non-printable characters.  */
1138       switch (val)
1139         {
1140         case ' ':
1141           string_append (decl, " ");
1142           break;
1143         case '\t':
1144           string_append (decl, "\\t");
1145           break;
1146         case '\n':
1147           string_append (decl, "\\n");
1148           break;
1149         case '\r':
1150           string_append (decl, "\\r");
1151           break;
1152         case '\f':
1153           string_append (decl, "\\f");
1154           break;
1155         case '\v':
1156           string_append (decl, "\\v");
1157           break;
1158
1159         default:
1160           if (ISPRINT (val))
1161             string_appendn (decl, &val, 1);
1162           else
1163             {
1164               string_append (decl, "\\x");
1165               string_appendn (decl, mangled, 2);
1166             }
1167         }
1168
1169       mangled = endptr;
1170     }
1171   string_append (decl, "\"");
1172
1173   if (type != 'a')
1174     string_appendn (decl, &type, 1);
1175
1176   return mangled;
1177 }
1178
1179 /* Extract the static array value from MANGLED and append it to DECL.
1180    Return the remaining string on success or NULL on failure.  */
1181 static const char *
1182 dlang_parse_arrayliteral (string *decl, const char *mangled)
1183 {
1184   long elements;
1185
1186   mangled = dlang_number (mangled, &elements);
1187   if (mangled == NULL)
1188     return NULL;
1189
1190   string_append (decl, "[");
1191   while (elements--)
1192     {
1193       mangled = dlang_value (decl, mangled, NULL, '\0');
1194       if (elements != 0)
1195         string_append (decl, ", ");
1196     }
1197
1198   string_append (decl, "]");
1199   return mangled;
1200 }
1201
1202 /* Extract the associative array value from MANGLED and append it to DECL.
1203    Return the remaining string on success or NULL on failure.  */
1204 static const char *
1205 dlang_parse_assocarray (string *decl, const char *mangled)
1206 {
1207   long elements;
1208
1209   mangled = dlang_number (mangled, &elements);
1210   if (mangled == NULL)
1211     return NULL;
1212
1213   string_append (decl, "[");
1214   while (elements--)
1215     {
1216       mangled = dlang_value (decl, mangled, NULL, '\0');
1217       string_append (decl, ":");
1218       mangled = dlang_value (decl, mangled, NULL, '\0');
1219
1220       if (elements != 0)
1221         string_append (decl, ", ");
1222     }
1223
1224   string_append (decl, "]");
1225   return mangled;
1226 }
1227
1228 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1229    Return the remaining string on success or NULL on failure.  */
1230 static const char *
1231 dlang_parse_structlit (string *decl, const char *mangled, const char *name)
1232 {
1233   long args;
1234
1235   mangled = dlang_number (mangled, &args);
1236   if (mangled == NULL)
1237     return NULL;
1238
1239   if (name != NULL)
1240     string_append (decl, name);
1241
1242   string_append (decl, "(");
1243   while (args--)
1244     {
1245       mangled = dlang_value (decl, mangled, NULL, '\0');
1246       if (args != 0)
1247         string_append (decl, ", ");
1248     }
1249
1250   string_append (decl, ")");
1251   return mangled;
1252 }
1253
1254 /* Extract the value from MANGLED and append it to DECL.
1255    Return the remaining string on success or NULL on failure.  */
1256 static const char *
1257 dlang_value (string *decl, const char *mangled, const char *name, char type)
1258 {
1259   if (mangled == NULL || *mangled == '\0')
1260     return NULL;
1261
1262   switch (*mangled)
1263     {
1264       /* Null value.  */
1265     case 'n':
1266       mangled++;
1267       string_append (decl, "null");
1268       break;
1269
1270       /* Integral values.  */
1271     case 'N':
1272       mangled++;
1273       string_append (decl, "-");
1274       mangled = dlang_parse_integer (decl, mangled, type);
1275       break;
1276
1277     case 'i':
1278       mangled++;
1279       /* Fall through */
1280
1281       /* There really should always be an `i' before encoded numbers, but there
1282          wasn't in early versions of D2, so this case range must remain for
1283          backwards compatibility.  */
1284     case '0': case '1': case '2': case '3': case '4':
1285     case '5': case '6': case '7': case '8': case '9':
1286       mangled = dlang_parse_integer (decl, mangled, type);
1287       break;
1288
1289       /* Real value.  */
1290     case 'e':
1291       mangled++;
1292       mangled = dlang_parse_real (decl, mangled);
1293       break;
1294
1295       /* Complex value.  */
1296     case 'c':
1297       mangled++;
1298       mangled = dlang_parse_real (decl, mangled);
1299       string_append (decl, "+");
1300       if (mangled == NULL || *mangled != 'c')
1301         return NULL;
1302       mangled++;
1303       mangled = dlang_parse_real (decl, mangled);
1304       string_append (decl, "i");
1305       break;
1306
1307       /* String values.  */
1308     case 'a': /* UTF8 */
1309     case 'w': /* UTF16 */
1310     case 'd': /* UTF32 */
1311       mangled = dlang_parse_string (decl, mangled);
1312       break;
1313
1314       /* Array values.  */
1315     case 'A':
1316       mangled++;
1317       if (type == 'H')
1318         mangled = dlang_parse_assocarray (decl, mangled);
1319       else
1320         mangled = dlang_parse_arrayliteral (decl, mangled);
1321       break;
1322
1323       /* Struct values.  */
1324     case 'S':
1325       mangled++;
1326       mangled = dlang_parse_structlit (decl, mangled, name);
1327       break;
1328
1329     default:
1330       return NULL;
1331     }
1332
1333   return mangled;
1334 }
1335
1336 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1337    Returns the remaining signature on success or NULL on failure.  */
1338 static const char *
1339 dlang_parse_mangle (string *decl, const char *mangled,
1340                     enum dlang_symbol_kinds kind)
1341 {
1342   /* A D mangled symbol is comprised of both scope and type information.
1343
1344         MangleName:
1345             _D QualifiedName Type
1346             _D QualifiedName M Type
1347             _D QualifiedName Z
1348             ^
1349      The caller should have guaranteed that the start pointer is at the
1350      above location.
1351    */
1352   mangled += 2;
1353
1354   mangled = dlang_parse_qualified (decl, mangled, dlang_top_level);
1355
1356   if (mangled != NULL)
1357     {
1358       /* Artificial symbols end with 'Z' and have no type.  */
1359       if (*mangled == 'Z')
1360         mangled++;
1361       else
1362         {
1363           string mods;
1364           int saved;
1365
1366           /* Skip over 'this' parameter.  */
1367           if (*mangled == 'M')
1368             mangled++;
1369
1370           /* Save the type modifiers for appending at the end if needed.  */
1371           string_init (&mods);
1372           mangled = dlang_type_modifiers (&mods, mangled);
1373
1374           if (mangled && dlang_call_convention_p (mangled))
1375             {
1376               /* Skip over calling convention and attributes.  */
1377               saved = string_length (decl);
1378               mangled = dlang_call_convention (decl, mangled);
1379               mangled = dlang_attributes (decl, mangled);
1380               string_setlength (decl, saved);
1381
1382               string_append (decl, "(");
1383               mangled = dlang_function_args (decl, mangled);
1384               string_append (decl, ")");
1385
1386               /* Add any const/immutable/shared modifier. */
1387               string_appendn (decl, mods.b, string_length (&mods));
1388             }
1389
1390           /* Consume the decl type of symbol.  */
1391           saved = string_length (decl);
1392           mangled = dlang_type (decl, mangled);
1393           string_setlength (decl, saved);
1394
1395           string_delete (&mods);
1396         }
1397     }
1398
1399   /* Check that the entire symbol was successfully demangled.  */
1400   if (kind == dlang_top_level)
1401     {
1402       if (mangled == NULL || *mangled != '\0')
1403         return NULL;
1404     }
1405
1406   return mangled;
1407 }
1408
1409 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1410    Returns the remaining signature on success or NULL on failure.  */
1411 static const char *
1412 dlang_parse_qualified (string *decl, const char *mangled,
1413                        enum dlang_symbol_kinds kind)
1414 {
1415   /* Qualified names are identifiers separated by their encoded length.
1416      Nested functions also encode their argument types without specifying
1417      what they return.
1418
1419         QualifiedName:
1420             SymbolName
1421             SymbolName QualifiedName
1422             SymbolName TypeFunctionNoReturn QualifiedName
1423             SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName
1424             ^
1425      The start pointer should be at the above location.
1426    */
1427   size_t n = 0;
1428   do
1429     {
1430       if (n++)
1431         string_append (decl, ".");
1432
1433       /* Skip over anonymous symbols.  */
1434       while (*mangled == '0')
1435         mangled++;
1436
1437       mangled = dlang_identifier (decl, mangled, kind);
1438
1439       /* Consume the encoded arguments.  However if this is not followed by the
1440          next encoded length, then this is not a continuation of a qualified
1441          name, in which case we backtrack and return the current unconsumed
1442          position of the mangled decl.  */
1443       if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
1444         {
1445           const char *start = mangled;
1446           int saved = string_length (decl);
1447
1448           /* Skip over 'this' parameter and type modifiers.  */
1449           if (*mangled == 'M')
1450             {
1451               mangled++;
1452               mangled = dlang_type_modifiers (decl, mangled);
1453               string_setlength (decl, saved);
1454             }
1455
1456           /* The rule we expect to match in the mangled string is:
1457
1458                 TypeFunctionNoReturn:
1459                     CallConvention FuncAttrs Arguments ArgClose
1460
1461              The calling convention and function attributes are not included
1462              in the demangled string.  */
1463           mangled = dlang_call_convention (decl, mangled);
1464           mangled = dlang_attributes (decl, mangled);
1465           string_setlength (decl, saved);
1466
1467           string_append (decl, "(");
1468           mangled = dlang_function_args (decl, mangled);
1469           string_append (decl, ")");
1470
1471           if (mangled == NULL || !ISDIGIT (*mangled))
1472             {
1473               /* Did not match the rule we were looking for.  */
1474               mangled = start;
1475               string_setlength (decl, saved);
1476             }
1477         }
1478     }
1479   while (mangled && ISDIGIT (*mangled));
1480
1481   return mangled;
1482 }
1483
1484 /* Demangle the tuple from MANGLED and append it to DECL.
1485    Return the remaining string on success or NULL on failure.  */
1486 static const char *
1487 dlang_parse_tuple (string *decl, const char *mangled)
1488 {
1489   long elements;
1490
1491   mangled = dlang_number (mangled, &elements);
1492   if (mangled == NULL)
1493     return NULL;
1494
1495   string_append (decl, "Tuple!(");
1496
1497   while (elements--)
1498     {
1499       mangled = dlang_type (decl, mangled);
1500       if (elements != 0)
1501         string_append (decl, ", ");
1502     }
1503
1504   string_append (decl, ")");
1505   return mangled;
1506 }
1507
1508 /* Demangle the argument list from MANGLED and append it to DECL.
1509    Return the remaining string on success or NULL on failure.  */
1510 static const char *
1511 dlang_template_args (string *decl, const char *mangled)
1512 {
1513   size_t n = 0;
1514
1515   while (mangled && *mangled != '\0')
1516     {
1517       switch (*mangled)
1518         {
1519         case 'Z': /* End of parameter list.  */
1520           mangled++;
1521           return mangled;
1522         }
1523
1524       if (n++)
1525         string_append (decl, ", ");
1526
1527       /* Skip over specialised template prefix.  */
1528       if (*mangled == 'H')
1529         mangled++;
1530
1531       switch (*mangled)
1532         {
1533         case 'S': /* Symbol parameter.  */
1534           mangled++;
1535           mangled = dlang_identifier (decl, mangled, dlang_template_param);
1536           break;
1537         case 'T': /* Type parameter.  */
1538           mangled++;
1539           mangled = dlang_type (decl, mangled);
1540           break;
1541         case 'V': /* Value parameter.  */
1542         {
1543           string name;
1544           char type;
1545
1546           /* Peek at the type.  */
1547           mangled++;
1548           type = *mangled;
1549
1550           /* In the few instances where the type is actually desired in
1551              the output, it should precede the value from dlang_value.  */
1552           string_init (&name);
1553           mangled = dlang_type (&name, mangled);
1554           string_need (&name, 1);
1555           *(name.p) = '\0';
1556
1557           mangled = dlang_value (decl, mangled, name.b, type);
1558           string_delete (&name);
1559           break;
1560         }
1561
1562         default:
1563           return NULL;
1564         }
1565     }
1566
1567   return mangled;
1568 }
1569
1570 /* Extract and demangle the template symbol in MANGLED, expected to
1571    be made up of LEN characters, and append it to DECL.
1572    Returns the remaining signature on success or NULL on failure.  */
1573 static const char *
1574 dlang_parse_template (string *decl, const char *mangled, long len)
1575 {
1576   const char *start = mangled;
1577
1578   /* Template instance names have the types and values of its parameters
1579      encoded into it.
1580
1581         TemplateInstanceName:
1582             Number __T LName TemplateArgs Z
1583             Number __U LName TemplateArgs Z
1584                    ^
1585      The start pointer should be at the above location, and LEN should be
1586      the value of the decoded number.
1587    */
1588
1589   /* Template symbol.  */
1590   if (!ISDIGIT (mangled[3]) || mangled[3] == '0')
1591     return NULL;
1592
1593   mangled += 3;
1594
1595   /* Template identifier.  */
1596   mangled = dlang_identifier (decl, mangled, dlang_template_ident);
1597
1598   /* Template arguments.  */
1599   string_append (decl, "!(");
1600   mangled = dlang_template_args (decl, mangled);
1601   string_append (decl, ")");
1602
1603   /* Check for template name length mismatch.  */
1604   if (mangled && (mangled - start) != len)
1605     return NULL;
1606
1607   return mangled;
1608 }
1609
1610 /* Extract and demangle the symbol in MANGLED.  Returns the demangled
1611    signature on success or NULL on failure.  */
1612
1613 char *
1614 dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
1615 {
1616   string decl;
1617   char *demangled = NULL;
1618
1619   if (mangled == NULL || *mangled == '\0')
1620     return NULL;
1621
1622   if (strncmp (mangled, "_D", 2) != 0)
1623     return NULL;
1624
1625   string_init (&decl);
1626
1627   if (strcmp (mangled, "_Dmain") == 0)
1628     {
1629       string_append (&decl, "D main");
1630     }
1631   else
1632     {
1633       if (dlang_parse_mangle (&decl, mangled, dlang_top_level) == NULL)
1634         string_delete (&decl);
1635     }
1636
1637   if (string_length (&decl) > 0)
1638     {
1639       string_need (&decl, 1);
1640       *(decl.p) = '\0';
1641       demangled = decl.b;
1642     }
1643
1644   return demangled;
1645 }
1646