1 1.1 mrg /* Demangler for the D programming language 2 1.1.1.10 mrg Copyright (C) 2014-2024 Free Software Foundation, Inc. 3 1.1 mrg Written by Iain Buclaw (ibuclaw (at) gdcproject.org) 4 1.1 mrg 5 1.1 mrg This file is part of the libiberty library. 6 1.1 mrg Libiberty is free software; you can redistribute it and/or 7 1.1 mrg modify it under the terms of the GNU Library General Public 8 1.1 mrg License as published by the Free Software Foundation; either 9 1.1 mrg version 2 of the License, or (at your option) any later version. 10 1.1 mrg 11 1.1 mrg In addition to the permissions in the GNU Library General Public 12 1.1 mrg License, the Free Software Foundation gives you unlimited permission 13 1.1 mrg to link the compiled version of this file into combinations with other 14 1.1 mrg programs, and to distribute those combinations without any restriction 15 1.1 mrg coming from the use of this file. (The Library Public License 16 1.1 mrg restrictions do apply in other respects; for example, they cover 17 1.1 mrg modification of the file, and distribution when not linked into a 18 1.1 mrg combined executable.) 19 1.1 mrg 20 1.1 mrg Libiberty is distributed in the hope that it will be useful, 21 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 22 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 1.1 mrg Library General Public License for more details. 24 1.1 mrg 25 1.1 mrg You should have received a copy of the GNU Library General Public 26 1.1 mrg License along with libiberty; see the file COPYING.LIB. 27 1.1 mrg If not, see <http://www.gnu.org/licenses/>. */ 28 1.1 mrg 29 1.1.1.6 mrg /* This file exports one function; dlang_demangle. */ 30 1.1 mrg 31 1.1 mrg #ifdef HAVE_CONFIG_H 32 1.1 mrg #include "config.h" 33 1.1 mrg #endif 34 1.1.1.9 mrg #ifdef HAVE_LIMITS_H 35 1.1.1.9 mrg #include <limits.h> 36 1.1.1.9 mrg #endif 37 1.1 mrg 38 1.1 mrg #include "safe-ctype.h" 39 1.1 mrg 40 1.1 mrg #include <sys/types.h> 41 1.1 mrg #include <string.h> 42 1.1 mrg #include <stdio.h> 43 1.1 mrg 44 1.1 mrg #ifdef HAVE_STDLIB_H 45 1.1 mrg #include <stdlib.h> 46 1.1 mrg #endif 47 1.1 mrg 48 1.1 mrg #include <demangle.h> 49 1.1 mrg #include "libiberty.h" 50 1.1 mrg 51 1.1.1.9 mrg #ifndef ULONG_MAX 52 1.1.1.9 mrg #define ULONG_MAX (~0UL) 53 1.1.1.9 mrg #endif 54 1.1.1.9 mrg #ifndef UINT_MAX 55 1.1.1.9 mrg #define UINT_MAX (~0U) 56 1.1.1.9 mrg #endif 57 1.1.1.9 mrg 58 1.1 mrg /* A mini string-handling package */ 59 1.1 mrg 60 1.1 mrg typedef struct string /* Beware: these aren't required to be */ 61 1.1 mrg { /* '\0' terminated. */ 62 1.1 mrg char *b; /* pointer to start of string */ 63 1.1 mrg char *p; /* pointer after last character */ 64 1.1 mrg char *e; /* pointer after end of allocated space */ 65 1.1 mrg } string; 66 1.1 mrg 67 1.1 mrg static void 68 1.1.1.9 mrg string_need (string *s, size_t n) 69 1.1 mrg { 70 1.1.1.9 mrg size_t tem; 71 1.1 mrg 72 1.1 mrg if (s->b == NULL) 73 1.1 mrg { 74 1.1 mrg if (n < 32) 75 1.1 mrg { 76 1.1 mrg n = 32; 77 1.1 mrg } 78 1.1 mrg s->p = s->b = XNEWVEC (char, n); 79 1.1 mrg s->e = s->b + n; 80 1.1 mrg } 81 1.1.1.9 mrg else if ((size_t) (s->e - s->p) < n) 82 1.1 mrg { 83 1.1 mrg tem = s->p - s->b; 84 1.1 mrg n += tem; 85 1.1 mrg n *= 2; 86 1.1 mrg s->b = XRESIZEVEC (char, s->b, n); 87 1.1 mrg s->p = s->b + tem; 88 1.1 mrg s->e = s->b + n; 89 1.1 mrg } 90 1.1 mrg } 91 1.1 mrg 92 1.1 mrg static void 93 1.1 mrg string_delete (string *s) 94 1.1 mrg { 95 1.1 mrg if (s->b != NULL) 96 1.1 mrg { 97 1.1 mrg XDELETEVEC (s->b); 98 1.1 mrg s->b = s->e = s->p = NULL; 99 1.1 mrg } 100 1.1 mrg } 101 1.1 mrg 102 1.1 mrg static void 103 1.1 mrg string_init (string *s) 104 1.1 mrg { 105 1.1 mrg s->b = s->p = s->e = NULL; 106 1.1 mrg } 107 1.1 mrg 108 1.1 mrg static int 109 1.1 mrg string_length (string *s) 110 1.1 mrg { 111 1.1 mrg if (s->p == s->b) 112 1.1 mrg { 113 1.1 mrg return 0; 114 1.1 mrg } 115 1.1 mrg return s->p - s->b; 116 1.1 mrg } 117 1.1 mrg 118 1.1 mrg static void 119 1.1 mrg string_setlength (string *s, int n) 120 1.1 mrg { 121 1.1 mrg if (n - string_length (s) < 0) 122 1.1 mrg { 123 1.1 mrg s->p = s->b + n; 124 1.1 mrg } 125 1.1 mrg } 126 1.1 mrg 127 1.1 mrg static void 128 1.1 mrg string_append (string *p, const char *s) 129 1.1 mrg { 130 1.1.1.9 mrg size_t n = strlen (s); 131 1.1 mrg string_need (p, n); 132 1.1 mrg memcpy (p->p, s, n); 133 1.1 mrg p->p += n; 134 1.1 mrg } 135 1.1 mrg 136 1.1 mrg static void 137 1.1.1.9 mrg string_appendn (string *p, const char *s, size_t n) 138 1.1 mrg { 139 1.1 mrg if (n != 0) 140 1.1 mrg { 141 1.1 mrg string_need (p, n); 142 1.1 mrg memcpy (p->p, s, n); 143 1.1 mrg p->p += n; 144 1.1 mrg } 145 1.1 mrg } 146 1.1 mrg 147 1.1 mrg static void 148 1.1.1.9 mrg string_prependn (string *p, const char *s, size_t n) 149 1.1 mrg { 150 1.1 mrg char *q; 151 1.1 mrg 152 1.1 mrg if (n != 0) 153 1.1 mrg { 154 1.1 mrg string_need (p, n); 155 1.1 mrg for (q = p->p - 1; q >= p->b; q--) 156 1.1 mrg { 157 1.1 mrg q[n] = q[0]; 158 1.1 mrg } 159 1.1 mrg memcpy (p->b, s, n); 160 1.1 mrg p->p += n; 161 1.1 mrg } 162 1.1 mrg } 163 1.1 mrg 164 1.1 mrg static void 165 1.1 mrg string_prepend (string *p, const char *s) 166 1.1 mrg { 167 1.1 mrg if (s != NULL && *s != '\0') 168 1.1 mrg { 169 1.1 mrg string_prependn (p, s, strlen (s)); 170 1.1 mrg } 171 1.1 mrg } 172 1.1 mrg 173 1.1.1.9 mrg /* Demangle information structure we pass around. */ 174 1.1.1.9 mrg struct dlang_info 175 1.1.1.2 mrg { 176 1.1.1.9 mrg /* The string we are demangling. */ 177 1.1.1.9 mrg const char *s; 178 1.1.1.9 mrg /* The index of the last back reference. */ 179 1.1.1.9 mrg int last_backref; 180 1.1.1.2 mrg }; 181 1.1.1.2 mrg 182 1.1.1.9 mrg /* Pass as the LEN to dlang_parse_template if symbol length is not known. */ 183 1.1.1.9 mrg #define TEMPLATE_LENGTH_UNKNOWN (-1UL) 184 1.1.1.9 mrg 185 1.1 mrg /* Prototypes for forward referenced functions */ 186 1.1.1.9 mrg static const char *dlang_function_type (string *, const char *, 187 1.1.1.9 mrg struct dlang_info *); 188 1.1.1.9 mrg 189 1.1.1.9 mrg static const char *dlang_function_args (string *, const char *, 190 1.1.1.9 mrg struct dlang_info *); 191 1.1 mrg 192 1.1.1.9 mrg static const char *dlang_type (string *, const char *, struct dlang_info *); 193 1.1 mrg 194 1.1.1.9 mrg static const char *dlang_value (string *, const char *, const char *, char, 195 1.1.1.9 mrg struct dlang_info *); 196 1.1 mrg 197 1.1.1.6 mrg static const char *dlang_parse_qualified (string *, const char *, 198 1.1.1.9 mrg struct dlang_info *, int); 199 1.1.1.6 mrg 200 1.1.1.6 mrg static const char *dlang_parse_mangle (string *, const char *, 201 1.1.1.9 mrg struct dlang_info *); 202 1.1 mrg 203 1.1.1.9 mrg static const char *dlang_parse_tuple (string *, const char *, 204 1.1.1.9 mrg struct dlang_info *); 205 1.1 mrg 206 1.1.1.9 mrg static const char *dlang_parse_template (string *, const char *, 207 1.1.1.9 mrg struct dlang_info *, unsigned long); 208 1.1.1.9 mrg 209 1.1.1.9 mrg static const char *dlang_lname (string *, const char *, unsigned long); 210 1.1 mrg 211 1.1 mrg 212 1.1.1.6 mrg /* Extract the number from MANGLED, and assign the result to RET. 213 1.1.1.9 mrg Return the remaining string on success or NULL on failure. 214 1.1.1.9 mrg A result larger than UINT_MAX is considered a failure. */ 215 1.1.1.6 mrg static const char * 216 1.1.1.9 mrg dlang_number (const char *mangled, unsigned long *ret) 217 1.1.1.6 mrg { 218 1.1.1.6 mrg /* Return NULL if trying to extract something that isn't a digit. */ 219 1.1.1.6 mrg if (mangled == NULL || !ISDIGIT (*mangled)) 220 1.1.1.6 mrg return NULL; 221 1.1.1.6 mrg 222 1.1.1.9 mrg unsigned long val = 0; 223 1.1.1.6 mrg 224 1.1.1.6 mrg while (ISDIGIT (*mangled)) 225 1.1.1.6 mrg { 226 1.1.1.9 mrg unsigned long digit = mangled[0] - '0'; 227 1.1.1.6 mrg 228 1.1.1.9 mrg /* Check for overflow. */ 229 1.1.1.9 mrg if (val > (UINT_MAX - digit) / 10) 230 1.1.1.6 mrg return NULL; 231 1.1.1.6 mrg 232 1.1.1.9 mrg val = val * 10 + digit; 233 1.1.1.6 mrg mangled++; 234 1.1.1.6 mrg } 235 1.1.1.6 mrg 236 1.1.1.9 mrg if (*mangled == '\0') 237 1.1.1.6 mrg return NULL; 238 1.1.1.6 mrg 239 1.1.1.9 mrg *ret = val; 240 1.1.1.6 mrg return mangled; 241 1.1.1.6 mrg } 242 1.1.1.6 mrg 243 1.1.1.6 mrg /* Extract the hex-digit from MANGLED, and assign the result to RET. 244 1.1.1.6 mrg Return the remaining string on success or NULL on failure. */ 245 1.1.1.6 mrg static const char * 246 1.1.1.6 mrg dlang_hexdigit (const char *mangled, char *ret) 247 1.1.1.6 mrg { 248 1.1.1.6 mrg char c; 249 1.1.1.6 mrg 250 1.1.1.6 mrg /* Return NULL if trying to extract something that isn't a hexdigit. */ 251 1.1.1.6 mrg if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1])) 252 1.1.1.6 mrg return NULL; 253 1.1.1.6 mrg 254 1.1.1.6 mrg c = mangled[0]; 255 1.1.1.6 mrg if (!ISDIGIT (c)) 256 1.1.1.9 mrg *ret = c - (ISUPPER (c) ? 'A' : 'a') + 10; 257 1.1.1.6 mrg else 258 1.1.1.9 mrg *ret = c - '0'; 259 1.1.1.6 mrg 260 1.1.1.6 mrg c = mangled[1]; 261 1.1.1.6 mrg if (!ISDIGIT (c)) 262 1.1.1.9 mrg *ret = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10); 263 1.1.1.6 mrg else 264 1.1.1.9 mrg *ret = (*ret << 4) | (c - '0'); 265 1.1.1.6 mrg 266 1.1.1.6 mrg mangled += 2; 267 1.1.1.6 mrg 268 1.1.1.6 mrg return mangled; 269 1.1.1.6 mrg } 270 1.1.1.6 mrg 271 1.1.1.6 mrg /* Extract the function calling convention from MANGLED and 272 1.1.1.6 mrg return 1 on success or 0 on failure. */ 273 1.1.1.6 mrg static int 274 1.1.1.6 mrg dlang_call_convention_p (const char *mangled) 275 1.1.1.6 mrg { 276 1.1.1.6 mrg switch (*mangled) 277 1.1.1.6 mrg { 278 1.1.1.6 mrg case 'F': case 'U': case 'V': 279 1.1.1.6 mrg case 'W': case 'R': case 'Y': 280 1.1.1.6 mrg return 1; 281 1.1.1.6 mrg 282 1.1.1.6 mrg default: 283 1.1.1.6 mrg return 0; 284 1.1.1.6 mrg } 285 1.1.1.6 mrg } 286 1.1.1.6 mrg 287 1.1.1.9 mrg /* Extract the back reference position from MANGLED, and assign the result 288 1.1.1.9 mrg to RET. Return the remaining string on success or NULL on failure. 289 1.1.1.9 mrg A result <= 0 is a failure. */ 290 1.1.1.9 mrg static const char * 291 1.1.1.9 mrg dlang_decode_backref (const char *mangled, long *ret) 292 1.1.1.9 mrg { 293 1.1.1.9 mrg /* Return NULL if trying to extract something that isn't a digit. */ 294 1.1.1.9 mrg if (mangled == NULL || !ISALPHA (*mangled)) 295 1.1.1.9 mrg return NULL; 296 1.1.1.9 mrg 297 1.1.1.9 mrg /* Any identifier or non-basic type that has been emitted to the mangled 298 1.1.1.9 mrg symbol before will not be emitted again, but is referenced by a special 299 1.1.1.9 mrg sequence encoding the relative position of the original occurrence in the 300 1.1.1.9 mrg mangled symbol name. 301 1.1.1.9 mrg 302 1.1.1.9 mrg Numbers in back references are encoded with base 26 by upper case letters 303 1.1.1.9 mrg A-Z for higher digits but lower case letters a-z for the last digit. 304 1.1.1.9 mrg 305 1.1.1.9 mrg NumberBackRef: 306 1.1.1.9 mrg [a-z] 307 1.1.1.9 mrg [A-Z] NumberBackRef 308 1.1.1.9 mrg ^ 309 1.1.1.9 mrg */ 310 1.1.1.9 mrg unsigned long val = 0; 311 1.1.1.9 mrg 312 1.1.1.9 mrg while (ISALPHA (*mangled)) 313 1.1.1.9 mrg { 314 1.1.1.9 mrg /* Check for overflow. */ 315 1.1.1.9 mrg if (val > (ULONG_MAX - 25) / 26) 316 1.1.1.9 mrg break; 317 1.1.1.9 mrg 318 1.1.1.9 mrg val *= 26; 319 1.1.1.9 mrg 320 1.1.1.9 mrg if (mangled[0] >= 'a' && mangled[0] <= 'z') 321 1.1.1.9 mrg { 322 1.1.1.9 mrg val += mangled[0] - 'a'; 323 1.1.1.9 mrg if ((long) val <= 0) 324 1.1.1.9 mrg break; 325 1.1.1.9 mrg *ret = val; 326 1.1.1.9 mrg return mangled + 1; 327 1.1.1.9 mrg } 328 1.1.1.9 mrg 329 1.1.1.9 mrg val += mangled[0] - 'A'; 330 1.1.1.9 mrg mangled++; 331 1.1.1.9 mrg } 332 1.1.1.9 mrg 333 1.1.1.9 mrg return NULL; 334 1.1.1.9 mrg } 335 1.1.1.9 mrg 336 1.1.1.9 mrg /* Extract the symbol pointed at by the back reference and assign the result 337 1.1.1.9 mrg to RET. Return the remaining string on success or NULL on failure. */ 338 1.1.1.9 mrg static const char * 339 1.1.1.9 mrg dlang_backref (const char *mangled, const char **ret, struct dlang_info *info) 340 1.1.1.9 mrg { 341 1.1.1.9 mrg *ret = NULL; 342 1.1.1.9 mrg 343 1.1.1.9 mrg if (mangled == NULL || *mangled != 'Q') 344 1.1.1.9 mrg return NULL; 345 1.1.1.9 mrg 346 1.1.1.9 mrg /* Position of 'Q'. */ 347 1.1.1.9 mrg const char *qpos = mangled; 348 1.1.1.9 mrg long refpos; 349 1.1.1.9 mrg mangled++; 350 1.1.1.9 mrg 351 1.1.1.9 mrg mangled = dlang_decode_backref (mangled, &refpos); 352 1.1.1.9 mrg if (mangled == NULL) 353 1.1.1.9 mrg return NULL; 354 1.1.1.9 mrg 355 1.1.1.9 mrg if (refpos > qpos - info->s) 356 1.1.1.9 mrg return NULL; 357 1.1.1.9 mrg 358 1.1.1.9 mrg /* Set the position of the back reference. */ 359 1.1.1.9 mrg *ret = qpos - refpos; 360 1.1.1.9 mrg 361 1.1.1.9 mrg return mangled; 362 1.1.1.9 mrg } 363 1.1.1.9 mrg 364 1.1.1.9 mrg /* Demangle a back referenced symbol from MANGLED and append it to DECL. 365 1.1.1.9 mrg Return the remaining string on success or NULL on failure. */ 366 1.1.1.9 mrg static const char * 367 1.1.1.9 mrg dlang_symbol_backref (string *decl, const char *mangled, 368 1.1.1.9 mrg struct dlang_info *info) 369 1.1.1.9 mrg { 370 1.1.1.9 mrg /* An identifier back reference always points to a digit 0 to 9. 371 1.1.1.9 mrg 372 1.1.1.9 mrg IdentifierBackRef: 373 1.1.1.9 mrg Q NumberBackRef 374 1.1.1.9 mrg ^ 375 1.1.1.9 mrg */ 376 1.1.1.9 mrg const char *backref; 377 1.1.1.9 mrg unsigned long len; 378 1.1.1.9 mrg 379 1.1.1.9 mrg /* Get position of the back reference. */ 380 1.1.1.9 mrg mangled = dlang_backref (mangled, &backref, info); 381 1.1.1.9 mrg 382 1.1.1.9 mrg /* Must point to a simple identifier. */ 383 1.1.1.9 mrg backref = dlang_number (backref, &len); 384 1.1.1.9 mrg if (backref == NULL || strlen(backref) < len) 385 1.1.1.9 mrg return NULL; 386 1.1.1.9 mrg 387 1.1.1.9 mrg backref = dlang_lname (decl, backref, len); 388 1.1.1.9 mrg if (backref == NULL) 389 1.1.1.9 mrg return NULL; 390 1.1.1.9 mrg 391 1.1.1.9 mrg return mangled; 392 1.1.1.9 mrg } 393 1.1.1.9 mrg 394 1.1.1.9 mrg /* Demangle a back referenced type from MANGLED and append it to DECL. 395 1.1.1.9 mrg IS_FUNCTION is 1 if the back referenced type is expected to be a function. 396 1.1.1.9 mrg Return the remaining string on success or NULL on failure. */ 397 1.1.1.9 mrg static const char * 398 1.1.1.9 mrg dlang_type_backref (string *decl, const char *mangled, struct dlang_info *info, 399 1.1.1.9 mrg int is_function) 400 1.1.1.9 mrg { 401 1.1.1.9 mrg /* A type back reference always points to a letter. 402 1.1.1.9 mrg 403 1.1.1.9 mrg TypeBackRef: 404 1.1.1.9 mrg Q NumberBackRef 405 1.1.1.9 mrg ^ 406 1.1.1.9 mrg */ 407 1.1.1.9 mrg const char *backref; 408 1.1.1.9 mrg 409 1.1.1.9 mrg /* If we appear to be moving backwards through the mangle string, then 410 1.1.1.9 mrg bail as this may be a recursive back reference. */ 411 1.1.1.9 mrg if (mangled - info->s >= info->last_backref) 412 1.1.1.9 mrg return NULL; 413 1.1.1.9 mrg 414 1.1.1.9 mrg int save_refpos = info->last_backref; 415 1.1.1.9 mrg info->last_backref = mangled - info->s; 416 1.1.1.9 mrg 417 1.1.1.9 mrg /* Get position of the back reference. */ 418 1.1.1.9 mrg mangled = dlang_backref (mangled, &backref, info); 419 1.1.1.9 mrg 420 1.1.1.9 mrg /* Must point to a type. */ 421 1.1.1.9 mrg if (is_function) 422 1.1.1.9 mrg backref = dlang_function_type (decl, backref, info); 423 1.1.1.9 mrg else 424 1.1.1.9 mrg backref = dlang_type (decl, backref, info); 425 1.1.1.9 mrg 426 1.1.1.9 mrg info->last_backref = save_refpos; 427 1.1.1.9 mrg 428 1.1.1.9 mrg if (backref == NULL) 429 1.1.1.9 mrg return NULL; 430 1.1.1.9 mrg 431 1.1.1.9 mrg return mangled; 432 1.1.1.9 mrg } 433 1.1.1.9 mrg 434 1.1.1.9 mrg /* Extract the beginning of a symbol name from MANGLED and 435 1.1.1.9 mrg return 1 on success or 0 on failure. */ 436 1.1.1.9 mrg static int 437 1.1.1.9 mrg dlang_symbol_name_p (const char *mangled, struct dlang_info *info) 438 1.1.1.9 mrg { 439 1.1.1.9 mrg long ret; 440 1.1.1.9 mrg const char *qref = mangled; 441 1.1.1.9 mrg 442 1.1.1.9 mrg if (ISDIGIT (*mangled)) 443 1.1.1.9 mrg return 1; 444 1.1.1.9 mrg 445 1.1.1.9 mrg if (mangled[0] == '_' && mangled[1] == '_' 446 1.1.1.9 mrg && (mangled[2] == 'T' || mangled[2] == 'U')) 447 1.1.1.9 mrg return 1; 448 1.1.1.9 mrg 449 1.1.1.9 mrg if (*mangled != 'Q') 450 1.1.1.9 mrg return 0; 451 1.1.1.9 mrg 452 1.1.1.9 mrg mangled = dlang_decode_backref (mangled + 1, &ret); 453 1.1.1.9 mrg if (mangled == NULL || ret > qref - info->s) 454 1.1.1.9 mrg return 0; 455 1.1.1.9 mrg 456 1.1.1.9 mrg return ISDIGIT (qref[-ret]); 457 1.1.1.9 mrg } 458 1.1.1.9 mrg 459 1.1 mrg /* Demangle the calling convention from MANGLED and append it to DECL. 460 1.1 mrg Return the remaining string on success or NULL on failure. */ 461 1.1 mrg static const char * 462 1.1 mrg dlang_call_convention (string *decl, const char *mangled) 463 1.1 mrg { 464 1.1 mrg if (mangled == NULL || *mangled == '\0') 465 1.1.1.2 mrg return NULL; 466 1.1 mrg 467 1.1 mrg switch (*mangled) 468 1.1 mrg { 469 1.1 mrg case 'F': /* (D) */ 470 1.1 mrg mangled++; 471 1.1 mrg break; 472 1.1 mrg case 'U': /* (C) */ 473 1.1 mrg mangled++; 474 1.1 mrg string_append (decl, "extern(C) "); 475 1.1 mrg break; 476 1.1 mrg case 'W': /* (Windows) */ 477 1.1 mrg mangled++; 478 1.1 mrg string_append (decl, "extern(Windows) "); 479 1.1 mrg break; 480 1.1 mrg case 'V': /* (Pascal) */ 481 1.1 mrg mangled++; 482 1.1 mrg string_append (decl, "extern(Pascal) "); 483 1.1 mrg break; 484 1.1 mrg case 'R': /* (C++) */ 485 1.1 mrg mangled++; 486 1.1 mrg string_append (decl, "extern(C++) "); 487 1.1 mrg break; 488 1.1.1.2 mrg case 'Y': /* (Objective-C) */ 489 1.1.1.2 mrg mangled++; 490 1.1.1.2 mrg string_append (decl, "extern(Objective-C) "); 491 1.1.1.2 mrg break; 492 1.1 mrg default: 493 1.1 mrg return NULL; 494 1.1 mrg } 495 1.1 mrg 496 1.1 mrg return mangled; 497 1.1 mrg } 498 1.1 mrg 499 1.1.1.2 mrg /* Extract the type modifiers from MANGLED and append them to DECL. 500 1.1.1.2 mrg Returns the remaining signature on success or NULL on failure. */ 501 1.1.1.2 mrg static const char * 502 1.1.1.2 mrg dlang_type_modifiers (string *decl, const char *mangled) 503 1.1.1.2 mrg { 504 1.1.1.2 mrg if (mangled == NULL || *mangled == '\0') 505 1.1.1.2 mrg return NULL; 506 1.1.1.2 mrg 507 1.1.1.2 mrg switch (*mangled) 508 1.1.1.2 mrg { 509 1.1.1.2 mrg case 'x': /* const */ 510 1.1.1.2 mrg mangled++; 511 1.1.1.2 mrg string_append (decl, " const"); 512 1.1.1.2 mrg return mangled; 513 1.1.1.2 mrg case 'y': /* immutable */ 514 1.1.1.2 mrg mangled++; 515 1.1.1.2 mrg string_append (decl, " immutable"); 516 1.1.1.2 mrg return mangled; 517 1.1.1.2 mrg case 'O': /* shared */ 518 1.1.1.2 mrg mangled++; 519 1.1.1.2 mrg string_append (decl, " shared"); 520 1.1.1.2 mrg return dlang_type_modifiers (decl, mangled); 521 1.1.1.2 mrg case 'N': 522 1.1.1.2 mrg mangled++; 523 1.1.1.2 mrg if (*mangled == 'g') /* wild */ 524 1.1.1.2 mrg { 525 1.1.1.2 mrg mangled++; 526 1.1.1.2 mrg string_append (decl, " inout"); 527 1.1.1.2 mrg return dlang_type_modifiers (decl, mangled); 528 1.1.1.2 mrg } 529 1.1.1.2 mrg else 530 1.1.1.2 mrg return NULL; 531 1.1.1.2 mrg 532 1.1.1.2 mrg default: 533 1.1.1.2 mrg return mangled; 534 1.1.1.2 mrg } 535 1.1.1.2 mrg } 536 1.1.1.2 mrg 537 1.1 mrg /* Demangle the D function attributes from MANGLED and append it to DECL. 538 1.1 mrg Return the remaining string on success or NULL on failure. */ 539 1.1 mrg static const char * 540 1.1 mrg dlang_attributes (string *decl, const char *mangled) 541 1.1 mrg { 542 1.1 mrg if (mangled == NULL || *mangled == '\0') 543 1.1.1.2 mrg return NULL; 544 1.1 mrg 545 1.1 mrg while (*mangled == 'N') 546 1.1 mrg { 547 1.1 mrg mangled++; 548 1.1 mrg switch (*mangled) 549 1.1 mrg { 550 1.1 mrg case 'a': /* pure */ 551 1.1 mrg mangled++; 552 1.1 mrg string_append (decl, "pure "); 553 1.1 mrg continue; 554 1.1 mrg case 'b': /* nothrow */ 555 1.1 mrg mangled++; 556 1.1 mrg string_append (decl, "nothrow "); 557 1.1 mrg continue; 558 1.1 mrg case 'c': /* ref */ 559 1.1 mrg mangled++; 560 1.1 mrg string_append (decl, "ref "); 561 1.1 mrg continue; 562 1.1 mrg case 'd': /* @property */ 563 1.1 mrg mangled++; 564 1.1 mrg string_append (decl, "@property "); 565 1.1 mrg continue; 566 1.1 mrg case 'e': /* @trusted */ 567 1.1 mrg mangled++; 568 1.1 mrg string_append (decl, "@trusted "); 569 1.1 mrg continue; 570 1.1 mrg case 'f': /* @safe */ 571 1.1 mrg mangled++; 572 1.1 mrg string_append (decl, "@safe "); 573 1.1 mrg continue; 574 1.1 mrg case 'g': 575 1.1 mrg case 'h': 576 1.1.1.2 mrg case 'k': 577 1.1.1.9 mrg case 'n': 578 1.1 mrg /* inout parameter is represented as 'Ng'. 579 1.1 mrg vector parameter is represented as 'Nh'. 580 1.1.1.9 mrg return parameter is represented as 'Nk'. 581 1.1.1.9 mrg typeof(*null) parameter is represented as 'Nn'. 582 1.1 mrg If we see this, then we know we're really in the 583 1.1 mrg parameter list. Rewind and break. */ 584 1.1 mrg mangled--; 585 1.1 mrg break; 586 1.1 mrg case 'i': /* @nogc */ 587 1.1 mrg mangled++; 588 1.1 mrg string_append (decl, "@nogc "); 589 1.1 mrg continue; 590 1.1.1.2 mrg case 'j': /* return */ 591 1.1.1.2 mrg mangled++; 592 1.1.1.2 mrg string_append (decl, "return "); 593 1.1.1.2 mrg continue; 594 1.1.1.6 mrg case 'l': /* scope */ 595 1.1.1.6 mrg mangled++; 596 1.1.1.6 mrg string_append (decl, "scope "); 597 1.1.1.6 mrg continue; 598 1.1.1.9 mrg case 'm': /* @live */ 599 1.1.1.9 mrg mangled++; 600 1.1.1.9 mrg string_append (decl, "@live "); 601 1.1.1.9 mrg continue; 602 1.1.1.2 mrg 603 1.1.1.2 mrg default: /* unknown attribute */ 604 1.1.1.2 mrg return NULL; 605 1.1 mrg } 606 1.1 mrg break; 607 1.1 mrg } 608 1.1 mrg 609 1.1 mrg return mangled; 610 1.1 mrg } 611 1.1 mrg 612 1.1.1.9 mrg /* Demangle the function type from MANGLED without the return type. 613 1.1.1.9 mrg The arguments are appended to ARGS, the calling convention is appended 614 1.1.1.9 mrg to CALL and attributes are appended to ATTR. Any of these can be NULL 615 1.1.1.9 mrg to throw the information away. Return the remaining string on success 616 1.1.1.9 mrg or NULL on failure. */ 617 1.1.1.9 mrg static const char * 618 1.1.1.9 mrg dlang_function_type_noreturn (string *args, string *call, string *attr, 619 1.1.1.9 mrg const char *mangled, struct dlang_info *info) 620 1.1.1.9 mrg { 621 1.1.1.9 mrg string dump; 622 1.1.1.9 mrg string_init (&dump); 623 1.1.1.9 mrg 624 1.1.1.9 mrg /* Skip over calling convention and attributes. */ 625 1.1.1.9 mrg mangled = dlang_call_convention (call ? call : &dump, mangled); 626 1.1.1.9 mrg mangled = dlang_attributes (attr ? attr : &dump, mangled); 627 1.1.1.9 mrg 628 1.1.1.9 mrg if (args) 629 1.1.1.9 mrg string_append (args, "("); 630 1.1.1.9 mrg 631 1.1.1.9 mrg mangled = dlang_function_args (args ? args : &dump, mangled, info); 632 1.1.1.9 mrg if (args) 633 1.1.1.9 mrg string_append (args, ")"); 634 1.1.1.9 mrg 635 1.1.1.9 mrg string_delete (&dump); 636 1.1.1.9 mrg return mangled; 637 1.1.1.9 mrg } 638 1.1.1.9 mrg 639 1.1 mrg /* Demangle the function type from MANGLED and append it to DECL. 640 1.1 mrg Return the remaining string on success or NULL on failure. */ 641 1.1 mrg static const char * 642 1.1.1.9 mrg dlang_function_type (string *decl, const char *mangled, struct dlang_info *info) 643 1.1 mrg { 644 1.1 mrg string attr, args, type; 645 1.1 mrg 646 1.1 mrg if (mangled == NULL || *mangled == '\0') 647 1.1.1.2 mrg return NULL; 648 1.1 mrg 649 1.1 mrg /* The order of the mangled string is: 650 1.1 mrg CallConvention FuncAttrs Arguments ArgClose Type 651 1.1 mrg 652 1.1 mrg The demangled string is re-ordered as: 653 1.1 mrg CallConvention Type Arguments FuncAttrs 654 1.1 mrg */ 655 1.1 mrg string_init (&attr); 656 1.1 mrg string_init (&args); 657 1.1 mrg string_init (&type); 658 1.1 mrg 659 1.1.1.9 mrg mangled = dlang_function_type_noreturn (&args, decl, &attr, mangled, info); 660 1.1 mrg 661 1.1 mrg /* Function return type. */ 662 1.1.1.9 mrg mangled = dlang_type (&type, mangled, info); 663 1.1 mrg 664 1.1 mrg /* Append to decl in order. */ 665 1.1.1.9 mrg string_appendn (decl, type.b, string_length (&type)); 666 1.1.1.9 mrg string_appendn (decl, args.b, string_length (&args)); 667 1.1.1.9 mrg string_append (decl, " "); 668 1.1.1.9 mrg string_appendn (decl, attr.b, string_length (&attr)); 669 1.1 mrg 670 1.1 mrg string_delete (&attr); 671 1.1 mrg string_delete (&args); 672 1.1 mrg string_delete (&type); 673 1.1 mrg return mangled; 674 1.1 mrg } 675 1.1 mrg 676 1.1 mrg /* Demangle the argument list from MANGLED and append it to DECL. 677 1.1 mrg Return the remaining string on success or NULL on failure. */ 678 1.1 mrg static const char * 679 1.1.1.9 mrg dlang_function_args (string *decl, const char *mangled, struct dlang_info *info) 680 1.1 mrg { 681 1.1 mrg size_t n = 0; 682 1.1 mrg 683 1.1 mrg while (mangled && *mangled != '\0') 684 1.1 mrg { 685 1.1 mrg switch (*mangled) 686 1.1 mrg { 687 1.1 mrg case 'X': /* (variadic T t...) style. */ 688 1.1 mrg mangled++; 689 1.1 mrg string_append (decl, "..."); 690 1.1 mrg return mangled; 691 1.1 mrg case 'Y': /* (variadic T t, ...) style. */ 692 1.1 mrg mangled++; 693 1.1.1.2 mrg if (n != 0) 694 1.1.1.2 mrg string_append (decl, ", "); 695 1.1.1.2 mrg string_append (decl, "..."); 696 1.1 mrg return mangled; 697 1.1 mrg case 'Z': /* Normal function. */ 698 1.1 mrg mangled++; 699 1.1 mrg return mangled; 700 1.1 mrg } 701 1.1 mrg 702 1.1 mrg if (n++) 703 1.1 mrg string_append (decl, ", "); 704 1.1 mrg 705 1.1 mrg if (*mangled == 'M') /* scope(T) */ 706 1.1 mrg { 707 1.1 mrg mangled++; 708 1.1 mrg string_append (decl, "scope "); 709 1.1 mrg } 710 1.1 mrg 711 1.1.1.2 mrg if (mangled[0] == 'N' && mangled[1] == 'k') /* return(T) */ 712 1.1.1.2 mrg { 713 1.1.1.2 mrg mangled += 2; 714 1.1.1.2 mrg string_append (decl, "return "); 715 1.1.1.2 mrg } 716 1.1.1.2 mrg 717 1.1 mrg switch (*mangled) 718 1.1 mrg { 719 1.1.1.9 mrg case 'I': /* in(T) */ 720 1.1.1.9 mrg mangled++; 721 1.1.1.9 mrg string_append (decl, "in "); 722 1.1.1.9 mrg if (*mangled == 'K') /* in ref(T) */ 723 1.1.1.9 mrg { 724 1.1.1.9 mrg mangled++; 725 1.1.1.9 mrg string_append (decl, "ref "); 726 1.1.1.9 mrg } 727 1.1.1.9 mrg break; 728 1.1 mrg case 'J': /* out(T) */ 729 1.1 mrg mangled++; 730 1.1 mrg string_append (decl, "out "); 731 1.1 mrg break; 732 1.1 mrg case 'K': /* ref(T) */ 733 1.1 mrg mangled++; 734 1.1 mrg string_append (decl, "ref "); 735 1.1 mrg break; 736 1.1 mrg case 'L': /* lazy(T) */ 737 1.1 mrg mangled++; 738 1.1 mrg string_append (decl, "lazy "); 739 1.1 mrg break; 740 1.1 mrg } 741 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 742 1.1 mrg } 743 1.1 mrg 744 1.1 mrg return mangled; 745 1.1 mrg } 746 1.1 mrg 747 1.1 mrg /* Demangle the type from MANGLED and append it to DECL. 748 1.1 mrg Return the remaining string on success or NULL on failure. */ 749 1.1 mrg static const char * 750 1.1.1.9 mrg dlang_type (string *decl, const char *mangled, struct dlang_info *info) 751 1.1 mrg { 752 1.1 mrg if (mangled == NULL || *mangled == '\0') 753 1.1.1.2 mrg return NULL; 754 1.1 mrg 755 1.1 mrg switch (*mangled) 756 1.1 mrg { 757 1.1 mrg case 'O': /* shared(T) */ 758 1.1 mrg mangled++; 759 1.1 mrg string_append (decl, "shared("); 760 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 761 1.1 mrg string_append (decl, ")"); 762 1.1 mrg return mangled; 763 1.1 mrg case 'x': /* const(T) */ 764 1.1 mrg mangled++; 765 1.1 mrg string_append (decl, "const("); 766 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 767 1.1 mrg string_append (decl, ")"); 768 1.1 mrg return mangled; 769 1.1 mrg case 'y': /* immutable(T) */ 770 1.1 mrg mangled++; 771 1.1 mrg string_append (decl, "immutable("); 772 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 773 1.1 mrg string_append (decl, ")"); 774 1.1 mrg return mangled; 775 1.1 mrg case 'N': 776 1.1 mrg mangled++; 777 1.1 mrg if (*mangled == 'g') /* wild(T) */ 778 1.1 mrg { 779 1.1 mrg mangled++; 780 1.1 mrg string_append (decl, "inout("); 781 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 782 1.1 mrg string_append (decl, ")"); 783 1.1 mrg return mangled; 784 1.1 mrg } 785 1.1 mrg else if (*mangled == 'h') /* vector(T) */ 786 1.1 mrg { 787 1.1 mrg mangled++; 788 1.1 mrg string_append (decl, "__vector("); 789 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 790 1.1 mrg string_append (decl, ")"); 791 1.1 mrg return mangled; 792 1.1 mrg } 793 1.1.1.9 mrg else if (*mangled == 'n') /* typeof(*null) */ 794 1.1.1.9 mrg { 795 1.1.1.9 mrg mangled++; 796 1.1.1.9 mrg string_append (decl, "typeof(*null)"); 797 1.1.1.9 mrg return mangled; 798 1.1.1.9 mrg } 799 1.1 mrg else 800 1.1 mrg return NULL; 801 1.1 mrg case 'A': /* dynamic array (T[]) */ 802 1.1 mrg mangled++; 803 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 804 1.1 mrg string_append (decl, "[]"); 805 1.1 mrg return mangled; 806 1.1 mrg case 'G': /* static array (T[N]) */ 807 1.1 mrg { 808 1.1 mrg const char *numptr; 809 1.1 mrg size_t num = 0; 810 1.1 mrg mangled++; 811 1.1 mrg 812 1.1 mrg numptr = mangled; 813 1.1 mrg while (ISDIGIT (*mangled)) 814 1.1 mrg { 815 1.1 mrg num++; 816 1.1 mrg mangled++; 817 1.1 mrg } 818 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 819 1.1 mrg string_append (decl, "["); 820 1.1 mrg string_appendn (decl, numptr, num); 821 1.1 mrg string_append (decl, "]"); 822 1.1 mrg return mangled; 823 1.1 mrg } 824 1.1 mrg case 'H': /* associative array (T[T]) */ 825 1.1 mrg { 826 1.1 mrg string type; 827 1.1 mrg size_t sztype; 828 1.1 mrg mangled++; 829 1.1 mrg 830 1.1 mrg string_init (&type); 831 1.1.1.9 mrg mangled = dlang_type (&type, mangled, info); 832 1.1 mrg sztype = string_length (&type); 833 1.1 mrg 834 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 835 1.1 mrg string_append (decl, "["); 836 1.1 mrg string_appendn (decl, type.b, sztype); 837 1.1 mrg string_append (decl, "]"); 838 1.1 mrg 839 1.1 mrg string_delete (&type); 840 1.1 mrg return mangled; 841 1.1 mrg } 842 1.1 mrg case 'P': /* pointer (T*) */ 843 1.1 mrg mangled++; 844 1.1.1.6 mrg if (!dlang_call_convention_p (mangled)) 845 1.1.1.2 mrg { 846 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 847 1.1.1.6 mrg string_append (decl, "*"); 848 1.1.1.2 mrg return mangled; 849 1.1.1.2 mrg } 850 1.1.1.6 mrg /* Fall through */ 851 1.1.1.6 mrg case 'F': /* function T (D) */ 852 1.1.1.6 mrg case 'U': /* function T (C) */ 853 1.1.1.6 mrg case 'W': /* function T (Windows) */ 854 1.1.1.6 mrg case 'V': /* function T (Pascal) */ 855 1.1.1.6 mrg case 'R': /* function T (C++) */ 856 1.1.1.6 mrg case 'Y': /* function T (Objective-C) */ 857 1.1.1.6 mrg /* Function pointer types don't include the trailing asterisk. */ 858 1.1.1.9 mrg mangled = dlang_function_type (decl, mangled, info); 859 1.1.1.6 mrg string_append (decl, "function"); 860 1.1 mrg return mangled; 861 1.1 mrg case 'C': /* class T */ 862 1.1 mrg case 'S': /* struct T */ 863 1.1 mrg case 'E': /* enum T */ 864 1.1 mrg case 'T': /* typedef T */ 865 1.1 mrg mangled++; 866 1.1.1.9 mrg return dlang_parse_qualified (decl, mangled, info, 0); 867 1.1 mrg case 'D': /* delegate T */ 868 1.1.1.2 mrg { 869 1.1.1.2 mrg string mods; 870 1.1.1.2 mrg size_t szmods; 871 1.1 mrg mangled++; 872 1.1.1.2 mrg 873 1.1.1.2 mrg string_init (&mods); 874 1.1.1.2 mrg mangled = dlang_type_modifiers (&mods, mangled); 875 1.1.1.2 mrg szmods = string_length (&mods); 876 1.1.1.2 mrg 877 1.1.1.9 mrg /* Back referenced function type. */ 878 1.1.1.9 mrg if (mangled && *mangled == 'Q') 879 1.1.1.9 mrg mangled = dlang_type_backref (decl, mangled, info, 1); 880 1.1.1.9 mrg else 881 1.1.1.9 mrg mangled = dlang_function_type (decl, mangled, info); 882 1.1.1.9 mrg 883 1.1 mrg string_append (decl, "delegate"); 884 1.1.1.2 mrg string_appendn (decl, mods.b, szmods); 885 1.1.1.2 mrg 886 1.1.1.2 mrg string_delete (&mods); 887 1.1 mrg return mangled; 888 1.1.1.2 mrg } 889 1.1 mrg case 'B': /* tuple T */ 890 1.1 mrg mangled++; 891 1.1.1.9 mrg return dlang_parse_tuple (decl, mangled, info); 892 1.1 mrg 893 1.1 mrg /* Basic types */ 894 1.1 mrg case 'n': 895 1.1 mrg mangled++; 896 1.1.1.9 mrg string_append (decl, "typeof(null)"); 897 1.1 mrg return mangled; 898 1.1 mrg case 'v': 899 1.1 mrg mangled++; 900 1.1 mrg string_append (decl, "void"); 901 1.1 mrg return mangled; 902 1.1 mrg case 'g': 903 1.1 mrg mangled++; 904 1.1 mrg string_append (decl, "byte"); 905 1.1 mrg return mangled; 906 1.1 mrg case 'h': 907 1.1 mrg mangled++; 908 1.1 mrg string_append (decl, "ubyte"); 909 1.1 mrg return mangled; 910 1.1 mrg case 's': 911 1.1 mrg mangled++; 912 1.1 mrg string_append (decl, "short"); 913 1.1 mrg return mangled; 914 1.1 mrg case 't': 915 1.1 mrg mangled++; 916 1.1 mrg string_append (decl, "ushort"); 917 1.1 mrg return mangled; 918 1.1 mrg case 'i': 919 1.1 mrg mangled++; 920 1.1 mrg string_append (decl, "int"); 921 1.1 mrg return mangled; 922 1.1 mrg case 'k': 923 1.1 mrg mangled++; 924 1.1 mrg string_append (decl, "uint"); 925 1.1 mrg return mangled; 926 1.1 mrg case 'l': 927 1.1 mrg mangled++; 928 1.1 mrg string_append (decl, "long"); 929 1.1 mrg return mangled; 930 1.1 mrg case 'm': 931 1.1 mrg mangled++; 932 1.1 mrg string_append (decl, "ulong"); 933 1.1 mrg return mangled; 934 1.1 mrg case 'f': 935 1.1 mrg mangled++; 936 1.1 mrg string_append (decl, "float"); 937 1.1 mrg return mangled; 938 1.1 mrg case 'd': 939 1.1 mrg mangled++; 940 1.1 mrg string_append (decl, "double"); 941 1.1 mrg return mangled; 942 1.1 mrg case 'e': 943 1.1 mrg mangled++; 944 1.1 mrg string_append (decl, "real"); 945 1.1 mrg return mangled; 946 1.1 mrg 947 1.1 mrg /* Imaginary and Complex types */ 948 1.1 mrg case 'o': 949 1.1 mrg mangled++; 950 1.1 mrg string_append (decl, "ifloat"); 951 1.1 mrg return mangled; 952 1.1 mrg case 'p': 953 1.1 mrg mangled++; 954 1.1 mrg string_append (decl, "idouble"); 955 1.1 mrg return mangled; 956 1.1 mrg case 'j': 957 1.1 mrg mangled++; 958 1.1 mrg string_append (decl, "ireal"); 959 1.1 mrg return mangled; 960 1.1 mrg case 'q': 961 1.1 mrg mangled++; 962 1.1 mrg string_append (decl, "cfloat"); 963 1.1 mrg return mangled; 964 1.1 mrg case 'r': 965 1.1 mrg mangled++; 966 1.1 mrg string_append (decl, "cdouble"); 967 1.1 mrg return mangled; 968 1.1 mrg case 'c': 969 1.1 mrg mangled++; 970 1.1 mrg string_append (decl, "creal"); 971 1.1 mrg return mangled; 972 1.1 mrg 973 1.1 mrg /* Other types */ 974 1.1 mrg case 'b': 975 1.1 mrg mangled++; 976 1.1 mrg string_append (decl, "bool"); 977 1.1 mrg return mangled; 978 1.1 mrg case 'a': 979 1.1 mrg mangled++; 980 1.1 mrg string_append (decl, "char"); 981 1.1 mrg return mangled; 982 1.1 mrg case 'u': 983 1.1 mrg mangled++; 984 1.1 mrg string_append (decl, "wchar"); 985 1.1 mrg return mangled; 986 1.1 mrg case 'w': 987 1.1 mrg mangled++; 988 1.1 mrg string_append (decl, "dchar"); 989 1.1 mrg return mangled; 990 1.1.1.2 mrg case 'z': 991 1.1.1.2 mrg mangled++; 992 1.1.1.2 mrg switch (*mangled) 993 1.1.1.2 mrg { 994 1.1.1.2 mrg case 'i': 995 1.1.1.2 mrg mangled++; 996 1.1.1.2 mrg string_append (decl, "cent"); 997 1.1.1.2 mrg return mangled; 998 1.1.1.2 mrg case 'k': 999 1.1.1.2 mrg mangled++; 1000 1.1.1.2 mrg string_append (decl, "ucent"); 1001 1.1.1.2 mrg return mangled; 1002 1.1.1.2 mrg } 1003 1.1.1.2 mrg return NULL; 1004 1.1 mrg 1005 1.1.1.9 mrg /* Back referenced type. */ 1006 1.1.1.9 mrg case 'Q': 1007 1.1.1.9 mrg return dlang_type_backref (decl, mangled, info, 0); 1008 1.1.1.9 mrg 1009 1.1 mrg default: /* unhandled */ 1010 1.1 mrg return NULL; 1011 1.1 mrg } 1012 1.1 mrg } 1013 1.1 mrg 1014 1.1 mrg /* Extract the identifier from MANGLED and append it to DECL. 1015 1.1 mrg Return the remaining string on success or NULL on failure. */ 1016 1.1 mrg static const char * 1017 1.1.1.9 mrg dlang_identifier (string *decl, const char *mangled, struct dlang_info *info) 1018 1.1 mrg { 1019 1.1.1.9 mrg unsigned long len; 1020 1.1.1.9 mrg 1021 1.1.1.9 mrg if (mangled == NULL || *mangled == '\0') 1022 1.1.1.9 mrg return NULL; 1023 1.1.1.9 mrg 1024 1.1.1.9 mrg if (*mangled == 'Q') 1025 1.1.1.9 mrg return dlang_symbol_backref (decl, mangled, info); 1026 1.1.1.9 mrg 1027 1.1.1.9 mrg /* May be a template instance without a length prefix. */ 1028 1.1.1.9 mrg if (mangled[0] == '_' && mangled[1] == '_' 1029 1.1.1.9 mrg && (mangled[2] == 'T' || mangled[2] == 'U')) 1030 1.1.1.9 mrg return dlang_parse_template (decl, mangled, info, TEMPLATE_LENGTH_UNKNOWN); 1031 1.1.1.9 mrg 1032 1.1.1.6 mrg const char *endptr = dlang_number (mangled, &len); 1033 1.1.1.2 mrg 1034 1.1.1.6 mrg if (endptr == NULL || len == 0) 1035 1.1.1.2 mrg return NULL; 1036 1.1 mrg 1037 1.1.1.9 mrg if (strlen (endptr) < len) 1038 1.1.1.9 mrg return NULL; 1039 1.1.1.2 mrg 1040 1.1.1.9 mrg mangled = endptr; 1041 1.1.1.2 mrg 1042 1.1.1.9 mrg /* May be a template instance with a length prefix. */ 1043 1.1.1.9 mrg if (len >= 5 && mangled[0] == '_' && mangled[1] == '_' 1044 1.1.1.9 mrg && (mangled[2] == 'T' || mangled[2] == 'U')) 1045 1.1.1.9 mrg return dlang_parse_template (decl, mangled, info, len); 1046 1.1.1.2 mrg 1047 1.1.1.9 mrg /* There can be multiple different declarations in the same function that have 1048 1.1.1.9 mrg the same mangled name. To make the mangled names unique, a fake parent in 1049 1.1.1.9 mrg the form `__Sddd' is added to the symbol. */ 1050 1.1.1.9 mrg if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S') 1051 1.1.1.2 mrg { 1052 1.1.1.9 mrg const char *numptr = mangled + 3; 1053 1.1.1.9 mrg while (numptr < (mangled + len) && ISDIGIT (*numptr)) 1054 1.1.1.9 mrg numptr++; 1055 1.1 mrg 1056 1.1.1.9 mrg if (mangled + len == numptr) 1057 1.1.1.9 mrg { 1058 1.1.1.9 mrg /* Skip over the fake parent. */ 1059 1.1.1.9 mrg mangled += len; 1060 1.1.1.9 mrg return dlang_identifier (decl, mangled, info); 1061 1.1.1.9 mrg } 1062 1.1 mrg 1063 1.1.1.9 mrg /* else demangle it as a plain identifier. */ 1064 1.1.1.9 mrg } 1065 1.1 mrg 1066 1.1.1.9 mrg return dlang_lname (decl, mangled, len); 1067 1.1.1.9 mrg } 1068 1.1.1.2 mrg 1069 1.1.1.9 mrg /* Extract the plain identifier from MANGLED and prepend/append it to DECL 1070 1.1.1.9 mrg with special treatment for some magic compiler generted symbols. 1071 1.1.1.9 mrg Return the remaining string on success or NULL on failure. */ 1072 1.1.1.9 mrg static const char * 1073 1.1.1.9 mrg dlang_lname (string *decl, const char *mangled, unsigned long len) 1074 1.1.1.9 mrg { 1075 1.1.1.9 mrg switch (len) 1076 1.1.1.9 mrg { 1077 1.1.1.9 mrg case 6: 1078 1.1.1.9 mrg if (strncmp (mangled, "__ctor", len) == 0) 1079 1.1.1.9 mrg { 1080 1.1.1.9 mrg /* Constructor symbol for a class/struct. */ 1081 1.1.1.9 mrg string_append (decl, "this"); 1082 1.1.1.9 mrg mangled += len; 1083 1.1.1.9 mrg return mangled; 1084 1.1.1.9 mrg } 1085 1.1.1.9 mrg else if (strncmp (mangled, "__dtor", len) == 0) 1086 1.1.1.9 mrg { 1087 1.1.1.9 mrg /* Destructor symbol for a class/struct. */ 1088 1.1.1.9 mrg string_append (decl, "~this"); 1089 1.1.1.9 mrg mangled += len; 1090 1.1.1.9 mrg return mangled; 1091 1.1.1.9 mrg } 1092 1.1.1.9 mrg else if (strncmp (mangled, "__initZ", len + 1) == 0) 1093 1.1.1.9 mrg { 1094 1.1.1.9 mrg /* The static initialiser for a given symbol. */ 1095 1.1.1.9 mrg string_prepend (decl, "initializer for "); 1096 1.1.1.9 mrg string_setlength (decl, string_length (decl) - 1); 1097 1.1.1.9 mrg mangled += len; 1098 1.1.1.9 mrg return mangled; 1099 1.1.1.9 mrg } 1100 1.1.1.9 mrg else if (strncmp (mangled, "__vtblZ", len + 1) == 0) 1101 1.1.1.9 mrg { 1102 1.1.1.9 mrg /* The vtable symbol for a given class. */ 1103 1.1.1.9 mrg string_prepend (decl, "vtable for "); 1104 1.1.1.9 mrg string_setlength (decl, string_length (decl) - 1); 1105 1.1.1.9 mrg mangled += len; 1106 1.1.1.9 mrg return mangled; 1107 1.1.1.9 mrg } 1108 1.1.1.9 mrg break; 1109 1.1.1.2 mrg 1110 1.1.1.9 mrg case 7: 1111 1.1.1.9 mrg if (strncmp (mangled, "__ClassZ", len + 1) == 0) 1112 1.1.1.9 mrg { 1113 1.1.1.9 mrg /* The classinfo symbol for a given class. */ 1114 1.1.1.9 mrg string_prepend (decl, "ClassInfo for "); 1115 1.1.1.9 mrg string_setlength (decl, string_length (decl) - 1); 1116 1.1.1.9 mrg mangled += len; 1117 1.1.1.9 mrg return mangled; 1118 1.1.1.9 mrg } 1119 1.1.1.9 mrg break; 1120 1.1.1.2 mrg 1121 1.1.1.9 mrg case 10: 1122 1.1.1.9 mrg if (strncmp (mangled, "__postblitMFZ", len + 3) == 0) 1123 1.1.1.9 mrg { 1124 1.1.1.9 mrg /* Postblit symbol for a struct. */ 1125 1.1.1.9 mrg string_append (decl, "this(this)"); 1126 1.1.1.9 mrg mangled += len + 3; 1127 1.1.1.9 mrg return mangled; 1128 1.1.1.9 mrg } 1129 1.1.1.9 mrg break; 1130 1.1.1.2 mrg 1131 1.1.1.9 mrg case 11: 1132 1.1.1.9 mrg if (strncmp (mangled, "__InterfaceZ", len + 1) == 0) 1133 1.1.1.9 mrg { 1134 1.1.1.9 mrg /* The interface symbol for a given class. */ 1135 1.1.1.9 mrg string_prepend (decl, "Interface for "); 1136 1.1.1.9 mrg string_setlength (decl, string_length (decl) - 1); 1137 1.1.1.9 mrg mangled += len; 1138 1.1.1.9 mrg return mangled; 1139 1.1 mrg } 1140 1.1.1.9 mrg break; 1141 1.1 mrg 1142 1.1.1.9 mrg case 12: 1143 1.1.1.9 mrg if (strncmp (mangled, "__ModuleInfoZ", len + 1) == 0) 1144 1.1.1.9 mrg { 1145 1.1.1.9 mrg /* The ModuleInfo symbol for a given module. */ 1146 1.1.1.9 mrg string_prepend (decl, "ModuleInfo for "); 1147 1.1.1.9 mrg string_setlength (decl, string_length (decl) - 1); 1148 1.1.1.9 mrg mangled += len; 1149 1.1.1.9 mrg return mangled; 1150 1.1.1.9 mrg } 1151 1.1.1.9 mrg break; 1152 1.1 mrg } 1153 1.1 mrg 1154 1.1.1.9 mrg string_appendn (decl, mangled, len); 1155 1.1.1.9 mrg mangled += len; 1156 1.1.1.9 mrg 1157 1.1 mrg return mangled; 1158 1.1 mrg } 1159 1.1 mrg 1160 1.1 mrg /* Extract the integer value from MANGLED and append it to DECL, 1161 1.1 mrg where TYPE is the type it should be represented as. 1162 1.1 mrg Return the remaining string on success or NULL on failure. */ 1163 1.1 mrg static const char * 1164 1.1 mrg dlang_parse_integer (string *decl, const char *mangled, char type) 1165 1.1 mrg { 1166 1.1 mrg if (type == 'a' || type == 'u' || type == 'w') 1167 1.1 mrg { 1168 1.1 mrg /* Parse character value. */ 1169 1.1.1.8 mrg char value[20]; 1170 1.1.1.8 mrg int pos = sizeof(value); 1171 1.1 mrg int width = 0; 1172 1.1.1.9 mrg unsigned long val; 1173 1.1 mrg 1174 1.1.1.6 mrg mangled = dlang_number (mangled, &val); 1175 1.1.1.6 mrg if (mangled == NULL) 1176 1.1 mrg return NULL; 1177 1.1 mrg 1178 1.1 mrg string_append (decl, "'"); 1179 1.1 mrg 1180 1.1 mrg if (type == 'a' && val >= 0x20 && val < 0x7F) 1181 1.1 mrg { 1182 1.1 mrg /* Represent as a character literal. */ 1183 1.1 mrg char c = (char) val; 1184 1.1 mrg string_appendn (decl, &c, 1); 1185 1.1 mrg } 1186 1.1 mrg else 1187 1.1 mrg { 1188 1.1 mrg /* Represent as a hexadecimal value. */ 1189 1.1 mrg switch (type) 1190 1.1 mrg { 1191 1.1 mrg case 'a': /* char */ 1192 1.1 mrg string_append (decl, "\\x"); 1193 1.1 mrg width = 2; 1194 1.1 mrg break; 1195 1.1 mrg case 'u': /* wchar */ 1196 1.1 mrg string_append (decl, "\\u"); 1197 1.1 mrg width = 4; 1198 1.1 mrg break; 1199 1.1 mrg case 'w': /* dchar */ 1200 1.1 mrg string_append (decl, "\\U"); 1201 1.1 mrg width = 8; 1202 1.1 mrg break; 1203 1.1 mrg } 1204 1.1 mrg 1205 1.1 mrg while (val > 0) 1206 1.1 mrg { 1207 1.1 mrg int digit = val % 16; 1208 1.1 mrg 1209 1.1 mrg if (digit < 10) 1210 1.1 mrg value[--pos] = (char)(digit + '0'); 1211 1.1 mrg else 1212 1.1 mrg value[--pos] = (char)((digit - 10) + 'a'); 1213 1.1 mrg 1214 1.1 mrg val /= 16; 1215 1.1 mrg width--; 1216 1.1 mrg } 1217 1.1 mrg 1218 1.1 mrg for (; width > 0; width--) 1219 1.1 mrg value[--pos] = '0'; 1220 1.1 mrg 1221 1.1.1.8 mrg string_appendn (decl, &(value[pos]), sizeof(value) - pos); 1222 1.1 mrg } 1223 1.1 mrg string_append (decl, "'"); 1224 1.1 mrg } 1225 1.1 mrg else if (type == 'b') 1226 1.1 mrg { 1227 1.1 mrg /* Parse boolean value. */ 1228 1.1.1.9 mrg unsigned long val; 1229 1.1 mrg 1230 1.1.1.6 mrg mangled = dlang_number (mangled, &val); 1231 1.1.1.6 mrg if (mangled == NULL) 1232 1.1 mrg return NULL; 1233 1.1 mrg 1234 1.1 mrg string_append (decl, val ? "true" : "false"); 1235 1.1 mrg } 1236 1.1 mrg else 1237 1.1 mrg { 1238 1.1 mrg /* Parse integer value. */ 1239 1.1 mrg const char *numptr = mangled; 1240 1.1 mrg size_t num = 0; 1241 1.1 mrg 1242 1.1.1.6 mrg if (! ISDIGIT (*mangled)) 1243 1.1.1.6 mrg return NULL; 1244 1.1.1.6 mrg 1245 1.1 mrg while (ISDIGIT (*mangled)) 1246 1.1 mrg { 1247 1.1 mrg num++; 1248 1.1 mrg mangled++; 1249 1.1 mrg } 1250 1.1 mrg string_appendn (decl, numptr, num); 1251 1.1 mrg 1252 1.1 mrg /* Append suffix. */ 1253 1.1 mrg switch (type) 1254 1.1 mrg { 1255 1.1 mrg case 'h': /* ubyte */ 1256 1.1 mrg case 't': /* ushort */ 1257 1.1 mrg case 'k': /* uint */ 1258 1.1 mrg string_append (decl, "u"); 1259 1.1 mrg break; 1260 1.1 mrg case 'l': /* long */ 1261 1.1 mrg string_append (decl, "L"); 1262 1.1 mrg break; 1263 1.1 mrg case 'm': /* ulong */ 1264 1.1 mrg string_append (decl, "uL"); 1265 1.1 mrg break; 1266 1.1 mrg } 1267 1.1 mrg } 1268 1.1 mrg 1269 1.1 mrg return mangled; 1270 1.1 mrg } 1271 1.1 mrg 1272 1.1 mrg /* Extract the floating-point value from MANGLED and append it to DECL. 1273 1.1 mrg Return the remaining string on success or NULL on failure. */ 1274 1.1 mrg static const char * 1275 1.1 mrg dlang_parse_real (string *decl, const char *mangled) 1276 1.1 mrg { 1277 1.1 mrg /* Handle NAN and +-INF. */ 1278 1.1 mrg if (strncmp (mangled, "NAN", 3) == 0) 1279 1.1 mrg { 1280 1.1 mrg string_append (decl, "NaN"); 1281 1.1 mrg mangled += 3; 1282 1.1 mrg return mangled; 1283 1.1 mrg } 1284 1.1 mrg else if (strncmp (mangled, "INF", 3) == 0) 1285 1.1 mrg { 1286 1.1 mrg string_append (decl, "Inf"); 1287 1.1 mrg mangled += 3; 1288 1.1 mrg return mangled; 1289 1.1 mrg } 1290 1.1 mrg else if (strncmp (mangled, "NINF", 4) == 0) 1291 1.1 mrg { 1292 1.1 mrg string_append (decl, "-Inf"); 1293 1.1 mrg mangled += 4; 1294 1.1 mrg return mangled; 1295 1.1 mrg } 1296 1.1 mrg 1297 1.1 mrg /* Hexadecimal prefix and leading bit. */ 1298 1.1 mrg if (*mangled == 'N') 1299 1.1 mrg { 1300 1.1.1.6 mrg string_append (decl, "-"); 1301 1.1 mrg mangled++; 1302 1.1 mrg } 1303 1.1 mrg 1304 1.1 mrg if (!ISXDIGIT (*mangled)) 1305 1.1 mrg return NULL; 1306 1.1 mrg 1307 1.1.1.6 mrg string_append (decl, "0x"); 1308 1.1.1.6 mrg string_appendn (decl, mangled, 1); 1309 1.1.1.6 mrg string_append (decl, "."); 1310 1.1 mrg mangled++; 1311 1.1 mrg 1312 1.1 mrg /* Significand. */ 1313 1.1 mrg while (ISXDIGIT (*mangled)) 1314 1.1 mrg { 1315 1.1.1.6 mrg string_appendn (decl, mangled, 1); 1316 1.1 mrg mangled++; 1317 1.1 mrg } 1318 1.1 mrg 1319 1.1 mrg /* Exponent. */ 1320 1.1 mrg if (*mangled != 'P') 1321 1.1 mrg return NULL; 1322 1.1 mrg 1323 1.1.1.6 mrg string_append (decl, "p"); 1324 1.1 mrg mangled++; 1325 1.1 mrg 1326 1.1 mrg if (*mangled == 'N') 1327 1.1 mrg { 1328 1.1.1.6 mrg string_append (decl, "-"); 1329 1.1 mrg mangled++; 1330 1.1 mrg } 1331 1.1 mrg 1332 1.1 mrg while (ISDIGIT (*mangled)) 1333 1.1 mrg { 1334 1.1.1.6 mrg string_appendn (decl, mangled, 1); 1335 1.1 mrg mangled++; 1336 1.1 mrg } 1337 1.1 mrg 1338 1.1 mrg return mangled; 1339 1.1 mrg } 1340 1.1 mrg 1341 1.1 mrg /* Extract the string value from MANGLED and append it to DECL. 1342 1.1 mrg Return the remaining string on success or NULL on failure. */ 1343 1.1 mrg static const char * 1344 1.1 mrg dlang_parse_string (string *decl, const char *mangled) 1345 1.1 mrg { 1346 1.1 mrg char type = *mangled; 1347 1.1.1.9 mrg unsigned long len; 1348 1.1 mrg 1349 1.1 mrg mangled++; 1350 1.1.1.6 mrg mangled = dlang_number (mangled, &len); 1351 1.1.1.6 mrg if (mangled == NULL || *mangled != '_') 1352 1.1 mrg return NULL; 1353 1.1 mrg 1354 1.1 mrg mangled++; 1355 1.1 mrg string_append (decl, "\""); 1356 1.1 mrg while (len--) 1357 1.1 mrg { 1358 1.1.1.6 mrg char val; 1359 1.1.1.6 mrg const char *endptr = dlang_hexdigit (mangled, &val); 1360 1.1.1.6 mrg 1361 1.1.1.6 mrg if (endptr == NULL) 1362 1.1.1.6 mrg return NULL; 1363 1.1.1.6 mrg 1364 1.1.1.6 mrg /* Sanitize white and non-printable characters. */ 1365 1.1.1.6 mrg switch (val) 1366 1.1 mrg { 1367 1.1.1.6 mrg case ' ': 1368 1.1.1.6 mrg string_append (decl, " "); 1369 1.1.1.6 mrg break; 1370 1.1.1.6 mrg case '\t': 1371 1.1.1.6 mrg string_append (decl, "\\t"); 1372 1.1.1.6 mrg break; 1373 1.1.1.6 mrg case '\n': 1374 1.1.1.6 mrg string_append (decl, "\\n"); 1375 1.1.1.6 mrg break; 1376 1.1.1.6 mrg case '\r': 1377 1.1.1.6 mrg string_append (decl, "\\r"); 1378 1.1.1.6 mrg break; 1379 1.1.1.6 mrg case '\f': 1380 1.1.1.6 mrg string_append (decl, "\\f"); 1381 1.1.1.6 mrg break; 1382 1.1.1.6 mrg case '\v': 1383 1.1.1.6 mrg string_append (decl, "\\v"); 1384 1.1.1.6 mrg break; 1385 1.1.1.2 mrg 1386 1.1.1.6 mrg default: 1387 1.1.1.6 mrg if (ISPRINT (val)) 1388 1.1.1.6 mrg string_appendn (decl, &val, 1); 1389 1.1.1.6 mrg else 1390 1.1.1.2 mrg { 1391 1.1.1.6 mrg string_append (decl, "\\x"); 1392 1.1.1.6 mrg string_appendn (decl, mangled, 2); 1393 1.1.1.2 mrg } 1394 1.1 mrg } 1395 1.1 mrg 1396 1.1.1.6 mrg mangled = endptr; 1397 1.1 mrg } 1398 1.1 mrg string_append (decl, "\""); 1399 1.1 mrg 1400 1.1 mrg if (type != 'a') 1401 1.1 mrg string_appendn (decl, &type, 1); 1402 1.1 mrg 1403 1.1 mrg return mangled; 1404 1.1 mrg } 1405 1.1 mrg 1406 1.1 mrg /* Extract the static array value from MANGLED and append it to DECL. 1407 1.1 mrg Return the remaining string on success or NULL on failure. */ 1408 1.1 mrg static const char * 1409 1.1.1.9 mrg dlang_parse_arrayliteral (string *decl, const char *mangled, 1410 1.1.1.9 mrg struct dlang_info *info) 1411 1.1 mrg { 1412 1.1.1.9 mrg unsigned long elements; 1413 1.1 mrg 1414 1.1.1.6 mrg mangled = dlang_number (mangled, &elements); 1415 1.1.1.6 mrg if (mangled == NULL) 1416 1.1 mrg return NULL; 1417 1.1 mrg 1418 1.1 mrg string_append (decl, "["); 1419 1.1 mrg while (elements--) 1420 1.1 mrg { 1421 1.1.1.9 mrg mangled = dlang_value (decl, mangled, NULL, '\0', info); 1422 1.1.1.8 mrg if (mangled == NULL) 1423 1.1.1.8 mrg return NULL; 1424 1.1.1.8 mrg 1425 1.1 mrg if (elements != 0) 1426 1.1 mrg string_append (decl, ", "); 1427 1.1 mrg } 1428 1.1 mrg 1429 1.1 mrg string_append (decl, "]"); 1430 1.1 mrg return mangled; 1431 1.1 mrg } 1432 1.1 mrg 1433 1.1 mrg /* Extract the associative array value from MANGLED and append it to DECL. 1434 1.1 mrg Return the remaining string on success or NULL on failure. */ 1435 1.1 mrg static const char * 1436 1.1.1.9 mrg dlang_parse_assocarray (string *decl, const char *mangled, 1437 1.1.1.9 mrg struct dlang_info *info) 1438 1.1 mrg { 1439 1.1.1.9 mrg unsigned long elements; 1440 1.1 mrg 1441 1.1.1.6 mrg mangled = dlang_number (mangled, &elements); 1442 1.1.1.6 mrg if (mangled == NULL) 1443 1.1 mrg return NULL; 1444 1.1 mrg 1445 1.1 mrg string_append (decl, "["); 1446 1.1 mrg while (elements--) 1447 1.1 mrg { 1448 1.1.1.9 mrg mangled = dlang_value (decl, mangled, NULL, '\0', info); 1449 1.1.1.8 mrg if (mangled == NULL) 1450 1.1.1.8 mrg return NULL; 1451 1.1.1.8 mrg 1452 1.1 mrg string_append (decl, ":"); 1453 1.1.1.9 mrg mangled = dlang_value (decl, mangled, NULL, '\0', info); 1454 1.1.1.8 mrg if (mangled == NULL) 1455 1.1.1.8 mrg return NULL; 1456 1.1 mrg 1457 1.1 mrg if (elements != 0) 1458 1.1 mrg string_append (decl, ", "); 1459 1.1 mrg } 1460 1.1 mrg 1461 1.1 mrg string_append (decl, "]"); 1462 1.1 mrg return mangled; 1463 1.1 mrg } 1464 1.1 mrg 1465 1.1 mrg /* Extract the struct literal value for NAME from MANGLED and append it to DECL. 1466 1.1 mrg Return the remaining string on success or NULL on failure. */ 1467 1.1 mrg static const char * 1468 1.1.1.9 mrg dlang_parse_structlit (string *decl, const char *mangled, const char *name, 1469 1.1.1.9 mrg struct dlang_info *info) 1470 1.1 mrg { 1471 1.1.1.9 mrg unsigned long args; 1472 1.1 mrg 1473 1.1.1.6 mrg mangled = dlang_number (mangled, &args); 1474 1.1.1.6 mrg if (mangled == NULL) 1475 1.1 mrg return NULL; 1476 1.1 mrg 1477 1.1 mrg if (name != NULL) 1478 1.1 mrg string_append (decl, name); 1479 1.1 mrg 1480 1.1 mrg string_append (decl, "("); 1481 1.1 mrg while (args--) 1482 1.1 mrg { 1483 1.1.1.9 mrg mangled = dlang_value (decl, mangled, NULL, '\0', info); 1484 1.1.1.8 mrg if (mangled == NULL) 1485 1.1.1.8 mrg return NULL; 1486 1.1.1.8 mrg 1487 1.1 mrg if (args != 0) 1488 1.1 mrg string_append (decl, ", "); 1489 1.1 mrg } 1490 1.1 mrg 1491 1.1 mrg string_append (decl, ")"); 1492 1.1 mrg return mangled; 1493 1.1 mrg } 1494 1.1 mrg 1495 1.1 mrg /* Extract the value from MANGLED and append it to DECL. 1496 1.1 mrg Return the remaining string on success or NULL on failure. */ 1497 1.1 mrg static const char * 1498 1.1.1.9 mrg dlang_value (string *decl, const char *mangled, const char *name, char type, 1499 1.1.1.9 mrg struct dlang_info *info) 1500 1.1 mrg { 1501 1.1 mrg if (mangled == NULL || *mangled == '\0') 1502 1.1.1.2 mrg return NULL; 1503 1.1 mrg 1504 1.1 mrg switch (*mangled) 1505 1.1 mrg { 1506 1.1 mrg /* Null value. */ 1507 1.1 mrg case 'n': 1508 1.1 mrg mangled++; 1509 1.1 mrg string_append (decl, "null"); 1510 1.1 mrg break; 1511 1.1 mrg 1512 1.1 mrg /* Integral values. */ 1513 1.1 mrg case 'N': 1514 1.1 mrg mangled++; 1515 1.1 mrg string_append (decl, "-"); 1516 1.1 mrg mangled = dlang_parse_integer (decl, mangled, type); 1517 1.1 mrg break; 1518 1.1 mrg 1519 1.1 mrg case 'i': 1520 1.1 mrg mangled++; 1521 1.1 mrg /* Fall through */ 1522 1.1.1.6 mrg 1523 1.1.1.6 mrg /* There really should always be an `i' before encoded numbers, but there 1524 1.1.1.6 mrg wasn't in early versions of D2, so this case range must remain for 1525 1.1.1.6 mrg backwards compatibility. */ 1526 1.1 mrg case '0': case '1': case '2': case '3': case '4': 1527 1.1 mrg case '5': case '6': case '7': case '8': case '9': 1528 1.1 mrg mangled = dlang_parse_integer (decl, mangled, type); 1529 1.1 mrg break; 1530 1.1 mrg 1531 1.1 mrg /* Real value. */ 1532 1.1 mrg case 'e': 1533 1.1 mrg mangled++; 1534 1.1 mrg mangled = dlang_parse_real (decl, mangled); 1535 1.1 mrg break; 1536 1.1 mrg 1537 1.1 mrg /* Complex value. */ 1538 1.1 mrg case 'c': 1539 1.1 mrg mangled++; 1540 1.1 mrg mangled = dlang_parse_real (decl, mangled); 1541 1.1 mrg string_append (decl, "+"); 1542 1.1 mrg if (mangled == NULL || *mangled != 'c') 1543 1.1 mrg return NULL; 1544 1.1 mrg mangled++; 1545 1.1 mrg mangled = dlang_parse_real (decl, mangled); 1546 1.1 mrg string_append (decl, "i"); 1547 1.1 mrg break; 1548 1.1 mrg 1549 1.1 mrg /* String values. */ 1550 1.1 mrg case 'a': /* UTF8 */ 1551 1.1 mrg case 'w': /* UTF16 */ 1552 1.1 mrg case 'd': /* UTF32 */ 1553 1.1 mrg mangled = dlang_parse_string (decl, mangled); 1554 1.1 mrg break; 1555 1.1 mrg 1556 1.1 mrg /* Array values. */ 1557 1.1 mrg case 'A': 1558 1.1 mrg mangled++; 1559 1.1 mrg if (type == 'H') 1560 1.1.1.9 mrg mangled = dlang_parse_assocarray (decl, mangled, info); 1561 1.1 mrg else 1562 1.1.1.9 mrg mangled = dlang_parse_arrayliteral (decl, mangled, info); 1563 1.1 mrg break; 1564 1.1 mrg 1565 1.1 mrg /* Struct values. */ 1566 1.1 mrg case 'S': 1567 1.1 mrg mangled++; 1568 1.1.1.9 mrg mangled = dlang_parse_structlit (decl, mangled, name, info); 1569 1.1.1.9 mrg break; 1570 1.1.1.9 mrg 1571 1.1.1.9 mrg /* Function literal symbol. */ 1572 1.1.1.9 mrg case 'f': 1573 1.1.1.9 mrg mangled++; 1574 1.1.1.9 mrg if (strncmp (mangled, "_D", 2) != 0 1575 1.1.1.9 mrg || !dlang_symbol_name_p (mangled + 2, info)) 1576 1.1.1.9 mrg return NULL; 1577 1.1.1.9 mrg mangled = dlang_parse_mangle (decl, mangled, info); 1578 1.1 mrg break; 1579 1.1 mrg 1580 1.1 mrg default: 1581 1.1 mrg return NULL; 1582 1.1 mrg } 1583 1.1 mrg 1584 1.1 mrg return mangled; 1585 1.1 mrg } 1586 1.1 mrg 1587 1.1.1.6 mrg /* Extract and demangle the symbol in MANGLED and append it to DECL. 1588 1.1.1.6 mrg Returns the remaining signature on success or NULL on failure. */ 1589 1.1.1.6 mrg static const char * 1590 1.1.1.9 mrg dlang_parse_mangle (string *decl, const char *mangled, struct dlang_info *info) 1591 1.1 mrg { 1592 1.1.1.6 mrg /* A D mangled symbol is comprised of both scope and type information. 1593 1.1.1.2 mrg 1594 1.1.1.6 mrg MangleName: 1595 1.1.1.6 mrg _D QualifiedName Type 1596 1.1.1.6 mrg _D QualifiedName Z 1597 1.1.1.6 mrg ^ 1598 1.1.1.6 mrg The caller should have guaranteed that the start pointer is at the 1599 1.1.1.6 mrg above location. 1600 1.1.1.9 mrg Note that type is never a function type, but only the return type of 1601 1.1.1.9 mrg a function or the type of a variable. 1602 1.1.1.6 mrg */ 1603 1.1.1.6 mrg mangled += 2; 1604 1.1.1.4 mrg 1605 1.1.1.9 mrg mangled = dlang_parse_qualified (decl, mangled, info, 1); 1606 1.1.1.4 mrg 1607 1.1.1.6 mrg if (mangled != NULL) 1608 1.1.1.6 mrg { 1609 1.1.1.6 mrg /* Artificial symbols end with 'Z' and have no type. */ 1610 1.1.1.6 mrg if (*mangled == 'Z') 1611 1.1.1.6 mrg mangled++; 1612 1.1.1.6 mrg else 1613 1.1.1.5 mrg { 1614 1.1.1.9 mrg /* Discard the declaration or return type. */ 1615 1.1.1.9 mrg string type; 1616 1.1.1.6 mrg 1617 1.1.1.9 mrg string_init (&type); 1618 1.1.1.9 mrg mangled = dlang_type (&type, mangled, info); 1619 1.1.1.9 mrg string_delete (&type); 1620 1.1.1.6 mrg } 1621 1.1 mrg } 1622 1.1.1.4 mrg 1623 1.1.1.6 mrg return mangled; 1624 1.1 mrg } 1625 1.1 mrg 1626 1.1.1.6 mrg /* Extract and demangle the qualified symbol in MANGLED and append it to DECL. 1627 1.1.1.9 mrg SUFFIX_MODIFIERS is 1 if we are printing modifiers on this after the symbol. 1628 1.1 mrg Returns the remaining signature on success or NULL on failure. */ 1629 1.1 mrg static const char * 1630 1.1.1.6 mrg dlang_parse_qualified (string *decl, const char *mangled, 1631 1.1.1.9 mrg struct dlang_info *info, int suffix_modifiers) 1632 1.1 mrg { 1633 1.1.1.6 mrg /* Qualified names are identifiers separated by their encoded length. 1634 1.1.1.6 mrg Nested functions also encode their argument types without specifying 1635 1.1.1.6 mrg what they return. 1636 1.1.1.6 mrg 1637 1.1.1.6 mrg QualifiedName: 1638 1.1.1.9 mrg SymbolFunctionName 1639 1.1.1.9 mrg SymbolFunctionName QualifiedName 1640 1.1.1.6 mrg ^ 1641 1.1.1.9 mrg 1642 1.1.1.9 mrg SymbolFunctionName: 1643 1.1.1.9 mrg SymbolName 1644 1.1.1.9 mrg SymbolName TypeFunctionNoReturn 1645 1.1.1.9 mrg SymbolName M TypeFunctionNoReturn 1646 1.1.1.9 mrg SymbolName M TypeModifiers TypeFunctionNoReturn 1647 1.1.1.9 mrg 1648 1.1.1.6 mrg The start pointer should be at the above location. 1649 1.1.1.6 mrg */ 1650 1.1 mrg size_t n = 0; 1651 1.1 mrg do 1652 1.1 mrg { 1653 1.1.1.9 mrg /* Skip over anonymous symbols. */ 1654 1.1.1.9 mrg if (*mangled == '0') 1655 1.1.1.9 mrg { 1656 1.1.1.9 mrg do 1657 1.1.1.9 mrg mangled++; 1658 1.1.1.9 mrg while (*mangled == '0'); 1659 1.1.1.9 mrg 1660 1.1.1.9 mrg continue; 1661 1.1.1.9 mrg } 1662 1.1.1.9 mrg 1663 1.1 mrg if (n++) 1664 1.1 mrg string_append (decl, "."); 1665 1.1 mrg 1666 1.1.1.9 mrg mangled = dlang_identifier (decl, mangled, info); 1667 1.1 mrg 1668 1.1.1.6 mrg /* Consume the encoded arguments. However if this is not followed by the 1669 1.1.1.9 mrg next encoded length or mangle type, then this is not a continuation of 1670 1.1.1.9 mrg a qualified name, in which case we backtrack and return the current 1671 1.1.1.9 mrg unconsumed position of the mangled decl. */ 1672 1.1.1.6 mrg if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled))) 1673 1.1 mrg { 1674 1.1.1.9 mrg string mods; 1675 1.1.1.6 mrg const char *start = mangled; 1676 1.1.1.6 mrg int saved = string_length (decl); 1677 1.1 mrg 1678 1.1.1.9 mrg /* Save the type modifiers for appending at the end if needed. */ 1679 1.1.1.9 mrg string_init (&mods); 1680 1.1.1.9 mrg 1681 1.1.1.6 mrg /* Skip over 'this' parameter and type modifiers. */ 1682 1.1 mrg if (*mangled == 'M') 1683 1.1.1.2 mrg { 1684 1.1.1.6 mrg mangled++; 1685 1.1.1.9 mrg mangled = dlang_type_modifiers (&mods, mangled); 1686 1.1.1.6 mrg string_setlength (decl, saved); 1687 1.1.1.2 mrg } 1688 1.1.1.2 mrg 1689 1.1.1.9 mrg mangled = dlang_function_type_noreturn (decl, NULL, NULL, 1690 1.1.1.9 mrg mangled, info); 1691 1.1.1.9 mrg if (suffix_modifiers) 1692 1.1.1.9 mrg string_appendn (decl, mods.b, string_length (&mods)); 1693 1.1.1.4 mrg 1694 1.1.1.9 mrg if (mangled == NULL || *mangled == '\0') 1695 1.1 mrg { 1696 1.1.1.6 mrg /* Did not match the rule we were looking for. */ 1697 1.1.1.2 mrg mangled = start; 1698 1.1.1.6 mrg string_setlength (decl, saved); 1699 1.1 mrg } 1700 1.1.1.9 mrg 1701 1.1.1.9 mrg string_delete (&mods); 1702 1.1 mrg } 1703 1.1 mrg } 1704 1.1.1.9 mrg while (mangled && dlang_symbol_name_p (mangled, info)); 1705 1.1 mrg 1706 1.1 mrg return mangled; 1707 1.1 mrg } 1708 1.1 mrg 1709 1.1 mrg /* Demangle the tuple from MANGLED and append it to DECL. 1710 1.1 mrg Return the remaining string on success or NULL on failure. */ 1711 1.1 mrg static const char * 1712 1.1.1.9 mrg dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info) 1713 1.1 mrg { 1714 1.1.1.9 mrg unsigned long elements; 1715 1.1 mrg 1716 1.1.1.6 mrg mangled = dlang_number (mangled, &elements); 1717 1.1.1.6 mrg if (mangled == NULL) 1718 1.1 mrg return NULL; 1719 1.1 mrg 1720 1.1 mrg string_append (decl, "Tuple!("); 1721 1.1 mrg 1722 1.1 mrg while (elements--) 1723 1.1 mrg { 1724 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 1725 1.1.1.8 mrg if (mangled == NULL) 1726 1.1.1.8 mrg return NULL; 1727 1.1.1.8 mrg 1728 1.1 mrg if (elements != 0) 1729 1.1 mrg string_append (decl, ", "); 1730 1.1 mrg } 1731 1.1 mrg 1732 1.1 mrg string_append (decl, ")"); 1733 1.1 mrg return mangled; 1734 1.1 mrg } 1735 1.1 mrg 1736 1.1.1.9 mrg /* Demangle the template symbol parameter from MANGLED and append it to DECL. 1737 1.1.1.9 mrg Return the remaining string on success or NULL on failure. */ 1738 1.1.1.9 mrg static const char * 1739 1.1.1.9 mrg dlang_template_symbol_param (string *decl, const char *mangled, 1740 1.1.1.9 mrg struct dlang_info *info) 1741 1.1.1.9 mrg { 1742 1.1.1.9 mrg if (strncmp (mangled, "_D", 2) == 0 1743 1.1.1.9 mrg && dlang_symbol_name_p (mangled + 2, info)) 1744 1.1.1.9 mrg return dlang_parse_mangle (decl, mangled, info); 1745 1.1.1.9 mrg 1746 1.1.1.9 mrg if (*mangled == 'Q') 1747 1.1.1.9 mrg return dlang_parse_qualified (decl, mangled, info, 0); 1748 1.1.1.9 mrg 1749 1.1.1.9 mrg unsigned long len; 1750 1.1.1.9 mrg const char *endptr = dlang_number (mangled, &len); 1751 1.1.1.9 mrg 1752 1.1.1.9 mrg if (endptr == NULL || len == 0) 1753 1.1.1.9 mrg return NULL; 1754 1.1.1.9 mrg 1755 1.1.1.9 mrg /* In template parameter symbols generated by the frontend up to 2.076, 1756 1.1.1.9 mrg the symbol length is encoded and the first character of the mangled 1757 1.1.1.9 mrg name can be a digit. This causes ambiguity issues because the digits 1758 1.1.1.9 mrg of the two numbers are adjacent. */ 1759 1.1.1.9 mrg long psize = len; 1760 1.1.1.9 mrg const char *pend; 1761 1.1.1.9 mrg int saved = string_length (decl); 1762 1.1.1.9 mrg 1763 1.1.1.9 mrg /* Work backwards until a match is found. */ 1764 1.1.1.9 mrg for (pend = endptr; endptr != NULL; pend--) 1765 1.1.1.9 mrg { 1766 1.1.1.9 mrg mangled = pend; 1767 1.1.1.9 mrg 1768 1.1.1.9 mrg /* Reached the beginning of the pointer to the name length, 1769 1.1.1.9 mrg try parsing the entire symbol. */ 1770 1.1.1.9 mrg if (psize == 0) 1771 1.1.1.9 mrg { 1772 1.1.1.9 mrg psize = len; 1773 1.1.1.9 mrg pend = endptr; 1774 1.1.1.9 mrg endptr = NULL; 1775 1.1.1.9 mrg } 1776 1.1.1.9 mrg 1777 1.1.1.9 mrg /* Check whether template parameter is a function with a valid 1778 1.1.1.9 mrg return type or an untyped identifier. */ 1779 1.1.1.9 mrg if (dlang_symbol_name_p (mangled, info)) 1780 1.1.1.9 mrg mangled = dlang_parse_qualified (decl, mangled, info, 0); 1781 1.1.1.9 mrg else if (strncmp (mangled, "_D", 2) == 0 1782 1.1.1.9 mrg && dlang_symbol_name_p (mangled + 2, info)) 1783 1.1.1.9 mrg mangled = dlang_parse_mangle (decl, mangled, info); 1784 1.1.1.9 mrg 1785 1.1.1.9 mrg /* Check for name length mismatch. */ 1786 1.1.1.9 mrg if (mangled && (endptr == NULL || (mangled - pend) == psize)) 1787 1.1.1.9 mrg return mangled; 1788 1.1.1.9 mrg 1789 1.1.1.9 mrg psize /= 10; 1790 1.1.1.9 mrg string_setlength (decl, saved); 1791 1.1.1.9 mrg } 1792 1.1.1.9 mrg 1793 1.1.1.9 mrg /* No match on any combinations. */ 1794 1.1.1.9 mrg return NULL; 1795 1.1.1.9 mrg } 1796 1.1.1.9 mrg 1797 1.1 mrg /* Demangle the argument list from MANGLED and append it to DECL. 1798 1.1 mrg Return the remaining string on success or NULL on failure. */ 1799 1.1 mrg static const char * 1800 1.1.1.9 mrg dlang_template_args (string *decl, const char *mangled, struct dlang_info *info) 1801 1.1 mrg { 1802 1.1 mrg size_t n = 0; 1803 1.1 mrg 1804 1.1 mrg while (mangled && *mangled != '\0') 1805 1.1 mrg { 1806 1.1 mrg switch (*mangled) 1807 1.1 mrg { 1808 1.1 mrg case 'Z': /* End of parameter list. */ 1809 1.1 mrg mangled++; 1810 1.1 mrg return mangled; 1811 1.1 mrg } 1812 1.1 mrg 1813 1.1 mrg if (n++) 1814 1.1 mrg string_append (decl, ", "); 1815 1.1 mrg 1816 1.1.1.2 mrg /* Skip over specialised template prefix. */ 1817 1.1.1.2 mrg if (*mangled == 'H') 1818 1.1.1.2 mrg mangled++; 1819 1.1.1.2 mrg 1820 1.1 mrg switch (*mangled) 1821 1.1 mrg { 1822 1.1 mrg case 'S': /* Symbol parameter. */ 1823 1.1 mrg mangled++; 1824 1.1.1.9 mrg mangled = dlang_template_symbol_param (decl, mangled, info); 1825 1.1 mrg break; 1826 1.1 mrg case 'T': /* Type parameter. */ 1827 1.1 mrg mangled++; 1828 1.1.1.9 mrg mangled = dlang_type (decl, mangled, info); 1829 1.1 mrg break; 1830 1.1 mrg case 'V': /* Value parameter. */ 1831 1.1 mrg { 1832 1.1 mrg string name; 1833 1.1 mrg char type; 1834 1.1 mrg 1835 1.1 mrg /* Peek at the type. */ 1836 1.1 mrg mangled++; 1837 1.1 mrg type = *mangled; 1838 1.1 mrg 1839 1.1.1.9 mrg if (type == 'Q') 1840 1.1.1.9 mrg { 1841 1.1.1.9 mrg /* Value type is a back reference, peek at the real type. */ 1842 1.1.1.9 mrg const char *backref; 1843 1.1.1.9 mrg if (dlang_backref (mangled, &backref, info) == NULL) 1844 1.1.1.9 mrg return NULL; 1845 1.1.1.9 mrg 1846 1.1.1.9 mrg type = *backref; 1847 1.1.1.9 mrg } 1848 1.1.1.9 mrg 1849 1.1 mrg /* In the few instances where the type is actually desired in 1850 1.1 mrg the output, it should precede the value from dlang_value. */ 1851 1.1 mrg string_init (&name); 1852 1.1.1.9 mrg mangled = dlang_type (&name, mangled, info); 1853 1.1 mrg string_need (&name, 1); 1854 1.1 mrg *(name.p) = '\0'; 1855 1.1 mrg 1856 1.1.1.9 mrg mangled = dlang_value (decl, mangled, name.b, type, info); 1857 1.1 mrg string_delete (&name); 1858 1.1 mrg break; 1859 1.1 mrg } 1860 1.1.1.9 mrg case 'X': /* Externally mangled parameter. */ 1861 1.1.1.9 mrg { 1862 1.1.1.9 mrg unsigned long len; 1863 1.1.1.9 mrg const char *endptr; 1864 1.1.1.9 mrg 1865 1.1.1.9 mrg mangled++; 1866 1.1.1.9 mrg endptr = dlang_number (mangled, &len); 1867 1.1.1.9 mrg if (endptr == NULL || strlen (endptr) < len) 1868 1.1.1.9 mrg return NULL; 1869 1.1 mrg 1870 1.1.1.9 mrg string_appendn (decl, endptr, len); 1871 1.1.1.9 mrg mangled = endptr + len; 1872 1.1.1.9 mrg break; 1873 1.1.1.9 mrg } 1874 1.1 mrg default: 1875 1.1 mrg return NULL; 1876 1.1 mrg } 1877 1.1 mrg } 1878 1.1 mrg 1879 1.1 mrg return mangled; 1880 1.1 mrg } 1881 1.1 mrg 1882 1.1 mrg /* Extract and demangle the template symbol in MANGLED, expected to 1883 1.1.1.9 mrg be made up of LEN characters (-1 if unknown), and append it to DECL. 1884 1.1 mrg Returns the remaining signature on success or NULL on failure. */ 1885 1.1 mrg static const char * 1886 1.1.1.9 mrg dlang_parse_template (string *decl, const char *mangled, 1887 1.1.1.9 mrg struct dlang_info *info, unsigned long len) 1888 1.1 mrg { 1889 1.1 mrg const char *start = mangled; 1890 1.1.1.9 mrg string args; 1891 1.1 mrg 1892 1.1 mrg /* Template instance names have the types and values of its parameters 1893 1.1 mrg encoded into it. 1894 1.1 mrg 1895 1.1 mrg TemplateInstanceName: 1896 1.1 mrg Number __T LName TemplateArgs Z 1897 1.1.1.6 mrg Number __U LName TemplateArgs Z 1898 1.1 mrg ^ 1899 1.1 mrg The start pointer should be at the above location, and LEN should be 1900 1.1 mrg the value of the decoded number. 1901 1.1 mrg */ 1902 1.1.1.6 mrg 1903 1.1.1.6 mrg /* Template symbol. */ 1904 1.1.1.9 mrg if (!dlang_symbol_name_p (mangled + 3, info) || mangled[3] == '0') 1905 1.1 mrg return NULL; 1906 1.1 mrg 1907 1.1 mrg mangled += 3; 1908 1.1 mrg 1909 1.1 mrg /* Template identifier. */ 1910 1.1.1.9 mrg mangled = dlang_identifier (decl, mangled, info); 1911 1.1 mrg 1912 1.1 mrg /* Template arguments. */ 1913 1.1.1.9 mrg string_init (&args); 1914 1.1.1.9 mrg mangled = dlang_template_args (&args, mangled, info); 1915 1.1.1.9 mrg 1916 1.1 mrg string_append (decl, "!("); 1917 1.1.1.9 mrg string_appendn (decl, args.b, string_length (&args)); 1918 1.1 mrg string_append (decl, ")"); 1919 1.1 mrg 1920 1.1.1.9 mrg string_delete (&args); 1921 1.1.1.9 mrg 1922 1.1 mrg /* Check for template name length mismatch. */ 1923 1.1.1.9 mrg if (len != TEMPLATE_LENGTH_UNKNOWN 1924 1.1.1.9 mrg && mangled 1925 1.1.1.9 mrg && (unsigned long) (mangled - start) != len) 1926 1.1 mrg return NULL; 1927 1.1 mrg 1928 1.1 mrg return mangled; 1929 1.1 mrg } 1930 1.1 mrg 1931 1.1.1.9 mrg /* Initialize the information structure we use to pass around information. */ 1932 1.1.1.9 mrg static void 1933 1.1.1.9 mrg dlang_demangle_init_info (const char *mangled, int last_backref, 1934 1.1.1.9 mrg struct dlang_info *info) 1935 1.1.1.9 mrg { 1936 1.1.1.9 mrg info->s = mangled; 1937 1.1.1.9 mrg info->last_backref = last_backref; 1938 1.1.1.9 mrg } 1939 1.1.1.9 mrg 1940 1.1 mrg /* Extract and demangle the symbol in MANGLED. Returns the demangled 1941 1.1 mrg signature on success or NULL on failure. */ 1942 1.1 mrg 1943 1.1 mrg char * 1944 1.1 mrg dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) 1945 1.1 mrg { 1946 1.1 mrg string decl; 1947 1.1 mrg char *demangled = NULL; 1948 1.1 mrg 1949 1.1 mrg if (mangled == NULL || *mangled == '\0') 1950 1.1 mrg return NULL; 1951 1.1 mrg 1952 1.1 mrg if (strncmp (mangled, "_D", 2) != 0) 1953 1.1 mrg return NULL; 1954 1.1 mrg 1955 1.1 mrg string_init (&decl); 1956 1.1 mrg 1957 1.1 mrg if (strcmp (mangled, "_Dmain") == 0) 1958 1.1 mrg { 1959 1.1 mrg string_append (&decl, "D main"); 1960 1.1 mrg } 1961 1.1 mrg else 1962 1.1 mrg { 1963 1.1.1.9 mrg struct dlang_info info; 1964 1.1.1.9 mrg 1965 1.1.1.9 mrg dlang_demangle_init_info (mangled, strlen (mangled), &info); 1966 1.1.1.9 mrg mangled = dlang_parse_mangle (&decl, mangled, &info); 1967 1.1.1.9 mrg 1968 1.1.1.9 mrg /* Check that the entire symbol was successfully demangled. */ 1969 1.1.1.9 mrg if (mangled == NULL || *mangled != '\0') 1970 1.1 mrg string_delete (&decl); 1971 1.1 mrg } 1972 1.1 mrg 1973 1.1 mrg if (string_length (&decl) > 0) 1974 1.1 mrg { 1975 1.1 mrg string_need (&decl, 1); 1976 1.1 mrg *(decl.p) = '\0'; 1977 1.1 mrg demangled = decl.b; 1978 1.1 mrg } 1979 1.1 mrg 1980 1.1 mrg return demangled; 1981 1.1 mrg } 1982 1.1 mrg 1983