cxxfilt 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/cxxfilt.gemspec +2 -2
- data/ext/cxxfilt/ansidecl.h +7 -89
- data/ext/cxxfilt/cp-demangle.c +980 -361
- data/ext/cxxfilt/cp-demangle.h +9 -2
- data/ext/cxxfilt/cp-demint.c +4 -1
- data/ext/cxxfilt/cplus-dem.c +19 -4589
- data/ext/cxxfilt/d-demangle.c +645 -309
- data/ext/cxxfilt/demangle.h +58 -51
- data/ext/cxxfilt/environ.h +1 -1
- data/ext/cxxfilt/extconf.rb +1 -0
- data/ext/cxxfilt/libiberty.h +52 -20
- data/ext/cxxfilt/rust-demangle.c +1508 -252
- data/ext/cxxfilt/safe-ctype.c +1 -1
- data/ext/cxxfilt/safe-ctype.h +2 -2
- data/ext/cxxfilt/xexit.c +1 -1
- data/ext/cxxfilt/xmalloc.c +10 -8
- data/ext/cxxfilt/xmemdup.c +4 -4
- data/lib/cxxfilt/version.rb +1 -1
- metadata +11 -11
data/ext/cxxfilt/d-demangle.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* Demangler for the D programming language
|
2
|
-
Copyright (C) 2014-
|
2
|
+
Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
3
3
|
Written by Iain Buclaw (ibuclaw@gdcproject.org)
|
4
4
|
|
5
5
|
This file is part of the libiberty library.
|
@@ -31,6 +31,9 @@ If not, see <http://www.gnu.org/licenses/>. */
|
|
31
31
|
#ifdef HAVE_CONFIG_H
|
32
32
|
#include "config.h"
|
33
33
|
#endif
|
34
|
+
#ifdef HAVE_LIMITS_H
|
35
|
+
#include <limits.h>
|
36
|
+
#endif
|
34
37
|
|
35
38
|
#include "safe-ctype.h"
|
36
39
|
|
@@ -45,6 +48,13 @@ If not, see <http://www.gnu.org/licenses/>. */
|
|
45
48
|
#include <demangle.h>
|
46
49
|
#include "libiberty.h"
|
47
50
|
|
51
|
+
#ifndef ULONG_MAX
|
52
|
+
#define ULONG_MAX (~0UL)
|
53
|
+
#endif
|
54
|
+
#ifndef UINT_MAX
|
55
|
+
#define UINT_MAX (~0U)
|
56
|
+
#endif
|
57
|
+
|
48
58
|
/* A mini string-handling package */
|
49
59
|
|
50
60
|
typedef struct string /* Beware: these aren't required to be */
|
@@ -55,9 +65,9 @@ typedef struct string /* Beware: these aren't required to be */
|
|
55
65
|
} string;
|
56
66
|
|
57
67
|
static void
|
58
|
-
string_need (string *s,
|
68
|
+
string_need (string *s, size_t n)
|
59
69
|
{
|
60
|
-
|
70
|
+
size_t tem;
|
61
71
|
|
62
72
|
if (s->b == NULL)
|
63
73
|
{
|
@@ -68,7 +78,7 @@ string_need (string *s, int n)
|
|
68
78
|
s->p = s->b = XNEWVEC (char, n);
|
69
79
|
s->e = s->b + n;
|
70
80
|
}
|
71
|
-
else if (s->e - s->p < n)
|
81
|
+
else if ((size_t) (s->e - s->p) < n)
|
72
82
|
{
|
73
83
|
tem = s->p - s->b;
|
74
84
|
n += tem;
|
@@ -117,14 +127,14 @@ string_setlength (string *s, int n)
|
|
117
127
|
static void
|
118
128
|
string_append (string *p, const char *s)
|
119
129
|
{
|
120
|
-
|
130
|
+
size_t n = strlen (s);
|
121
131
|
string_need (p, n);
|
122
132
|
memcpy (p->p, s, n);
|
123
133
|
p->p += n;
|
124
134
|
}
|
125
135
|
|
126
136
|
static void
|
127
|
-
string_appendn (string *p, const char *s,
|
137
|
+
string_appendn (string *p, const char *s, size_t n)
|
128
138
|
{
|
129
139
|
if (n != 0)
|
130
140
|
{
|
@@ -135,7 +145,7 @@ string_appendn (string *p, const char *s, int n)
|
|
135
145
|
}
|
136
146
|
|
137
147
|
static void
|
138
|
-
string_prependn (string *p, const char *s,
|
148
|
+
string_prependn (string *p, const char *s, size_t n)
|
139
149
|
{
|
140
150
|
char *q;
|
141
151
|
|
@@ -160,66 +170,73 @@ string_prepend (string *p, const char *s)
|
|
160
170
|
}
|
161
171
|
}
|
162
172
|
|
163
|
-
/*
|
164
|
-
|
173
|
+
/* Demangle information structure we pass around. */
|
174
|
+
struct dlang_info
|
165
175
|
{
|
166
|
-
/*
|
167
|
-
|
168
|
-
/*
|
169
|
-
|
170
|
-
/* Strongly typed name, such as for classes, structs and enums. */
|
171
|
-
dlang_type_name,
|
172
|
-
/* Template identifier. */
|
173
|
-
dlang_template_ident,
|
174
|
-
/* Template symbol parameter. */
|
175
|
-
dlang_template_param
|
176
|
+
/* The string we are demangling. */
|
177
|
+
const char *s;
|
178
|
+
/* The index of the last back reference. */
|
179
|
+
int last_backref;
|
176
180
|
};
|
177
181
|
|
182
|
+
/* Pass as the LEN to dlang_parse_template if symbol length is not known. */
|
183
|
+
#define TEMPLATE_LENGTH_UNKNOWN (-1UL)
|
184
|
+
|
178
185
|
/* Prototypes for forward referenced functions */
|
179
|
-
static const char *
|
186
|
+
static const char *dlang_function_type (string *, const char *,
|
187
|
+
struct dlang_info *);
|
188
|
+
|
189
|
+
static const char *dlang_function_args (string *, const char *,
|
190
|
+
struct dlang_info *);
|
180
191
|
|
181
|
-
static const char *dlang_type (string *, const char *);
|
192
|
+
static const char *dlang_type (string *, const char *, struct dlang_info *);
|
182
193
|
|
183
|
-
static const char *dlang_value (string *, const char *, const char *, char
|
194
|
+
static const char *dlang_value (string *, const char *, const char *, char,
|
195
|
+
struct dlang_info *);
|
184
196
|
|
185
197
|
static const char *dlang_parse_qualified (string *, const char *,
|
186
|
-
|
198
|
+
struct dlang_info *, int);
|
187
199
|
|
188
200
|
static const char *dlang_parse_mangle (string *, const char *,
|
189
|
-
|
201
|
+
struct dlang_info *);
|
202
|
+
|
203
|
+
static const char *dlang_parse_tuple (string *, const char *,
|
204
|
+
struct dlang_info *);
|
190
205
|
|
191
|
-
static const char *
|
206
|
+
static const char *dlang_parse_template (string *, const char *,
|
207
|
+
struct dlang_info *, unsigned long);
|
192
208
|
|
193
|
-
static const char *
|
209
|
+
static const char *dlang_lname (string *, const char *, unsigned long);
|
194
210
|
|
195
211
|
|
196
212
|
/* Extract the number from MANGLED, and assign the result to RET.
|
197
|
-
Return the remaining string on success or NULL on failure.
|
213
|
+
Return the remaining string on success or NULL on failure.
|
214
|
+
A result larger than UINT_MAX is considered a failure. */
|
198
215
|
static const char *
|
199
|
-
dlang_number (const char *mangled, long *ret)
|
216
|
+
dlang_number (const char *mangled, unsigned long *ret)
|
200
217
|
{
|
201
218
|
/* Return NULL if trying to extract something that isn't a digit. */
|
202
219
|
if (mangled == NULL || !ISDIGIT (*mangled))
|
203
220
|
return NULL;
|
204
221
|
|
205
|
-
|
222
|
+
unsigned long val = 0;
|
206
223
|
|
207
224
|
while (ISDIGIT (*mangled))
|
208
225
|
{
|
209
|
-
|
226
|
+
unsigned long digit = mangled[0] - '0';
|
210
227
|
|
211
|
-
/*
|
212
|
-
|
213
|
-
if ((*ret % 10) != 0)
|
228
|
+
/* Check for overflow. */
|
229
|
+
if (val > (UINT_MAX - digit) / 10)
|
214
230
|
return NULL;
|
215
231
|
|
216
|
-
|
232
|
+
val = val * 10 + digit;
|
217
233
|
mangled++;
|
218
234
|
}
|
219
235
|
|
220
|
-
if (*mangled == '\0'
|
236
|
+
if (*mangled == '\0')
|
221
237
|
return NULL;
|
222
238
|
|
239
|
+
*ret = val;
|
223
240
|
return mangled;
|
224
241
|
}
|
225
242
|
|
@@ -236,15 +253,15 @@ dlang_hexdigit (const char *mangled, char *ret)
|
|
236
253
|
|
237
254
|
c = mangled[0];
|
238
255
|
if (!ISDIGIT (c))
|
239
|
-
|
256
|
+
*ret = c - (ISUPPER (c) ? 'A' : 'a') + 10;
|
240
257
|
else
|
241
|
-
|
258
|
+
*ret = c - '0';
|
242
259
|
|
243
260
|
c = mangled[1];
|
244
261
|
if (!ISDIGIT (c))
|
245
|
-
|
262
|
+
*ret = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10);
|
246
263
|
else
|
247
|
-
|
264
|
+
*ret = (*ret << 4) | (c - '0');
|
248
265
|
|
249
266
|
mangled += 2;
|
250
267
|
|
@@ -267,6 +284,178 @@ dlang_call_convention_p (const char *mangled)
|
|
267
284
|
}
|
268
285
|
}
|
269
286
|
|
287
|
+
/* Extract the back reference position from MANGLED, and assign the result
|
288
|
+
to RET. Return the remaining string on success or NULL on failure.
|
289
|
+
A result <= 0 is a failure. */
|
290
|
+
static const char *
|
291
|
+
dlang_decode_backref (const char *mangled, long *ret)
|
292
|
+
{
|
293
|
+
/* Return NULL if trying to extract something that isn't a digit. */
|
294
|
+
if (mangled == NULL || !ISALPHA (*mangled))
|
295
|
+
return NULL;
|
296
|
+
|
297
|
+
/* Any identifier or non-basic type that has been emitted to the mangled
|
298
|
+
symbol before will not be emitted again, but is referenced by a special
|
299
|
+
sequence encoding the relative position of the original occurrence in the
|
300
|
+
mangled symbol name.
|
301
|
+
|
302
|
+
Numbers in back references are encoded with base 26 by upper case letters
|
303
|
+
A-Z for higher digits but lower case letters a-z for the last digit.
|
304
|
+
|
305
|
+
NumberBackRef:
|
306
|
+
[a-z]
|
307
|
+
[A-Z] NumberBackRef
|
308
|
+
^
|
309
|
+
*/
|
310
|
+
unsigned long val = 0;
|
311
|
+
|
312
|
+
while (ISALPHA (*mangled))
|
313
|
+
{
|
314
|
+
/* Check for overflow. */
|
315
|
+
if (val > (ULONG_MAX - 25) / 26)
|
316
|
+
break;
|
317
|
+
|
318
|
+
val *= 26;
|
319
|
+
|
320
|
+
if (mangled[0] >= 'a' && mangled[0] <= 'z')
|
321
|
+
{
|
322
|
+
val += mangled[0] - 'a';
|
323
|
+
if ((long) val <= 0)
|
324
|
+
break;
|
325
|
+
*ret = val;
|
326
|
+
return mangled + 1;
|
327
|
+
}
|
328
|
+
|
329
|
+
val += mangled[0] - 'A';
|
330
|
+
mangled++;
|
331
|
+
}
|
332
|
+
|
333
|
+
return NULL;
|
334
|
+
}
|
335
|
+
|
336
|
+
/* Extract the symbol pointed at by the back reference and assign the result
|
337
|
+
to RET. Return the remaining string on success or NULL on failure. */
|
338
|
+
static const char *
|
339
|
+
dlang_backref (const char *mangled, const char **ret, struct dlang_info *info)
|
340
|
+
{
|
341
|
+
*ret = NULL;
|
342
|
+
|
343
|
+
if (mangled == NULL || *mangled != 'Q')
|
344
|
+
return NULL;
|
345
|
+
|
346
|
+
/* Position of 'Q'. */
|
347
|
+
const char *qpos = mangled;
|
348
|
+
long refpos;
|
349
|
+
mangled++;
|
350
|
+
|
351
|
+
mangled = dlang_decode_backref (mangled, &refpos);
|
352
|
+
if (mangled == NULL)
|
353
|
+
return NULL;
|
354
|
+
|
355
|
+
if (refpos > qpos - info->s)
|
356
|
+
return NULL;
|
357
|
+
|
358
|
+
/* Set the position of the back reference. */
|
359
|
+
*ret = qpos - refpos;
|
360
|
+
|
361
|
+
return mangled;
|
362
|
+
}
|
363
|
+
|
364
|
+
/* Demangle a back referenced symbol from MANGLED and append it to DECL.
|
365
|
+
Return the remaining string on success or NULL on failure. */
|
366
|
+
static const char *
|
367
|
+
dlang_symbol_backref (string *decl, const char *mangled,
|
368
|
+
struct dlang_info *info)
|
369
|
+
{
|
370
|
+
/* An identifier back reference always points to a digit 0 to 9.
|
371
|
+
|
372
|
+
IdentifierBackRef:
|
373
|
+
Q NumberBackRef
|
374
|
+
^
|
375
|
+
*/
|
376
|
+
const char *backref;
|
377
|
+
unsigned long len;
|
378
|
+
|
379
|
+
/* Get position of the back reference. */
|
380
|
+
mangled = dlang_backref (mangled, &backref, info);
|
381
|
+
|
382
|
+
/* Must point to a simple identifier. */
|
383
|
+
backref = dlang_number (backref, &len);
|
384
|
+
if (backref == NULL || strlen(backref) < len)
|
385
|
+
return NULL;
|
386
|
+
|
387
|
+
backref = dlang_lname (decl, backref, len);
|
388
|
+
if (backref == NULL)
|
389
|
+
return NULL;
|
390
|
+
|
391
|
+
return mangled;
|
392
|
+
}
|
393
|
+
|
394
|
+
/* Demangle a back referenced type from MANGLED and append it to DECL.
|
395
|
+
IS_FUNCTION is 1 if the back referenced type is expected to be a function.
|
396
|
+
Return the remaining string on success or NULL on failure. */
|
397
|
+
static const char *
|
398
|
+
dlang_type_backref (string *decl, const char *mangled, struct dlang_info *info,
|
399
|
+
int is_function)
|
400
|
+
{
|
401
|
+
/* A type back reference always points to a letter.
|
402
|
+
|
403
|
+
TypeBackRef:
|
404
|
+
Q NumberBackRef
|
405
|
+
^
|
406
|
+
*/
|
407
|
+
const char *backref;
|
408
|
+
|
409
|
+
/* If we appear to be moving backwards through the mangle string, then
|
410
|
+
bail as this may be a recursive back reference. */
|
411
|
+
if (mangled - info->s >= info->last_backref)
|
412
|
+
return NULL;
|
413
|
+
|
414
|
+
int save_refpos = info->last_backref;
|
415
|
+
info->last_backref = mangled - info->s;
|
416
|
+
|
417
|
+
/* Get position of the back reference. */
|
418
|
+
mangled = dlang_backref (mangled, &backref, info);
|
419
|
+
|
420
|
+
/* Must point to a type. */
|
421
|
+
if (is_function)
|
422
|
+
backref = dlang_function_type (decl, backref, info);
|
423
|
+
else
|
424
|
+
backref = dlang_type (decl, backref, info);
|
425
|
+
|
426
|
+
info->last_backref = save_refpos;
|
427
|
+
|
428
|
+
if (backref == NULL)
|
429
|
+
return NULL;
|
430
|
+
|
431
|
+
return mangled;
|
432
|
+
}
|
433
|
+
|
434
|
+
/* Extract the beginning of a symbol name from MANGLED and
|
435
|
+
return 1 on success or 0 on failure. */
|
436
|
+
static int
|
437
|
+
dlang_symbol_name_p (const char *mangled, struct dlang_info *info)
|
438
|
+
{
|
439
|
+
long ret;
|
440
|
+
const char *qref = mangled;
|
441
|
+
|
442
|
+
if (ISDIGIT (*mangled))
|
443
|
+
return 1;
|
444
|
+
|
445
|
+
if (mangled[0] == '_' && mangled[1] == '_'
|
446
|
+
&& (mangled[2] == 'T' || mangled[2] == 'U'))
|
447
|
+
return 1;
|
448
|
+
|
449
|
+
if (*mangled != 'Q')
|
450
|
+
return 0;
|
451
|
+
|
452
|
+
mangled = dlang_decode_backref (mangled + 1, &ret);
|
453
|
+
if (mangled == NULL || ret > qref - info->s)
|
454
|
+
return 0;
|
455
|
+
|
456
|
+
return ISDIGIT (qref[-ret]);
|
457
|
+
}
|
458
|
+
|
270
459
|
/* Demangle the calling convention from MANGLED and append it to DECL.
|
271
460
|
Return the remaining string on success or NULL on failure. */
|
272
461
|
static const char *
|
@@ -385,9 +574,11 @@ dlang_attributes (string *decl, const char *mangled)
|
|
385
574
|
case 'g':
|
386
575
|
case 'h':
|
387
576
|
case 'k':
|
577
|
+
case 'n':
|
388
578
|
/* inout parameter is represented as 'Ng'.
|
389
579
|
vector parameter is represented as 'Nh'.
|
390
|
-
return
|
580
|
+
return parameter is represented as 'Nk'.
|
581
|
+
typeof(*null) parameter is represented as 'Nn'.
|
391
582
|
If we see this, then we know we're really in the
|
392
583
|
parameter list. Rewind and break. */
|
393
584
|
mangled--;
|
@@ -404,6 +595,10 @@ dlang_attributes (string *decl, const char *mangled)
|
|
404
595
|
mangled++;
|
405
596
|
string_append (decl, "scope ");
|
406
597
|
continue;
|
598
|
+
case 'm': /* @live */
|
599
|
+
mangled++;
|
600
|
+
string_append (decl, "@live ");
|
601
|
+
continue;
|
407
602
|
|
408
603
|
default: /* unknown attribute */
|
409
604
|
return NULL;
|
@@ -414,13 +609,39 @@ dlang_attributes (string *decl, const char *mangled)
|
|
414
609
|
return mangled;
|
415
610
|
}
|
416
611
|
|
612
|
+
/* Demangle the function type from MANGLED without the return type.
|
613
|
+
The arguments are appended to ARGS, the calling convention is appended
|
614
|
+
to CALL and attributes are appended to ATTR. Any of these can be NULL
|
615
|
+
to throw the information away. Return the remaining string on success
|
616
|
+
or NULL on failure. */
|
617
|
+
static const char *
|
618
|
+
dlang_function_type_noreturn (string *args, string *call, string *attr,
|
619
|
+
const char *mangled, struct dlang_info *info)
|
620
|
+
{
|
621
|
+
string dump;
|
622
|
+
string_init (&dump);
|
623
|
+
|
624
|
+
/* Skip over calling convention and attributes. */
|
625
|
+
mangled = dlang_call_convention (call ? call : &dump, mangled);
|
626
|
+
mangled = dlang_attributes (attr ? attr : &dump, mangled);
|
627
|
+
|
628
|
+
if (args)
|
629
|
+
string_append (args, "(");
|
630
|
+
|
631
|
+
mangled = dlang_function_args (args ? args : &dump, mangled, info);
|
632
|
+
if (args)
|
633
|
+
string_append (args, ")");
|
634
|
+
|
635
|
+
string_delete (&dump);
|
636
|
+
return mangled;
|
637
|
+
}
|
638
|
+
|
417
639
|
/* Demangle the function type from MANGLED and append it to DECL.
|
418
640
|
Return the remaining string on success or NULL on failure. */
|
419
641
|
static const char *
|
420
|
-
dlang_function_type (string *decl, const char *mangled)
|
642
|
+
dlang_function_type (string *decl, const char *mangled, struct dlang_info *info)
|
421
643
|
{
|
422
644
|
string attr, args, type;
|
423
|
-
size_t szattr, szargs, sztype;
|
424
645
|
|
425
646
|
if (mangled == NULL || *mangled == '\0')
|
426
647
|
return NULL;
|
@@ -435,27 +656,16 @@ dlang_function_type (string *decl, const char *mangled)
|
|
435
656
|
string_init (&args);
|
436
657
|
string_init (&type);
|
437
658
|
|
438
|
-
|
439
|
-
mangled = dlang_call_convention (decl, mangled);
|
440
|
-
|
441
|
-
/* Function attributes. */
|
442
|
-
mangled = dlang_attributes (&attr, mangled);
|
443
|
-
szattr = string_length (&attr);
|
444
|
-
|
445
|
-
/* Function arguments. */
|
446
|
-
mangled = dlang_function_args (&args, mangled);
|
447
|
-
szargs = string_length (&args);
|
659
|
+
mangled = dlang_function_type_noreturn (&args, decl, &attr, mangled, info);
|
448
660
|
|
449
661
|
/* Function return type. */
|
450
|
-
mangled = dlang_type (&type, mangled);
|
451
|
-
sztype = string_length (&type);
|
662
|
+
mangled = dlang_type (&type, mangled, info);
|
452
663
|
|
453
664
|
/* Append to decl in order. */
|
454
|
-
string_appendn (decl, type.b,
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
string_appendn (decl, attr.b, szattr);
|
665
|
+
string_appendn (decl, type.b, string_length (&type));
|
666
|
+
string_appendn (decl, args.b, string_length (&args));
|
667
|
+
string_append (decl, " ");
|
668
|
+
string_appendn (decl, attr.b, string_length (&attr));
|
459
669
|
|
460
670
|
string_delete (&attr);
|
461
671
|
string_delete (&args);
|
@@ -466,7 +676,7 @@ dlang_function_type (string *decl, const char *mangled)
|
|
466
676
|
/* Demangle the argument list from MANGLED and append it to DECL.
|
467
677
|
Return the remaining string on success or NULL on failure. */
|
468
678
|
static const char *
|
469
|
-
dlang_function_args (string *decl, const char *mangled)
|
679
|
+
dlang_function_args (string *decl, const char *mangled, struct dlang_info *info)
|
470
680
|
{
|
471
681
|
size_t n = 0;
|
472
682
|
|
@@ -506,6 +716,15 @@ dlang_function_args (string *decl, const char *mangled)
|
|
506
716
|
|
507
717
|
switch (*mangled)
|
508
718
|
{
|
719
|
+
case 'I': /* in(T) */
|
720
|
+
mangled++;
|
721
|
+
string_append (decl, "in ");
|
722
|
+
if (*mangled == 'K') /* in ref(T) */
|
723
|
+
{
|
724
|
+
mangled++;
|
725
|
+
string_append (decl, "ref ");
|
726
|
+
}
|
727
|
+
break;
|
509
728
|
case 'J': /* out(T) */
|
510
729
|
mangled++;
|
511
730
|
string_append (decl, "out ");
|
@@ -519,7 +738,7 @@ dlang_function_args (string *decl, const char *mangled)
|
|
519
738
|
string_append (decl, "lazy ");
|
520
739
|
break;
|
521
740
|
}
|
522
|
-
mangled = dlang_type (decl, mangled);
|
741
|
+
mangled = dlang_type (decl, mangled, info);
|
523
742
|
}
|
524
743
|
|
525
744
|
return mangled;
|
@@ -528,7 +747,7 @@ dlang_function_args (string *decl, const char *mangled)
|
|
528
747
|
/* Demangle the type from MANGLED and append it to DECL.
|
529
748
|
Return the remaining string on success or NULL on failure. */
|
530
749
|
static const char *
|
531
|
-
dlang_type (string *decl, const char *mangled)
|
750
|
+
dlang_type (string *decl, const char *mangled, struct dlang_info *info)
|
532
751
|
{
|
533
752
|
if (mangled == NULL || *mangled == '\0')
|
534
753
|
return NULL;
|
@@ -538,19 +757,19 @@ dlang_type (string *decl, const char *mangled)
|
|
538
757
|
case 'O': /* shared(T) */
|
539
758
|
mangled++;
|
540
759
|
string_append (decl, "shared(");
|
541
|
-
mangled = dlang_type (decl, mangled);
|
760
|
+
mangled = dlang_type (decl, mangled, info);
|
542
761
|
string_append (decl, ")");
|
543
762
|
return mangled;
|
544
763
|
case 'x': /* const(T) */
|
545
764
|
mangled++;
|
546
765
|
string_append (decl, "const(");
|
547
|
-
mangled = dlang_type (decl, mangled);
|
766
|
+
mangled = dlang_type (decl, mangled, info);
|
548
767
|
string_append (decl, ")");
|
549
768
|
return mangled;
|
550
769
|
case 'y': /* immutable(T) */
|
551
770
|
mangled++;
|
552
771
|
string_append (decl, "immutable(");
|
553
|
-
mangled = dlang_type (decl, mangled);
|
772
|
+
mangled = dlang_type (decl, mangled, info);
|
554
773
|
string_append (decl, ")");
|
555
774
|
return mangled;
|
556
775
|
case 'N':
|
@@ -559,7 +778,7 @@ dlang_type (string *decl, const char *mangled)
|
|
559
778
|
{
|
560
779
|
mangled++;
|
561
780
|
string_append (decl, "inout(");
|
562
|
-
mangled = dlang_type (decl, mangled);
|
781
|
+
mangled = dlang_type (decl, mangled, info);
|
563
782
|
string_append (decl, ")");
|
564
783
|
return mangled;
|
565
784
|
}
|
@@ -567,15 +786,21 @@ dlang_type (string *decl, const char *mangled)
|
|
567
786
|
{
|
568
787
|
mangled++;
|
569
788
|
string_append (decl, "__vector(");
|
570
|
-
mangled = dlang_type (decl, mangled);
|
789
|
+
mangled = dlang_type (decl, mangled, info);
|
571
790
|
string_append (decl, ")");
|
572
791
|
return mangled;
|
573
792
|
}
|
793
|
+
else if (*mangled == 'n') /* typeof(*null) */
|
794
|
+
{
|
795
|
+
mangled++;
|
796
|
+
string_append (decl, "typeof(*null)");
|
797
|
+
return mangled;
|
798
|
+
}
|
574
799
|
else
|
575
800
|
return NULL;
|
576
801
|
case 'A': /* dynamic array (T[]) */
|
577
802
|
mangled++;
|
578
|
-
mangled = dlang_type (decl, mangled);
|
803
|
+
mangled = dlang_type (decl, mangled, info);
|
579
804
|
string_append (decl, "[]");
|
580
805
|
return mangled;
|
581
806
|
case 'G': /* static array (T[N]) */
|
@@ -590,7 +815,7 @@ dlang_type (string *decl, const char *mangled)
|
|
590
815
|
num++;
|
591
816
|
mangled++;
|
592
817
|
}
|
593
|
-
mangled = dlang_type (decl, mangled);
|
818
|
+
mangled = dlang_type (decl, mangled, info);
|
594
819
|
string_append (decl, "[");
|
595
820
|
string_appendn (decl, numptr, num);
|
596
821
|
string_append (decl, "]");
|
@@ -603,10 +828,10 @@ dlang_type (string *decl, const char *mangled)
|
|
603
828
|
mangled++;
|
604
829
|
|
605
830
|
string_init (&type);
|
606
|
-
mangled = dlang_type (&type, mangled);
|
831
|
+
mangled = dlang_type (&type, mangled, info);
|
607
832
|
sztype = string_length (&type);
|
608
833
|
|
609
|
-
mangled = dlang_type (decl, mangled);
|
834
|
+
mangled = dlang_type (decl, mangled, info);
|
610
835
|
string_append (decl, "[");
|
611
836
|
string_appendn (decl, type.b, sztype);
|
612
837
|
string_append (decl, "]");
|
@@ -618,7 +843,7 @@ dlang_type (string *decl, const char *mangled)
|
|
618
843
|
mangled++;
|
619
844
|
if (!dlang_call_convention_p (mangled))
|
620
845
|
{
|
621
|
-
mangled = dlang_type (decl, mangled);
|
846
|
+
mangled = dlang_type (decl, mangled, info);
|
622
847
|
string_append (decl, "*");
|
623
848
|
return mangled;
|
624
849
|
}
|
@@ -630,16 +855,15 @@ dlang_type (string *decl, const char *mangled)
|
|
630
855
|
case 'R': /* function T (C++) */
|
631
856
|
case 'Y': /* function T (Objective-C) */
|
632
857
|
/* Function pointer types don't include the trailing asterisk. */
|
633
|
-
mangled = dlang_function_type (decl, mangled);
|
858
|
+
mangled = dlang_function_type (decl, mangled, info);
|
634
859
|
string_append (decl, "function");
|
635
860
|
return mangled;
|
636
|
-
case 'I': /* ident T */
|
637
861
|
case 'C': /* class T */
|
638
862
|
case 'S': /* struct T */
|
639
863
|
case 'E': /* enum T */
|
640
864
|
case 'T': /* typedef T */
|
641
865
|
mangled++;
|
642
|
-
return dlang_parse_qualified (decl, mangled,
|
866
|
+
return dlang_parse_qualified (decl, mangled, info, 0);
|
643
867
|
case 'D': /* delegate T */
|
644
868
|
{
|
645
869
|
string mods;
|
@@ -650,7 +874,12 @@ dlang_type (string *decl, const char *mangled)
|
|
650
874
|
mangled = dlang_type_modifiers (&mods, mangled);
|
651
875
|
szmods = string_length (&mods);
|
652
876
|
|
653
|
-
|
877
|
+
/* Back referenced function type. */
|
878
|
+
if (mangled && *mangled == 'Q')
|
879
|
+
mangled = dlang_type_backref (decl, mangled, info, 1);
|
880
|
+
else
|
881
|
+
mangled = dlang_function_type (decl, mangled, info);
|
882
|
+
|
654
883
|
string_append (decl, "delegate");
|
655
884
|
string_appendn (decl, mods.b, szmods);
|
656
885
|
|
@@ -659,12 +888,12 @@ dlang_type (string *decl, const char *mangled)
|
|
659
888
|
}
|
660
889
|
case 'B': /* tuple T */
|
661
890
|
mangled++;
|
662
|
-
return dlang_parse_tuple (decl, mangled);
|
891
|
+
return dlang_parse_tuple (decl, mangled, info);
|
663
892
|
|
664
893
|
/* Basic types */
|
665
894
|
case 'n':
|
666
895
|
mangled++;
|
667
|
-
string_append (decl, "
|
896
|
+
string_append (decl, "typeof(null)");
|
668
897
|
return mangled;
|
669
898
|
case 'v':
|
670
899
|
mangled++;
|
@@ -773,6 +1002,10 @@ dlang_type (string *decl, const char *mangled)
|
|
773
1002
|
}
|
774
1003
|
return NULL;
|
775
1004
|
|
1005
|
+
/* Back referenced type. */
|
1006
|
+
case 'Q':
|
1007
|
+
return dlang_type_backref (decl, mangled, info, 0);
|
1008
|
+
|
776
1009
|
default: /* unhandled */
|
777
1010
|
return NULL;
|
778
1011
|
}
|
@@ -781,152 +1014,146 @@ dlang_type (string *decl, const char *mangled)
|
|
781
1014
|
/* Extract the identifier from MANGLED and append it to DECL.
|
782
1015
|
Return the remaining string on success or NULL on failure. */
|
783
1016
|
static const char *
|
784
|
-
dlang_identifier (string *decl, const char *mangled,
|
785
|
-
enum dlang_symbol_kinds kind)
|
1017
|
+
dlang_identifier (string *decl, const char *mangled, struct dlang_info *info)
|
786
1018
|
{
|
787
|
-
long len;
|
1019
|
+
unsigned long len;
|
1020
|
+
|
1021
|
+
if (mangled == NULL || *mangled == '\0')
|
1022
|
+
return NULL;
|
1023
|
+
|
1024
|
+
if (*mangled == 'Q')
|
1025
|
+
return dlang_symbol_backref (decl, mangled, info);
|
1026
|
+
|
1027
|
+
/* May be a template instance without a length prefix. */
|
1028
|
+
if (mangled[0] == '_' && mangled[1] == '_'
|
1029
|
+
&& (mangled[2] == 'T' || mangled[2] == 'U'))
|
1030
|
+
return dlang_parse_template (decl, mangled, info, TEMPLATE_LENGTH_UNKNOWN);
|
1031
|
+
|
788
1032
|
const char *endptr = dlang_number (mangled, &len);
|
789
1033
|
|
790
1034
|
if (endptr == NULL || len == 0)
|
791
1035
|
return NULL;
|
792
1036
|
|
793
|
-
|
794
|
-
|
795
|
-
digits of the two numbers are adjacent. */
|
796
|
-
if (kind == dlang_template_param)
|
797
|
-
{
|
798
|
-
long psize = len;
|
799
|
-
const char *pend;
|
800
|
-
int saved = string_length (decl);
|
801
|
-
|
802
|
-
/* Work backwards until a match is found. */
|
803
|
-
for (pend = endptr; endptr != NULL; pend--)
|
804
|
-
{
|
805
|
-
mangled = pend;
|
1037
|
+
if (strlen (endptr) < len)
|
1038
|
+
return NULL;
|
806
1039
|
|
807
|
-
|
808
|
-
try parsing the entire symbol. */
|
809
|
-
if (psize == 0)
|
810
|
-
{
|
811
|
-
psize = len;
|
812
|
-
pend = endptr;
|
813
|
-
endptr = NULL;
|
814
|
-
}
|
1040
|
+
mangled = endptr;
|
815
1041
|
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
dlang_template_ident);
|
821
|
-
else if (strncmp (mangled, "_D", 2) == 0)
|
822
|
-
mangled = dlang_parse_mangle (decl, mangled, dlang_function);
|
1042
|
+
/* May be a template instance with a length prefix. */
|
1043
|
+
if (len >= 5 && mangled[0] == '_' && mangled[1] == '_'
|
1044
|
+
&& (mangled[2] == 'T' || mangled[2] == 'U'))
|
1045
|
+
return dlang_parse_template (decl, mangled, info, len);
|
823
1046
|
|
824
|
-
|
825
|
-
|
826
|
-
|
1047
|
+
/* There can be multiple different declarations in the same function that have
|
1048
|
+
the same mangled name. To make the mangled names unique, a fake parent in
|
1049
|
+
the form `__Sddd' is added to the symbol. */
|
1050
|
+
if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S')
|
1051
|
+
{
|
1052
|
+
const char *numptr = mangled + 3;
|
1053
|
+
while (numptr < (mangled + len) && ISDIGIT (*numptr))
|
1054
|
+
numptr++;
|
827
1055
|
|
828
|
-
|
829
|
-
|
1056
|
+
if (mangled + len == numptr)
|
1057
|
+
{
|
1058
|
+
/* Skip over the fake parent. */
|
1059
|
+
mangled += len;
|
1060
|
+
return dlang_identifier (decl, mangled, info);
|
830
1061
|
}
|
831
1062
|
|
832
|
-
/*
|
833
|
-
return NULL;
|
1063
|
+
/* else demangle it as a plain identifier. */
|
834
1064
|
}
|
835
|
-
else
|
836
|
-
{
|
837
|
-
if (strlen (endptr) < (size_t) len)
|
838
|
-
return NULL;
|
839
|
-
|
840
|
-
mangled = endptr;
|
841
1065
|
|
842
|
-
|
843
|
-
|
844
|
-
&& (mangled[2] == 'T' || mangled[2] == 'U'))
|
845
|
-
return dlang_parse_template (decl, mangled, len);
|
1066
|
+
return dlang_lname (decl, mangled, len);
|
1067
|
+
}
|
846
1068
|
|
847
|
-
|
1069
|
+
/* Extract the plain identifier from MANGLED and prepend/append it to DECL
|
1070
|
+
with special treatment for some magic compiler generted symbols.
|
1071
|
+
Return the remaining string on success or NULL on failure. */
|
1072
|
+
static const char *
|
1073
|
+
dlang_lname (string *decl, const char *mangled, unsigned long len)
|
1074
|
+
{
|
1075
|
+
switch (len)
|
1076
|
+
{
|
1077
|
+
case 6:
|
1078
|
+
if (strncmp (mangled, "__ctor", len) == 0)
|
848
1079
|
{
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
return mangled;
|
879
|
-
}
|
880
|
-
break;
|
881
|
-
|
882
|
-
case 7:
|
883
|
-
if (strncmp (mangled, "__ClassZ", len+1) == 0)
|
884
|
-
{
|
885
|
-
/* The classinfo symbol for a given class. */
|
886
|
-
string_prepend (decl, "ClassInfo for ");
|
887
|
-
string_setlength (decl, string_length (decl) - 1);
|
888
|
-
mangled += len;
|
889
|
-
return mangled;
|
890
|
-
}
|
891
|
-
break;
|
1080
|
+
/* Constructor symbol for a class/struct. */
|
1081
|
+
string_append (decl, "this");
|
1082
|
+
mangled += len;
|
1083
|
+
return mangled;
|
1084
|
+
}
|
1085
|
+
else if (strncmp (mangled, "__dtor", len) == 0)
|
1086
|
+
{
|
1087
|
+
/* Destructor symbol for a class/struct. */
|
1088
|
+
string_append (decl, "~this");
|
1089
|
+
mangled += len;
|
1090
|
+
return mangled;
|
1091
|
+
}
|
1092
|
+
else if (strncmp (mangled, "__initZ", len + 1) == 0)
|
1093
|
+
{
|
1094
|
+
/* The static initialiser for a given symbol. */
|
1095
|
+
string_prepend (decl, "initializer for ");
|
1096
|
+
string_setlength (decl, string_length (decl) - 1);
|
1097
|
+
mangled += len;
|
1098
|
+
return mangled;
|
1099
|
+
}
|
1100
|
+
else if (strncmp (mangled, "__vtblZ", len + 1) == 0)
|
1101
|
+
{
|
1102
|
+
/* The vtable symbol for a given class. */
|
1103
|
+
string_prepend (decl, "vtable for ");
|
1104
|
+
string_setlength (decl, string_length (decl) - 1);
|
1105
|
+
mangled += len;
|
1106
|
+
return mangled;
|
1107
|
+
}
|
1108
|
+
break;
|
892
1109
|
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
1110
|
+
case 7:
|
1111
|
+
if (strncmp (mangled, "__ClassZ", len + 1) == 0)
|
1112
|
+
{
|
1113
|
+
/* The classinfo symbol for a given class. */
|
1114
|
+
string_prepend (decl, "ClassInfo for ");
|
1115
|
+
string_setlength (decl, string_length (decl) - 1);
|
1116
|
+
mangled += len;
|
1117
|
+
return mangled;
|
1118
|
+
}
|
1119
|
+
break;
|
902
1120
|
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
break;
|
1121
|
+
case 10:
|
1122
|
+
if (strncmp (mangled, "__postblitMFZ", len + 3) == 0)
|
1123
|
+
{
|
1124
|
+
/* Postblit symbol for a struct. */
|
1125
|
+
string_append (decl, "this(this)");
|
1126
|
+
mangled += len + 3;
|
1127
|
+
return mangled;
|
1128
|
+
}
|
1129
|
+
break;
|
913
1130
|
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
}
|
923
|
-
break;
|
1131
|
+
case 11:
|
1132
|
+
if (strncmp (mangled, "__InterfaceZ", len + 1) == 0)
|
1133
|
+
{
|
1134
|
+
/* The interface symbol for a given class. */
|
1135
|
+
string_prepend (decl, "Interface for ");
|
1136
|
+
string_setlength (decl, string_length (decl) - 1);
|
1137
|
+
mangled += len;
|
1138
|
+
return mangled;
|
924
1139
|
}
|
1140
|
+
break;
|
925
1141
|
|
926
|
-
|
927
|
-
mangled
|
1142
|
+
case 12:
|
1143
|
+
if (strncmp (mangled, "__ModuleInfoZ", len + 1) == 0)
|
1144
|
+
{
|
1145
|
+
/* The ModuleInfo symbol for a given module. */
|
1146
|
+
string_prepend (decl, "ModuleInfo for ");
|
1147
|
+
string_setlength (decl, string_length (decl) - 1);
|
1148
|
+
mangled += len;
|
1149
|
+
return mangled;
|
1150
|
+
}
|
1151
|
+
break;
|
928
1152
|
}
|
929
1153
|
|
1154
|
+
string_appendn (decl, mangled, len);
|
1155
|
+
mangled += len;
|
1156
|
+
|
930
1157
|
return mangled;
|
931
1158
|
}
|
932
1159
|
|
@@ -939,10 +1166,10 @@ dlang_parse_integer (string *decl, const char *mangled, char type)
|
|
939
1166
|
if (type == 'a' || type == 'u' || type == 'w')
|
940
1167
|
{
|
941
1168
|
/* Parse character value. */
|
942
|
-
char value[
|
943
|
-
int pos =
|
1169
|
+
char value[20];
|
1170
|
+
int pos = sizeof(value);
|
944
1171
|
int width = 0;
|
945
|
-
long val;
|
1172
|
+
unsigned long val;
|
946
1173
|
|
947
1174
|
mangled = dlang_number (mangled, &val);
|
948
1175
|
if (mangled == NULL)
|
@@ -991,14 +1218,14 @@ dlang_parse_integer (string *decl, const char *mangled, char type)
|
|
991
1218
|
for (; width > 0; width--)
|
992
1219
|
value[--pos] = '0';
|
993
1220
|
|
994
|
-
string_appendn (decl, &(value[pos]),
|
1221
|
+
string_appendn (decl, &(value[pos]), sizeof(value) - pos);
|
995
1222
|
}
|
996
1223
|
string_append (decl, "'");
|
997
1224
|
}
|
998
1225
|
else if (type == 'b')
|
999
1226
|
{
|
1000
1227
|
/* Parse boolean value. */
|
1001
|
-
long val;
|
1228
|
+
unsigned long val;
|
1002
1229
|
|
1003
1230
|
mangled = dlang_number (mangled, &val);
|
1004
1231
|
if (mangled == NULL)
|
@@ -1117,7 +1344,7 @@ static const char *
|
|
1117
1344
|
dlang_parse_string (string *decl, const char *mangled)
|
1118
1345
|
{
|
1119
1346
|
char type = *mangled;
|
1120
|
-
long len;
|
1347
|
+
unsigned long len;
|
1121
1348
|
|
1122
1349
|
mangled++;
|
1123
1350
|
mangled = dlang_number (mangled, &len);
|
@@ -1179,9 +1406,10 @@ dlang_parse_string (string *decl, const char *mangled)
|
|
1179
1406
|
/* Extract the static array value from MANGLED and append it to DECL.
|
1180
1407
|
Return the remaining string on success or NULL on failure. */
|
1181
1408
|
static const char *
|
1182
|
-
dlang_parse_arrayliteral (string *decl, const char *mangled
|
1409
|
+
dlang_parse_arrayliteral (string *decl, const char *mangled,
|
1410
|
+
struct dlang_info *info)
|
1183
1411
|
{
|
1184
|
-
long elements;
|
1412
|
+
unsigned long elements;
|
1185
1413
|
|
1186
1414
|
mangled = dlang_number (mangled, &elements);
|
1187
1415
|
if (mangled == NULL)
|
@@ -1190,7 +1418,10 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
|
|
1190
1418
|
string_append (decl, "[");
|
1191
1419
|
while (elements--)
|
1192
1420
|
{
|
1193
|
-
mangled = dlang_value (decl, mangled, NULL, '\0');
|
1421
|
+
mangled = dlang_value (decl, mangled, NULL, '\0', info);
|
1422
|
+
if (mangled == NULL)
|
1423
|
+
return NULL;
|
1424
|
+
|
1194
1425
|
if (elements != 0)
|
1195
1426
|
string_append (decl, ", ");
|
1196
1427
|
}
|
@@ -1202,9 +1433,10 @@ dlang_parse_arrayliteral (string *decl, const char *mangled)
|
|
1202
1433
|
/* Extract the associative array value from MANGLED and append it to DECL.
|
1203
1434
|
Return the remaining string on success or NULL on failure. */
|
1204
1435
|
static const char *
|
1205
|
-
dlang_parse_assocarray (string *decl, const char *mangled
|
1436
|
+
dlang_parse_assocarray (string *decl, const char *mangled,
|
1437
|
+
struct dlang_info *info)
|
1206
1438
|
{
|
1207
|
-
long elements;
|
1439
|
+
unsigned long elements;
|
1208
1440
|
|
1209
1441
|
mangled = dlang_number (mangled, &elements);
|
1210
1442
|
if (mangled == NULL)
|
@@ -1213,9 +1445,14 @@ dlang_parse_assocarray (string *decl, const char *mangled)
|
|
1213
1445
|
string_append (decl, "[");
|
1214
1446
|
while (elements--)
|
1215
1447
|
{
|
1216
|
-
mangled = dlang_value (decl, mangled, NULL, '\0');
|
1448
|
+
mangled = dlang_value (decl, mangled, NULL, '\0', info);
|
1449
|
+
if (mangled == NULL)
|
1450
|
+
return NULL;
|
1451
|
+
|
1217
1452
|
string_append (decl, ":");
|
1218
|
-
mangled = dlang_value (decl, mangled, NULL, '\0');
|
1453
|
+
mangled = dlang_value (decl, mangled, NULL, '\0', info);
|
1454
|
+
if (mangled == NULL)
|
1455
|
+
return NULL;
|
1219
1456
|
|
1220
1457
|
if (elements != 0)
|
1221
1458
|
string_append (decl, ", ");
|
@@ -1228,9 +1465,10 @@ dlang_parse_assocarray (string *decl, const char *mangled)
|
|
1228
1465
|
/* Extract the struct literal value for NAME from MANGLED and append it to DECL.
|
1229
1466
|
Return the remaining string on success or NULL on failure. */
|
1230
1467
|
static const char *
|
1231
|
-
dlang_parse_structlit (string *decl, const char *mangled, const char *name
|
1468
|
+
dlang_parse_structlit (string *decl, const char *mangled, const char *name,
|
1469
|
+
struct dlang_info *info)
|
1232
1470
|
{
|
1233
|
-
long args;
|
1471
|
+
unsigned long args;
|
1234
1472
|
|
1235
1473
|
mangled = dlang_number (mangled, &args);
|
1236
1474
|
if (mangled == NULL)
|
@@ -1242,7 +1480,10 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
|
|
1242
1480
|
string_append (decl, "(");
|
1243
1481
|
while (args--)
|
1244
1482
|
{
|
1245
|
-
mangled = dlang_value (decl, mangled, NULL, '\0');
|
1483
|
+
mangled = dlang_value (decl, mangled, NULL, '\0', info);
|
1484
|
+
if (mangled == NULL)
|
1485
|
+
return NULL;
|
1486
|
+
|
1246
1487
|
if (args != 0)
|
1247
1488
|
string_append (decl, ", ");
|
1248
1489
|
}
|
@@ -1254,7 +1495,8 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name)
|
|
1254
1495
|
/* Extract the value from MANGLED and append it to DECL.
|
1255
1496
|
Return the remaining string on success or NULL on failure. */
|
1256
1497
|
static const char *
|
1257
|
-
dlang_value (string *decl, const char *mangled, const char *name, char type
|
1498
|
+
dlang_value (string *decl, const char *mangled, const char *name, char type,
|
1499
|
+
struct dlang_info *info)
|
1258
1500
|
{
|
1259
1501
|
if (mangled == NULL || *mangled == '\0')
|
1260
1502
|
return NULL;
|
@@ -1315,15 +1557,24 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
|
|
1315
1557
|
case 'A':
|
1316
1558
|
mangled++;
|
1317
1559
|
if (type == 'H')
|
1318
|
-
mangled = dlang_parse_assocarray (decl, mangled);
|
1560
|
+
mangled = dlang_parse_assocarray (decl, mangled, info);
|
1319
1561
|
else
|
1320
|
-
mangled = dlang_parse_arrayliteral (decl, mangled);
|
1562
|
+
mangled = dlang_parse_arrayliteral (decl, mangled, info);
|
1321
1563
|
break;
|
1322
1564
|
|
1323
1565
|
/* Struct values. */
|
1324
1566
|
case 'S':
|
1325
1567
|
mangled++;
|
1326
|
-
mangled = dlang_parse_structlit (decl, mangled, name);
|
1568
|
+
mangled = dlang_parse_structlit (decl, mangled, name, info);
|
1569
|
+
break;
|
1570
|
+
|
1571
|
+
/* Function literal symbol. */
|
1572
|
+
case 'f':
|
1573
|
+
mangled++;
|
1574
|
+
if (strncmp (mangled, "_D", 2) != 0
|
1575
|
+
|| !dlang_symbol_name_p (mangled + 2, info))
|
1576
|
+
return NULL;
|
1577
|
+
mangled = dlang_parse_mangle (decl, mangled, info);
|
1327
1578
|
break;
|
1328
1579
|
|
1329
1580
|
default:
|
@@ -1336,22 +1587,22 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
|
|
1336
1587
|
/* Extract and demangle the symbol in MANGLED and append it to DECL.
|
1337
1588
|
Returns the remaining signature on success or NULL on failure. */
|
1338
1589
|
static const char *
|
1339
|
-
dlang_parse_mangle (string *decl, const char *mangled,
|
1340
|
-
enum dlang_symbol_kinds kind)
|
1590
|
+
dlang_parse_mangle (string *decl, const char *mangled, struct dlang_info *info)
|
1341
1591
|
{
|
1342
1592
|
/* A D mangled symbol is comprised of both scope and type information.
|
1343
1593
|
|
1344
1594
|
MangleName:
|
1345
1595
|
_D QualifiedName Type
|
1346
|
-
_D QualifiedName M Type
|
1347
1596
|
_D QualifiedName Z
|
1348
1597
|
^
|
1349
1598
|
The caller should have guaranteed that the start pointer is at the
|
1350
1599
|
above location.
|
1600
|
+
Note that type is never a function type, but only the return type of
|
1601
|
+
a function or the type of a variable.
|
1351
1602
|
*/
|
1352
1603
|
mangled += 2;
|
1353
1604
|
|
1354
|
-
mangled = dlang_parse_qualified (decl, mangled,
|
1605
|
+
mangled = dlang_parse_qualified (decl, mangled, info, 1);
|
1355
1606
|
|
1356
1607
|
if (mangled != NULL)
|
1357
1608
|
{
|
@@ -1360,123 +1611,97 @@ dlang_parse_mangle (string *decl, const char *mangled,
|
|
1360
1611
|
mangled++;
|
1361
1612
|
else
|
1362
1613
|
{
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
/* Skip over 'this' parameter. */
|
1367
|
-
if (*mangled == 'M')
|
1368
|
-
mangled++;
|
1369
|
-
|
1370
|
-
/* Save the type modifiers for appending at the end if needed. */
|
1371
|
-
string_init (&mods);
|
1372
|
-
mangled = dlang_type_modifiers (&mods, mangled);
|
1373
|
-
|
1374
|
-
if (mangled && dlang_call_convention_p (mangled))
|
1375
|
-
{
|
1376
|
-
/* Skip over calling convention and attributes. */
|
1377
|
-
saved = string_length (decl);
|
1378
|
-
mangled = dlang_call_convention (decl, mangled);
|
1379
|
-
mangled = dlang_attributes (decl, mangled);
|
1380
|
-
string_setlength (decl, saved);
|
1381
|
-
|
1382
|
-
string_append (decl, "(");
|
1383
|
-
mangled = dlang_function_args (decl, mangled);
|
1384
|
-
string_append (decl, ")");
|
1385
|
-
|
1386
|
-
/* Add any const/immutable/shared modifier. */
|
1387
|
-
string_appendn (decl, mods.b, string_length (&mods));
|
1388
|
-
}
|
1614
|
+
/* Discard the declaration or return type. */
|
1615
|
+
string type;
|
1389
1616
|
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
string_setlength (decl, saved);
|
1394
|
-
|
1395
|
-
string_delete (&mods);
|
1617
|
+
string_init (&type);
|
1618
|
+
mangled = dlang_type (&type, mangled, info);
|
1619
|
+
string_delete (&type);
|
1396
1620
|
}
|
1397
1621
|
}
|
1398
1622
|
|
1399
|
-
/* Check that the entire symbol was successfully demangled. */
|
1400
|
-
if (kind == dlang_top_level)
|
1401
|
-
{
|
1402
|
-
if (mangled == NULL || *mangled != '\0')
|
1403
|
-
return NULL;
|
1404
|
-
}
|
1405
|
-
|
1406
1623
|
return mangled;
|
1407
1624
|
}
|
1408
1625
|
|
1409
1626
|
/* Extract and demangle the qualified symbol in MANGLED and append it to DECL.
|
1627
|
+
SUFFIX_MODIFIERS is 1 if we are printing modifiers on this after the symbol.
|
1410
1628
|
Returns the remaining signature on success or NULL on failure. */
|
1411
1629
|
static const char *
|
1412
1630
|
dlang_parse_qualified (string *decl, const char *mangled,
|
1413
|
-
|
1631
|
+
struct dlang_info *info, int suffix_modifiers)
|
1414
1632
|
{
|
1415
1633
|
/* Qualified names are identifiers separated by their encoded length.
|
1416
1634
|
Nested functions also encode their argument types without specifying
|
1417
1635
|
what they return.
|
1418
1636
|
|
1419
1637
|
QualifiedName:
|
1420
|
-
|
1421
|
-
|
1422
|
-
SymbolName TypeFunctionNoReturn QualifiedName
|
1423
|
-
SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName
|
1638
|
+
SymbolFunctionName
|
1639
|
+
SymbolFunctionName QualifiedName
|
1424
1640
|
^
|
1641
|
+
|
1642
|
+
SymbolFunctionName:
|
1643
|
+
SymbolName
|
1644
|
+
SymbolName TypeFunctionNoReturn
|
1645
|
+
SymbolName M TypeFunctionNoReturn
|
1646
|
+
SymbolName M TypeModifiers TypeFunctionNoReturn
|
1647
|
+
|
1425
1648
|
The start pointer should be at the above location.
|
1426
1649
|
*/
|
1427
1650
|
size_t n = 0;
|
1428
1651
|
do
|
1429
1652
|
{
|
1653
|
+
/* Skip over anonymous symbols. */
|
1654
|
+
if (*mangled == '0')
|
1655
|
+
{
|
1656
|
+
do
|
1657
|
+
mangled++;
|
1658
|
+
while (*mangled == '0');
|
1659
|
+
|
1660
|
+
continue;
|
1661
|
+
}
|
1662
|
+
|
1430
1663
|
if (n++)
|
1431
1664
|
string_append (decl, ".");
|
1432
1665
|
|
1433
|
-
|
1434
|
-
while (*mangled == '0')
|
1435
|
-
mangled++;
|
1436
|
-
|
1437
|
-
mangled = dlang_identifier (decl, mangled, kind);
|
1666
|
+
mangled = dlang_identifier (decl, mangled, info);
|
1438
1667
|
|
1439
1668
|
/* Consume the encoded arguments. However if this is not followed by the
|
1440
|
-
next encoded length, then this is not a continuation of
|
1441
|
-
name, in which case we backtrack and return the current
|
1442
|
-
position of the mangled decl. */
|
1669
|
+
next encoded length or mangle type, then this is not a continuation of
|
1670
|
+
a qualified name, in which case we backtrack and return the current
|
1671
|
+
unconsumed position of the mangled decl. */
|
1443
1672
|
if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled)))
|
1444
1673
|
{
|
1674
|
+
string mods;
|
1445
1675
|
const char *start = mangled;
|
1446
1676
|
int saved = string_length (decl);
|
1447
1677
|
|
1678
|
+
/* Save the type modifiers for appending at the end if needed. */
|
1679
|
+
string_init (&mods);
|
1680
|
+
|
1448
1681
|
/* Skip over 'this' parameter and type modifiers. */
|
1449
1682
|
if (*mangled == 'M')
|
1450
1683
|
{
|
1451
1684
|
mangled++;
|
1452
|
-
mangled = dlang_type_modifiers (
|
1685
|
+
mangled = dlang_type_modifiers (&mods, mangled);
|
1453
1686
|
string_setlength (decl, saved);
|
1454
1687
|
}
|
1455
1688
|
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
The calling convention and function attributes are not included
|
1462
|
-
in the demangled string. */
|
1463
|
-
mangled = dlang_call_convention (decl, mangled);
|
1464
|
-
mangled = dlang_attributes (decl, mangled);
|
1465
|
-
string_setlength (decl, saved);
|
1689
|
+
mangled = dlang_function_type_noreturn (decl, NULL, NULL,
|
1690
|
+
mangled, info);
|
1691
|
+
if (suffix_modifiers)
|
1692
|
+
string_appendn (decl, mods.b, string_length (&mods));
|
1466
1693
|
|
1467
|
-
|
1468
|
-
mangled = dlang_function_args (decl, mangled);
|
1469
|
-
string_append (decl, ")");
|
1470
|
-
|
1471
|
-
if (mangled == NULL || !ISDIGIT (*mangled))
|
1694
|
+
if (mangled == NULL || *mangled == '\0')
|
1472
1695
|
{
|
1473
1696
|
/* Did not match the rule we were looking for. */
|
1474
1697
|
mangled = start;
|
1475
1698
|
string_setlength (decl, saved);
|
1476
1699
|
}
|
1700
|
+
|
1701
|
+
string_delete (&mods);
|
1477
1702
|
}
|
1478
1703
|
}
|
1479
|
-
while (mangled &&
|
1704
|
+
while (mangled && dlang_symbol_name_p (mangled, info));
|
1480
1705
|
|
1481
1706
|
return mangled;
|
1482
1707
|
}
|
@@ -1484,9 +1709,9 @@ dlang_parse_qualified (string *decl, const char *mangled,
|
|
1484
1709
|
/* Demangle the tuple from MANGLED and append it to DECL.
|
1485
1710
|
Return the remaining string on success or NULL on failure. */
|
1486
1711
|
static const char *
|
1487
|
-
dlang_parse_tuple (string *decl, const char *mangled)
|
1712
|
+
dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info)
|
1488
1713
|
{
|
1489
|
-
long elements;
|
1714
|
+
unsigned long elements;
|
1490
1715
|
|
1491
1716
|
mangled = dlang_number (mangled, &elements);
|
1492
1717
|
if (mangled == NULL)
|
@@ -1496,7 +1721,10 @@ dlang_parse_tuple (string *decl, const char *mangled)
|
|
1496
1721
|
|
1497
1722
|
while (elements--)
|
1498
1723
|
{
|
1499
|
-
mangled = dlang_type (decl, mangled);
|
1724
|
+
mangled = dlang_type (decl, mangled, info);
|
1725
|
+
if (mangled == NULL)
|
1726
|
+
return NULL;
|
1727
|
+
|
1500
1728
|
if (elements != 0)
|
1501
1729
|
string_append (decl, ", ");
|
1502
1730
|
}
|
@@ -1505,10 +1733,71 @@ dlang_parse_tuple (string *decl, const char *mangled)
|
|
1505
1733
|
return mangled;
|
1506
1734
|
}
|
1507
1735
|
|
1736
|
+
/* Demangle the template symbol parameter from MANGLED and append it to DECL.
|
1737
|
+
Return the remaining string on success or NULL on failure. */
|
1738
|
+
static const char *
|
1739
|
+
dlang_template_symbol_param (string *decl, const char *mangled,
|
1740
|
+
struct dlang_info *info)
|
1741
|
+
{
|
1742
|
+
if (strncmp (mangled, "_D", 2) == 0
|
1743
|
+
&& dlang_symbol_name_p (mangled + 2, info))
|
1744
|
+
return dlang_parse_mangle (decl, mangled, info);
|
1745
|
+
|
1746
|
+
if (*mangled == 'Q')
|
1747
|
+
return dlang_parse_qualified (decl, mangled, info, 0);
|
1748
|
+
|
1749
|
+
unsigned long len;
|
1750
|
+
const char *endptr = dlang_number (mangled, &len);
|
1751
|
+
|
1752
|
+
if (endptr == NULL || len == 0)
|
1753
|
+
return NULL;
|
1754
|
+
|
1755
|
+
/* In template parameter symbols generated by the frontend up to 2.076,
|
1756
|
+
the symbol length is encoded and the first character of the mangled
|
1757
|
+
name can be a digit. This causes ambiguity issues because the digits
|
1758
|
+
of the two numbers are adjacent. */
|
1759
|
+
long psize = len;
|
1760
|
+
const char *pend;
|
1761
|
+
int saved = string_length (decl);
|
1762
|
+
|
1763
|
+
/* Work backwards until a match is found. */
|
1764
|
+
for (pend = endptr; endptr != NULL; pend--)
|
1765
|
+
{
|
1766
|
+
mangled = pend;
|
1767
|
+
|
1768
|
+
/* Reached the beginning of the pointer to the name length,
|
1769
|
+
try parsing the entire symbol. */
|
1770
|
+
if (psize == 0)
|
1771
|
+
{
|
1772
|
+
psize = len;
|
1773
|
+
pend = endptr;
|
1774
|
+
endptr = NULL;
|
1775
|
+
}
|
1776
|
+
|
1777
|
+
/* Check whether template parameter is a function with a valid
|
1778
|
+
return type or an untyped identifier. */
|
1779
|
+
if (dlang_symbol_name_p (mangled, info))
|
1780
|
+
mangled = dlang_parse_qualified (decl, mangled, info, 0);
|
1781
|
+
else if (strncmp (mangled, "_D", 2) == 0
|
1782
|
+
&& dlang_symbol_name_p (mangled + 2, info))
|
1783
|
+
mangled = dlang_parse_mangle (decl, mangled, info);
|
1784
|
+
|
1785
|
+
/* Check for name length mismatch. */
|
1786
|
+
if (mangled && (endptr == NULL || (mangled - pend) == psize))
|
1787
|
+
return mangled;
|
1788
|
+
|
1789
|
+
psize /= 10;
|
1790
|
+
string_setlength (decl, saved);
|
1791
|
+
}
|
1792
|
+
|
1793
|
+
/* No match on any combinations. */
|
1794
|
+
return NULL;
|
1795
|
+
}
|
1796
|
+
|
1508
1797
|
/* Demangle the argument list from MANGLED and append it to DECL.
|
1509
1798
|
Return the remaining string on success or NULL on failure. */
|
1510
1799
|
static const char *
|
1511
|
-
dlang_template_args (string *decl, const char *mangled)
|
1800
|
+
dlang_template_args (string *decl, const char *mangled, struct dlang_info *info)
|
1512
1801
|
{
|
1513
1802
|
size_t n = 0;
|
1514
1803
|
|
@@ -1532,11 +1821,11 @@ dlang_template_args (string *decl, const char *mangled)
|
|
1532
1821
|
{
|
1533
1822
|
case 'S': /* Symbol parameter. */
|
1534
1823
|
mangled++;
|
1535
|
-
mangled =
|
1824
|
+
mangled = dlang_template_symbol_param (decl, mangled, info);
|
1536
1825
|
break;
|
1537
1826
|
case 'T': /* Type parameter. */
|
1538
1827
|
mangled++;
|
1539
|
-
mangled = dlang_type (decl, mangled);
|
1828
|
+
mangled = dlang_type (decl, mangled, info);
|
1540
1829
|
break;
|
1541
1830
|
case 'V': /* Value parameter. */
|
1542
1831
|
{
|
@@ -1547,18 +1836,41 @@ dlang_template_args (string *decl, const char *mangled)
|
|
1547
1836
|
mangled++;
|
1548
1837
|
type = *mangled;
|
1549
1838
|
|
1839
|
+
if (type == 'Q')
|
1840
|
+
{
|
1841
|
+
/* Value type is a back reference, peek at the real type. */
|
1842
|
+
const char *backref;
|
1843
|
+
if (dlang_backref (mangled, &backref, info) == NULL)
|
1844
|
+
return NULL;
|
1845
|
+
|
1846
|
+
type = *backref;
|
1847
|
+
}
|
1848
|
+
|
1550
1849
|
/* In the few instances where the type is actually desired in
|
1551
1850
|
the output, it should precede the value from dlang_value. */
|
1552
1851
|
string_init (&name);
|
1553
|
-
mangled = dlang_type (&name, mangled);
|
1852
|
+
mangled = dlang_type (&name, mangled, info);
|
1554
1853
|
string_need (&name, 1);
|
1555
1854
|
*(name.p) = '\0';
|
1556
1855
|
|
1557
|
-
mangled = dlang_value (decl, mangled, name.b, type);
|
1856
|
+
mangled = dlang_value (decl, mangled, name.b, type, info);
|
1558
1857
|
string_delete (&name);
|
1559
1858
|
break;
|
1560
1859
|
}
|
1860
|
+
case 'X': /* Externally mangled parameter. */
|
1861
|
+
{
|
1862
|
+
unsigned long len;
|
1863
|
+
const char *endptr;
|
1864
|
+
|
1865
|
+
mangled++;
|
1866
|
+
endptr = dlang_number (mangled, &len);
|
1867
|
+
if (endptr == NULL || strlen (endptr) < len)
|
1868
|
+
return NULL;
|
1561
1869
|
|
1870
|
+
string_appendn (decl, endptr, len);
|
1871
|
+
mangled = endptr + len;
|
1872
|
+
break;
|
1873
|
+
}
|
1562
1874
|
default:
|
1563
1875
|
return NULL;
|
1564
1876
|
}
|
@@ -1568,12 +1880,14 @@ dlang_template_args (string *decl, const char *mangled)
|
|
1568
1880
|
}
|
1569
1881
|
|
1570
1882
|
/* Extract and demangle the template symbol in MANGLED, expected to
|
1571
|
-
be made up of LEN characters, and append it to DECL.
|
1883
|
+
be made up of LEN characters (-1 if unknown), and append it to DECL.
|
1572
1884
|
Returns the remaining signature on success or NULL on failure. */
|
1573
1885
|
static const char *
|
1574
|
-
dlang_parse_template (string *decl, const char *mangled,
|
1886
|
+
dlang_parse_template (string *decl, const char *mangled,
|
1887
|
+
struct dlang_info *info, unsigned long len)
|
1575
1888
|
{
|
1576
1889
|
const char *start = mangled;
|
1890
|
+
string args;
|
1577
1891
|
|
1578
1892
|
/* Template instance names have the types and values of its parameters
|
1579
1893
|
encoded into it.
|
@@ -1587,26 +1901,42 @@ dlang_parse_template (string *decl, const char *mangled, long len)
|
|
1587
1901
|
*/
|
1588
1902
|
|
1589
1903
|
/* Template symbol. */
|
1590
|
-
if (!
|
1904
|
+
if (!dlang_symbol_name_p (mangled + 3, info) || mangled[3] == '0')
|
1591
1905
|
return NULL;
|
1592
1906
|
|
1593
1907
|
mangled += 3;
|
1594
1908
|
|
1595
1909
|
/* Template identifier. */
|
1596
|
-
mangled = dlang_identifier (decl, mangled,
|
1910
|
+
mangled = dlang_identifier (decl, mangled, info);
|
1597
1911
|
|
1598
1912
|
/* Template arguments. */
|
1913
|
+
string_init (&args);
|
1914
|
+
mangled = dlang_template_args (&args, mangled, info);
|
1915
|
+
|
1599
1916
|
string_append (decl, "!(");
|
1600
|
-
|
1917
|
+
string_appendn (decl, args.b, string_length (&args));
|
1601
1918
|
string_append (decl, ")");
|
1602
1919
|
|
1920
|
+
string_delete (&args);
|
1921
|
+
|
1603
1922
|
/* Check for template name length mismatch. */
|
1604
|
-
if (
|
1923
|
+
if (len != TEMPLATE_LENGTH_UNKNOWN
|
1924
|
+
&& mangled
|
1925
|
+
&& (unsigned long) (mangled - start) != len)
|
1605
1926
|
return NULL;
|
1606
1927
|
|
1607
1928
|
return mangled;
|
1608
1929
|
}
|
1609
1930
|
|
1931
|
+
/* Initialize the information structure we use to pass around information. */
|
1932
|
+
static void
|
1933
|
+
dlang_demangle_init_info (const char *mangled, int last_backref,
|
1934
|
+
struct dlang_info *info)
|
1935
|
+
{
|
1936
|
+
info->s = mangled;
|
1937
|
+
info->last_backref = last_backref;
|
1938
|
+
}
|
1939
|
+
|
1610
1940
|
/* Extract and demangle the symbol in MANGLED. Returns the demangled
|
1611
1941
|
signature on success or NULL on failure. */
|
1612
1942
|
|
@@ -1630,7 +1960,13 @@ dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
|
|
1630
1960
|
}
|
1631
1961
|
else
|
1632
1962
|
{
|
1633
|
-
|
1963
|
+
struct dlang_info info;
|
1964
|
+
|
1965
|
+
dlang_demangle_init_info (mangled, strlen (mangled), &info);
|
1966
|
+
mangled = dlang_parse_mangle (&decl, mangled, &info);
|
1967
|
+
|
1968
|
+
/* Check that the entire symbol was successfully demangled. */
|
1969
|
+
if (mangled == NULL || *mangled != '\0')
|
1634
1970
|
string_delete (&decl);
|
1635
1971
|
}
|
1636
1972
|
|