]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libiberty/d-demangle.c
1 /* Demangler for the D programming language
2 Copyright (C) 2014-2017 Free Software Foundation, Inc.
3 Written by Iain Buclaw (ibuclaw@gdcproject.org)
5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 In addition to the permissions in the GNU Library General Public
12 License, the Free Software Foundation gives you unlimited permission
13 to link the compiled version of this file into combinations with other
14 programs, and to distribute those combinations without any restriction
15 coming from the use of this file. (The Library Public License
16 restrictions do apply in other respects; for example, they cover
17 modification of the file, and distribution when not linked into a
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. */
35 #include "safe-ctype.h"
37 #include <sys/types.h>
46 #include "libiberty.h"
48 /* A mini string-handling package */
50 typedef struct string
/* Beware: these aren't required to be */
51 { /* '\0' terminated. */
52 char *b
; /* pointer to start of string */
53 char *p
; /* pointer after last character */
54 char *e
; /* pointer after end of allocated space */
58 string_need (string
*s
, int n
)
68 s
->p
= s
->b
= XNEWVEC (char, n
);
71 else if (s
->e
- s
->p
< n
)
76 s
->b
= XRESIZEVEC (char, s
->b
, n
);
83 string_delete (string
*s
)
88 s
->b
= s
->e
= s
->p
= NULL
;
93 string_init (string
*s
)
95 s
->b
= s
->p
= s
->e
= NULL
;
99 string_length (string
*s
)
109 string_setlength (string
*s
, int n
)
111 if (n
- string_length (s
) < 0)
118 string_append (string
*p
, const char *s
)
127 string_appendn (string
*p
, const char *s
, int n
)
138 string_prependn (string
*p
, const char *s
, int n
)
145 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
155 string_prepend (string
*p
, const char *s
)
157 if (s
!= NULL
&& *s
!= '\0')
159 string_prependn (p
, s
, strlen (s
));
163 /* What kinds of symbol we could be parsing. */
164 enum dlang_symbol_kinds
166 /* Top-level symbol, needs it's type checked. */
168 /* Function symbol, needs it's type checked. */
170 /* Strongly typed name, such as for classes, structs and enums. */
172 /* Template identifier. */
173 dlang_template_ident
,
174 /* Template symbol parameter. */
178 /* Prototypes for forward referenced functions */
179 static const char *dlang_function_args (string
*, const char *);
181 static const char *dlang_type (string
*, const char *);
183 static const char *dlang_value (string
*, const char *, const char *, char);
185 static const char *dlang_parse_qualified (string
*, const char *,
186 enum dlang_symbol_kinds
);
188 static const char *dlang_parse_mangle (string
*, const char *,
189 enum dlang_symbol_kinds
);
191 static const char *dlang_parse_tuple (string
*, const char *);
193 static const char *dlang_parse_template (string
*, const char *, long);
196 /* Extract the number from MANGLED, and assign the result to RET.
197 Return the remaining string on success or NULL on failure. */
199 dlang_number (const char *mangled
, long *ret
)
201 /* Return NULL if trying to extract something that isn't a digit. */
202 if (mangled
== NULL
|| !ISDIGIT (*mangled
))
207 while (ISDIGIT (*mangled
))
211 /* If an overflow occured when multiplying by ten, the result
212 will not be a multiple of ten. */
213 if ((*ret
% 10) != 0)
216 (*ret
) += mangled
[0] - '0';
220 if (*mangled
== '\0' || *ret
< 0)
226 /* Demangle the calling convention from MANGLED and append it to DECL.
227 Return the remaining string on success or NULL on failure. */
229 dlang_call_convention (string
*decl
, const char *mangled
)
231 if (mangled
== NULL
|| *mangled
== '\0')
241 string_append (decl
, "extern(C) ");
243 case 'W': /* (Windows) */
245 string_append (decl
, "extern(Windows) ");
247 case 'V': /* (Pascal) */
249 string_append (decl
, "extern(Pascal) ");
251 case 'R': /* (C++) */
253 string_append (decl
, "extern(C++) ");
255 case 'Y': /* (Objective-C) */
257 string_append (decl
, "extern(Objective-C) ");
266 /* Extract the type modifiers from MANGLED and append them to DECL.
267 Returns the remaining signature on success or NULL on failure. */
269 dlang_type_modifiers (string
*decl
, const char *mangled
)
271 if (mangled
== NULL
|| *mangled
== '\0')
276 case 'x': /* const */
278 string_append (decl
, " const");
280 case 'y': /* immutable */
282 string_append (decl
, " immutable");
284 case 'O': /* shared */
286 string_append (decl
, " shared");
287 return dlang_type_modifiers (decl
, mangled
);
290 if (*mangled
== 'g') /* wild */
293 string_append (decl
, " inout");
294 return dlang_type_modifiers (decl
, mangled
);
304 /* Demangle the D function attributes from MANGLED and append it to DECL.
305 Return the remaining string on success or NULL on failure. */
307 dlang_attributes (string
*decl
, const char *mangled
)
309 if (mangled
== NULL
|| *mangled
== '\0')
312 while (*mangled
== 'N')
319 string_append (decl
, "pure ");
321 case 'b': /* nothrow */
323 string_append (decl
, "nothrow ");
327 string_append (decl
, "ref ");
329 case 'd': /* @property */
331 string_append (decl
, "@property ");
333 case 'e': /* @trusted */
335 string_append (decl
, "@trusted ");
337 case 'f': /* @safe */
339 string_append (decl
, "@safe ");
344 /* inout parameter is represented as 'Ng'.
345 vector parameter is represented as 'Nh'.
346 return paramenter is represented as 'Nk'.
347 If we see this, then we know we're really in the
348 parameter list. Rewind and break. */
351 case 'i': /* @nogc */
353 string_append (decl
, "@nogc ");
355 case 'j': /* return */
357 string_append (decl
, "return ");
359 case 'l': /* scope */
361 string_append (decl
, "scope ");
364 default: /* unknown attribute */
373 /* Demangle the function type from MANGLED and append it to DECL.
374 Return the remaining string on success or NULL on failure. */
376 dlang_function_type (string
*decl
, const char *mangled
)
378 string attr
, args
, type
;
379 size_t szattr
, szargs
, sztype
;
381 if (mangled
== NULL
|| *mangled
== '\0')
384 /* The order of the mangled string is:
385 CallConvention FuncAttrs Arguments ArgClose Type
387 The demangled string is re-ordered as:
388 CallConvention Type Arguments FuncAttrs
394 /* Function call convention. */
395 mangled
= dlang_call_convention (decl
, mangled
);
397 /* Function attributes. */
398 mangled
= dlang_attributes (&attr
, mangled
);
399 szattr
= string_length (&attr
);
401 /* Function arguments. */
402 mangled
= dlang_function_args (&args
, mangled
);
403 szargs
= string_length (&args
);
405 /* Function return type. */
406 mangled
= dlang_type (&type
, mangled
);
407 sztype
= string_length (&type
);
409 /* Append to decl in order. */
410 string_appendn (decl
, type
.b
, sztype
);
411 string_append (decl
, "(");
412 string_appendn (decl
, args
.b
, szargs
);
413 string_append (decl
, ") ");
414 string_appendn (decl
, attr
.b
, szattr
);
416 string_delete (&attr
);
417 string_delete (&args
);
418 string_delete (&type
);
422 /* Demangle the argument list from MANGLED and append it to DECL.
423 Return the remaining string on success or NULL on failure. */
425 dlang_function_args (string
*decl
, const char *mangled
)
429 while (mangled
&& *mangled
!= '\0')
433 case 'X': /* (variadic T t...) style. */
435 string_append (decl
, "...");
437 case 'Y': /* (variadic T t, ...) style. */
440 string_append (decl
, ", ");
441 string_append (decl
, "...");
443 case 'Z': /* Normal function. */
449 string_append (decl
, ", ");
451 if (*mangled
== 'M') /* scope(T) */
454 string_append (decl
, "scope ");
457 if (mangled
[0] == 'N' && mangled
[1] == 'k') /* return(T) */
460 string_append (decl
, "return ");
465 case 'J': /* out(T) */
467 string_append (decl
, "out ");
469 case 'K': /* ref(T) */
471 string_append (decl
, "ref ");
473 case 'L': /* lazy(T) */
475 string_append (decl
, "lazy ");
478 mangled
= dlang_type (decl
, mangled
);
484 /* Demangle the type from MANGLED and append it to DECL.
485 Return the remaining string on success or NULL on failure. */
487 dlang_type (string
*decl
, const char *mangled
)
489 if (mangled
== NULL
|| *mangled
== '\0')
494 case 'O': /* shared(T) */
496 string_append (decl
, "shared(");
497 mangled
= dlang_type (decl
, mangled
);
498 string_append (decl
, ")");
500 case 'x': /* const(T) */
502 string_append (decl
, "const(");
503 mangled
= dlang_type (decl
, mangled
);
504 string_append (decl
, ")");
506 case 'y': /* immutable(T) */
508 string_append (decl
, "immutable(");
509 mangled
= dlang_type (decl
, mangled
);
510 string_append (decl
, ")");
514 if (*mangled
== 'g') /* wild(T) */
517 string_append (decl
, "inout(");
518 mangled
= dlang_type (decl
, mangled
);
519 string_append (decl
, ")");
522 else if (*mangled
== 'h') /* vector(T) */
525 string_append (decl
, "__vector(");
526 mangled
= dlang_type (decl
, mangled
);
527 string_append (decl
, ")");
532 case 'A': /* dynamic array (T[]) */
534 mangled
= dlang_type (decl
, mangled
);
535 string_append (decl
, "[]");
537 case 'G': /* static array (T[N]) */
544 while (ISDIGIT (*mangled
))
549 mangled
= dlang_type (decl
, mangled
);
550 string_append (decl
, "[");
551 string_appendn (decl
, numptr
, num
);
552 string_append (decl
, "]");
555 case 'H': /* associative array (T[T]) */
562 mangled
= dlang_type (&type
, mangled
);
563 sztype
= string_length (&type
);
565 mangled
= dlang_type (decl
, mangled
);
566 string_append (decl
, "[");
567 string_appendn (decl
, type
.b
, sztype
);
568 string_append (decl
, "]");
570 string_delete (&type
);
573 case 'P': /* pointer (T*) */
575 /* Function pointer types don't include the trailing asterisk. */
578 case 'F': case 'U': case 'W':
579 case 'V': case 'R': case 'Y':
580 mangled
= dlang_function_type (decl
, mangled
);
581 string_append (decl
, "function");
584 mangled
= dlang_type (decl
, mangled
);
585 string_append (decl
, "*");
587 case 'I': /* ident T */
588 case 'C': /* class T */
589 case 'S': /* struct T */
590 case 'E': /* enum T */
591 case 'T': /* typedef T */
593 return dlang_parse_qualified (decl
, mangled
, dlang_type_name
);
594 case 'D': /* delegate T */
601 mangled
= dlang_type_modifiers (&mods
, mangled
);
602 szmods
= string_length (&mods
);
604 mangled
= dlang_function_type (decl
, mangled
);
605 string_append (decl
, "delegate");
606 string_appendn (decl
, mods
.b
, szmods
);
608 string_delete (&mods
);
611 case 'B': /* tuple T */
613 return dlang_parse_tuple (decl
, mangled
);
618 string_append (decl
, "none");
622 string_append (decl
, "void");
626 string_append (decl
, "byte");
630 string_append (decl
, "ubyte");
634 string_append (decl
, "short");
638 string_append (decl
, "ushort");
642 string_append (decl
, "int");
646 string_append (decl
, "uint");
650 string_append (decl
, "long");
654 string_append (decl
, "ulong");
658 string_append (decl
, "float");
662 string_append (decl
, "double");
666 string_append (decl
, "real");
669 /* Imaginary and Complex types */
672 string_append (decl
, "ifloat");
676 string_append (decl
, "idouble");
680 string_append (decl
, "ireal");
684 string_append (decl
, "cfloat");
688 string_append (decl
, "cdouble");
692 string_append (decl
, "creal");
698 string_append (decl
, "bool");
702 string_append (decl
, "char");
706 string_append (decl
, "wchar");
710 string_append (decl
, "dchar");
718 string_append (decl
, "cent");
722 string_append (decl
, "ucent");
727 default: /* unhandled */
732 /* Extract the identifier from MANGLED and append it to DECL.
733 Return the remaining string on success or NULL on failure. */
735 dlang_identifier (string
*decl
, const char *mangled
,
736 enum dlang_symbol_kinds kind
)
739 const char *endptr
= dlang_number (mangled
, &len
);
741 if (endptr
== NULL
|| len
== 0)
744 /* In template parameter symbols, the first character of the mangled
745 name can be a digit. This causes ambiguity issues because the
746 digits of the two numbers are adjacent. */
747 if (kind
== dlang_template_param
)
751 int saved
= string_length (decl
);
753 /* Work backwards until a match is found. */
754 for (pend
= endptr
; endptr
!= NULL
; pend
--)
758 /* Reached the beginning of the pointer to the name length,
759 try parsing the entire symbol. */
767 /* Check whether template parameter is a function with a valid
768 return type or an untyped identifier. */
769 if (ISDIGIT (*mangled
))
770 mangled
= dlang_parse_qualified (decl
, mangled
,
771 dlang_template_ident
);
772 else if (strncmp (mangled
, "_D", 2) == 0)
773 mangled
= dlang_parse_mangle (decl
, mangled
, dlang_function
);
775 /* Check for name length mismatch. */
776 if (mangled
&& (mangled
- pend
) == psize
)
780 string_setlength (decl
, saved
);
783 /* No match on any combinations. */
788 if (strlen (endptr
) < (size_t) len
)
793 /* May be a template instance. */
794 if (len
>= 5 && mangled
[0] == '_' && mangled
[1] == '_'
795 && (mangled
[2] == 'T' || mangled
[2] == 'U'))
796 return dlang_parse_template (decl
, mangled
, len
);
801 if (strncmp (mangled
, "__ctor", len
) == 0)
803 /* Constructor symbol for a class/struct. */
804 string_append (decl
, "this");
808 else if (strncmp (mangled
, "__dtor", len
) == 0)
810 /* Destructor symbol for a class/struct. */
811 string_append (decl
, "~this");
815 else if (strncmp (mangled
, "__initZ", len
+1) == 0)
817 /* The static initialiser for a given symbol. */
818 string_append (decl
, "init$");
822 else if (strncmp (mangled
, "__vtblZ", len
+1) == 0)
824 /* The vtable symbol for a given class. */
825 string_prepend (decl
, "vtable for ");
826 string_setlength (decl
, string_length (decl
) - 1);
833 if (strncmp (mangled
, "__ClassZ", len
+1) == 0)
835 /* The classinfo symbol for a given class. */
836 string_prepend (decl
, "ClassInfo for ");
837 string_setlength (decl
, string_length (decl
) - 1);
844 if (strncmp (mangled
, "__postblitMFZ", len
+3) == 0)
846 /* Postblit symbol for a struct. */
847 string_append (decl
, "this(this)");
854 if (strncmp (mangled
, "__InterfaceZ", len
+1) == 0)
856 /* The interface symbol for a given class. */
857 string_prepend (decl
, "Interface for ");
858 string_setlength (decl
, string_length (decl
) - 1);
865 if (strncmp (mangled
, "__ModuleInfoZ", len
+1) == 0)
867 /* The ModuleInfo symbol for a given module. */
868 string_prepend (decl
, "ModuleInfo for ");
869 string_setlength (decl
, string_length (decl
) - 1);
876 string_appendn (decl
, mangled
, len
);
883 /* Extract the integer value from MANGLED and append it to DECL,
884 where TYPE is the type it should be represented as.
885 Return the remaining string on success or NULL on failure. */
887 dlang_parse_integer (string
*decl
, const char *mangled
, char type
)
889 if (type
== 'a' || type
== 'u' || type
== 'w')
891 /* Parse character value. */
897 mangled
= dlang_number (mangled
, &val
);
901 string_append (decl
, "'");
903 if (type
== 'a' && val
>= 0x20 && val
< 0x7F)
905 /* Represent as a character literal. */
907 string_appendn (decl
, &c
, 1);
911 /* Represent as a hexadecimal value. */
915 string_append (decl
, "\\x");
918 case 'u': /* wchar */
919 string_append (decl
, "\\u");
922 case 'w': /* dchar */
923 string_append (decl
, "\\U");
930 int digit
= val
% 16;
933 value
[--pos
] = (char)(digit
+ '0');
935 value
[--pos
] = (char)((digit
- 10) + 'a');
941 for (; width
> 0; width
--)
944 string_appendn (decl
, &(value
[pos
]), 10 - pos
);
946 string_append (decl
, "'");
948 else if (type
== 'b')
950 /* Parse boolean value. */
953 mangled
= dlang_number (mangled
, &val
);
957 string_append (decl
, val
? "true" : "false");
961 /* Parse integer value. */
962 const char *numptr
= mangled
;
965 if (! ISDIGIT (*mangled
))
968 while (ISDIGIT (*mangled
))
973 string_appendn (decl
, numptr
, num
);
978 case 'h': /* ubyte */
979 case 't': /* ushort */
981 string_append (decl
, "u");
984 string_append (decl
, "L");
986 case 'm': /* ulong */
987 string_append (decl
, "uL");
995 /* Extract the floating-point value from MANGLED and append it to DECL.
996 Return the remaining string on success or NULL on failure. */
998 dlang_parse_real (string
*decl
, const char *mangled
)
1003 /* Handle NAN and +-INF. */
1004 if (strncmp (mangled
, "NAN", 3) == 0)
1006 string_append (decl
, "NaN");
1010 else if (strncmp (mangled
, "INF", 3) == 0)
1012 string_append (decl
, "Inf");
1016 else if (strncmp (mangled
, "NINF", 4) == 0)
1018 string_append (decl
, "-Inf");
1023 /* Hexadecimal prefix and leading bit. */
1024 if (*mangled
== 'N')
1026 buffer
[len
++] = '-';
1030 if (!ISXDIGIT (*mangled
))
1033 buffer
[len
++] = '0';
1034 buffer
[len
++] = 'x';
1035 buffer
[len
++] = *mangled
;
1036 buffer
[len
++] = '.';
1040 while (ISXDIGIT (*mangled
))
1042 buffer
[len
++] = *mangled
;
1047 if (*mangled
!= 'P')
1050 buffer
[len
++] = 'p';
1053 if (*mangled
== 'N')
1055 buffer
[len
++] = '-';
1059 while (ISDIGIT (*mangled
))
1061 buffer
[len
++] = *mangled
;
1065 /* Write out the demangled hexadecimal, rather than trying to
1066 convert the buffer into a floating-point value. */
1068 len
= strlen (buffer
);
1069 string_appendn (decl
, buffer
, len
);
1073 /* Convert VAL from an ascii hexdigit to value. */
1075 ascii2hex (char val
)
1077 if (val
>= 'a' && val
<= 'f')
1078 return (val
- 'a' + 10);
1080 if (val
>= 'A' && val
<= 'F')
1081 return (val
- 'A' + 10);
1083 if (val
>= '0' && val
<= '9')
1089 /* Extract the string value from MANGLED and append it to DECL.
1090 Return the remaining string on success or NULL on failure. */
1092 dlang_parse_string (string
*decl
, const char *mangled
)
1094 char type
= *mangled
;
1098 mangled
= dlang_number (mangled
, &len
);
1099 if (mangled
== NULL
|| *mangled
!= '_')
1103 string_append (decl
, "\"");
1106 if (ISXDIGIT (mangled
[0]) && ISXDIGIT (mangled
[1]))
1108 char a
= ascii2hex (mangled
[0]);
1109 char b
= ascii2hex (mangled
[1]);
1110 char val
= (a
<< 4) | b
;
1112 /* Sanitize white and non-printable characters. */
1116 string_append (decl
, " ");
1119 string_append (decl
, "\\t");
1122 string_append (decl
, "\\n");
1125 string_append (decl
, "\\r");
1128 string_append (decl
, "\\f");
1131 string_append (decl
, "\\v");
1136 string_appendn (decl
, &val
, 1);
1139 string_append (decl
, "\\x");
1140 string_appendn (decl
, mangled
, 2);
1149 string_append (decl
, "\"");
1152 string_appendn (decl
, &type
, 1);
1157 /* Extract the static array value from MANGLED and append it to DECL.
1158 Return the remaining string on success or NULL on failure. */
1160 dlang_parse_arrayliteral (string
*decl
, const char *mangled
)
1164 mangled
= dlang_number (mangled
, &elements
);
1165 if (mangled
== NULL
)
1168 string_append (decl
, "[");
1171 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1173 string_append (decl
, ", ");
1176 string_append (decl
, "]");
1180 /* Extract the associative array value from MANGLED and append it to DECL.
1181 Return the remaining string on success or NULL on failure. */
1183 dlang_parse_assocarray (string
*decl
, const char *mangled
)
1187 mangled
= dlang_number (mangled
, &elements
);
1188 if (mangled
== NULL
)
1191 string_append (decl
, "[");
1194 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1195 string_append (decl
, ":");
1196 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1199 string_append (decl
, ", ");
1202 string_append (decl
, "]");
1206 /* Extract the struct literal value for NAME from MANGLED and append it to DECL.
1207 Return the remaining string on success or NULL on failure. */
1209 dlang_parse_structlit (string
*decl
, const char *mangled
, const char *name
)
1213 mangled
= dlang_number (mangled
, &args
);
1214 if (mangled
== NULL
)
1218 string_append (decl
, name
);
1220 string_append (decl
, "(");
1223 mangled
= dlang_value (decl
, mangled
, NULL
, '\0');
1225 string_append (decl
, ", ");
1228 string_append (decl
, ")");
1232 /* Extract the value from MANGLED and append it to DECL.
1233 Return the remaining string on success or NULL on failure. */
1235 dlang_value (string
*decl
, const char *mangled
, const char *name
, char type
)
1237 if (mangled
== NULL
|| *mangled
== '\0')
1245 string_append (decl
, "null");
1248 /* Integral values. */
1251 string_append (decl
, "-");
1252 mangled
= dlang_parse_integer (decl
, mangled
, type
);
1259 /* There really should always be an `i' before encoded numbers, but there
1260 wasn't in early versions of D2, so this case range must remain for
1261 backwards compatibility. */
1262 case '0': case '1': case '2': case '3': case '4':
1263 case '5': case '6': case '7': case '8': case '9':
1264 mangled
= dlang_parse_integer (decl
, mangled
, type
);
1270 mangled
= dlang_parse_real (decl
, mangled
);
1273 /* Complex value. */
1276 mangled
= dlang_parse_real (decl
, mangled
);
1277 string_append (decl
, "+");
1278 if (mangled
== NULL
|| *mangled
!= 'c')
1281 mangled
= dlang_parse_real (decl
, mangled
);
1282 string_append (decl
, "i");
1285 /* String values. */
1286 case 'a': /* UTF8 */
1287 case 'w': /* UTF16 */
1288 case 'd': /* UTF32 */
1289 mangled
= dlang_parse_string (decl
, mangled
);
1296 mangled
= dlang_parse_assocarray (decl
, mangled
);
1298 mangled
= dlang_parse_arrayliteral (decl
, mangled
);
1301 /* Struct values. */
1304 mangled
= dlang_parse_structlit (decl
, mangled
, name
);
1314 /* Extract the function calling convention from MANGLED and
1315 return 1 on success or 0 on failure. */
1317 dlang_call_convention_p (const char *mangled
)
1321 case 'F': case 'U': case 'V':
1322 case 'W': case 'R': case 'Y':
1330 /* Extract and demangle the symbol in MANGLED and append it to DECL.
1331 Returns the remaining signature on success or NULL on failure. */
1333 dlang_parse_mangle (string
*decl
, const char *mangled
,
1334 enum dlang_symbol_kinds kind
)
1336 /* A D mangled symbol is comprised of both scope and type information.
1339 _D QualifiedName Type
1340 _D QualifiedName M Type
1343 The caller should have guaranteed that the start pointer is at the
1348 mangled
= dlang_parse_qualified (decl
, mangled
, dlang_top_level
);
1350 if (mangled
!= NULL
)
1352 /* Artificial symbols end with 'Z' and have no type. */
1353 if (*mangled
== 'Z')
1360 /* Skip over 'this' parameter. */
1361 if (*mangled
== 'M')
1364 /* Save the type modifiers for appending at the end if needed. */
1365 string_init (&mods
);
1366 mangled
= dlang_type_modifiers (&mods
, mangled
);
1368 if (mangled
&& dlang_call_convention_p (mangled
))
1370 /* Skip over calling convention and attributes. */
1371 saved
= string_length (decl
);
1372 mangled
= dlang_call_convention (decl
, mangled
);
1373 mangled
= dlang_attributes (decl
, mangled
);
1374 string_setlength (decl
, saved
);
1376 string_append (decl
, "(");
1377 mangled
= dlang_function_args (decl
, mangled
);
1378 string_append (decl
, ")");
1380 /* Add any const/immutable/shared modifier. */
1381 string_appendn (decl
, mods
.b
, string_length (&mods
));
1384 /* Consume the decl type of symbol. */
1385 saved
= string_length (decl
);
1386 mangled
= dlang_type (decl
, mangled
);
1387 string_setlength (decl
, saved
);
1389 string_delete (&mods
);
1393 /* Check that the entire symbol was successfully demangled. */
1394 if (kind
== dlang_top_level
)
1396 if (mangled
== NULL
|| *mangled
!= '\0')
1403 /* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
1404 Returns the remaining signature on success or NULL on failure. */
1406 dlang_parse_qualified (string
*decl
, const char *mangled
,
1407 enum dlang_symbol_kinds kind
)
1409 /* Qualified names are identifiers separated by their encoded length.
1410 Nested functions also encode their argument types without specifying
1415 SymbolName QualifiedName
1416 SymbolName TypeFunctionNoReturn QualifiedName
1417 SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName
1419 The start pointer should be at the above location.
1425 string_append (decl
, ".");
1427 /* Skip over anonymous symbols. */
1428 while (*mangled
== '0')
1431 mangled
= dlang_identifier (decl
, mangled
, kind
);
1433 /* Consume the encoded arguments. However if this is not followed by the
1434 next encoded length, then this is not a continuation of a qualified
1435 name, in which case we backtrack and return the current unconsumed
1436 position of the mangled decl. */
1437 if (mangled
&& (*mangled
== 'M' || dlang_call_convention_p (mangled
)))
1439 const char *start
= mangled
;
1440 int saved
= string_length (decl
);
1442 /* Skip over 'this' parameter and type modifiers. */
1443 if (*mangled
== 'M')
1446 mangled
= dlang_type_modifiers (decl
, mangled
);
1447 string_setlength (decl
, saved
);
1450 /* The rule we expect to match in the mangled string is:
1452 TypeFunctionNoReturn:
1453 CallConvention FuncAttrs Arguments ArgClose
1455 The calling convention and function attributes are not included
1456 in the demangled string. */
1457 mangled
= dlang_call_convention (decl
, mangled
);
1458 mangled
= dlang_attributes (decl
, mangled
);
1459 string_setlength (decl
, saved
);
1461 string_append (decl
, "(");
1462 mangled
= dlang_function_args (decl
, mangled
);
1463 string_append (decl
, ")");
1465 if (mangled
== NULL
|| !ISDIGIT (*mangled
))
1467 /* Did not match the rule we were looking for. */
1469 string_setlength (decl
, saved
);
1473 while (mangled
&& ISDIGIT (*mangled
));
1478 /* Demangle the tuple from MANGLED and append it to DECL.
1479 Return the remaining string on success or NULL on failure. */
1481 dlang_parse_tuple (string
*decl
, const char *mangled
)
1485 mangled
= dlang_number (mangled
, &elements
);
1486 if (mangled
== NULL
)
1489 string_append (decl
, "Tuple!(");
1493 mangled
= dlang_type (decl
, mangled
);
1495 string_append (decl
, ", ");
1498 string_append (decl
, ")");
1502 /* Demangle the argument list from MANGLED and append it to DECL.
1503 Return the remaining string on success or NULL on failure. */
1505 dlang_template_args (string
*decl
, const char *mangled
)
1509 while (mangled
&& *mangled
!= '\0')
1513 case 'Z': /* End of parameter list. */
1519 string_append (decl
, ", ");
1521 /* Skip over specialised template prefix. */
1522 if (*mangled
== 'H')
1527 case 'S': /* Symbol parameter. */
1529 mangled
= dlang_identifier (decl
, mangled
, dlang_template_param
);
1531 case 'T': /* Type parameter. */
1533 mangled
= dlang_type (decl
, mangled
);
1535 case 'V': /* Value parameter. */
1540 /* Peek at the type. */
1544 /* In the few instances where the type is actually desired in
1545 the output, it should precede the value from dlang_value. */
1546 string_init (&name
);
1547 mangled
= dlang_type (&name
, mangled
);
1548 string_need (&name
, 1);
1551 mangled
= dlang_value (decl
, mangled
, name
.b
, type
);
1552 string_delete (&name
);
1564 /* Extract and demangle the template symbol in MANGLED, expected to
1565 be made up of LEN characters, and append it to DECL.
1566 Returns the remaining signature on success or NULL on failure. */
1568 dlang_parse_template (string
*decl
, const char *mangled
, long len
)
1570 const char *start
= mangled
;
1572 /* Template instance names have the types and values of its parameters
1575 TemplateInstanceName:
1576 Number __T LName TemplateArgs Z
1577 Number __U LName TemplateArgs Z
1579 The start pointer should be at the above location, and LEN should be
1580 the value of the decoded number.
1583 /* Template symbol. */
1584 if (!ISDIGIT (mangled
[3]) || mangled
[3] == '0')
1589 /* Template identifier. */
1590 mangled
= dlang_identifier (decl
, mangled
, dlang_template_ident
);
1592 /* Template arguments. */
1593 string_append (decl
, "!(");
1594 mangled
= dlang_template_args (decl
, mangled
);
1595 string_append (decl
, ")");
1597 /* Check for template name length mismatch. */
1598 if (mangled
&& (mangled
- start
) != len
)
1604 /* Extract and demangle the symbol in MANGLED. Returns the demangled
1605 signature on success or NULL on failure. */
1608 dlang_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
1611 char *demangled
= NULL
;
1613 if (mangled
== NULL
|| *mangled
== '\0')
1616 if (strncmp (mangled
, "_D", 2) != 0)
1619 string_init (&decl
);
1621 if (strcmp (mangled
, "_Dmain") == 0)
1623 string_append (&decl
, "D main");
1627 if (dlang_parse_mangle (&decl
, mangled
, dlang_top_level
) == NULL
)
1628 string_delete (&decl
);
1631 if (string_length (&decl
) > 0)
1633 string_need (&decl
, 1);