GNU Binutils with patches for OS216
Revision | 727b7b1864973c2645a554727afd0eaf1303673a (tree) |
---|---|
Time | 2020-06-25 08:52:48 |
Author | H.J. Lu <hjl.tools@gmai...> |
Commiter | H.J. Lu |
Sync config, include and libiberty with GCC
config/
2020-06-24 H.J. Lu <hongjiu.lu@intel.com>
Sync with GCC
2020-05-29 H.J. Lu <hjl.tools@gmail.com>
PR bootstrap/95413
* cet.m4: Replace save_CFLAGS and save_LDFLAGS with
cet_save_CFLAGS and cet_save_LDFLAGS.
include/
2020-06-24 H.J. Lu <hongjiu.lu@intel.com>
Sync with GCC
2020-06-23 Nick Alcock <nick.alcock@oracle.com>
* libiberty.h (bsearch_r): New.
2020-04-17 Martin Liska <mliska@suse.cz>
Jonathan Yong <10walls@gmail.com>
PR gcov-profile/94570
* filenames.h (defined): Do not define HAVE_DOS_BASED_FILE_SYSTEM
for CYGWIN.
libiberty/
2020-06-23 Nick Alcock <nick.alcock@oracle.com>
* bsearch_r.c: New file.
* Makefile.in (CFILES): Add bsearch_r.c.
(REQUIRED_OFILES): Add bsearch_r.o.
* functions.texi: Regenerate.
2020-05-29 H.J. Lu <hjl.tools@gmail.com>
PR bootstrap/95413
* configure: Regenerated.
2020-05-15 Iain Buclaw <ibuclaw@gdcproject.org>
* d-demangle.c (dlang_attributes): Add @live attribute.
* testsuite/d-demangle-expected: Add new tests.
2020-05-14 Rainer Schuetze <r.sagitario@gmx.de>
Iain Buclaw <ibuclaw@gdcproject.org>
* d-demangle.c (enum dlang_symbol_kinds): Remove enum.
(struct dlang_info): New struct
(dlang_decode_backref): New function.
(dlang_backref): New function.
(dlang_symbol_backref): New function.
(dlang_type_backref): New function.
(dlang_symbol_name_p): New function.
(dlang_function_type_noreturn): New function.
(dlang_function_type): Add 'info' parameter. Decode function type
with dlang_function_type_noreturn.
(dlang_function_args): Add 'info' parameter.
(dlang_type): Add 'info' parameter. Handle back referenced types.
(dlang_identifier): Replace 'kind' parameter with 'info'. Handle back
referenced symbols. Split off decoding of plain identifiers to...
(dlang_lname): ...here.
(dlang_parse_mangle): Replace 'kind' parameter with 'info'. Decode
function type and return with dlang_type.
(dlang_parse_qualified): Replace 'kind' parameter with 'info', add
'suffix_modifier' parameter. Decode function type with
dlang_function_type_noreturn.
(dlang_parse_tuple): Add 'info' parameter.
(dlang_template_symbol_param): New function.
(dlang_template_args): Add 'info' parameter. Decode symbol parameter
with dlang_template_symbol_param. Handle back referenced values, and
externally mangled parameters.
(dlang_parse_template): Add 'info' parameter.
(dlang_demangle_init_info): New function.
(dlang_demangle): Initialize and pass 'info' parameter.
* testsuite/d-demangle-expected: Add new tests.
@@ -1,3 +1,12 @@ | ||
1 | +2020-06-24 H.J. Lu <hongjiu.lu@intel.com> | |
2 | + | |
3 | + Sync with GCC | |
4 | + 2020-05-29 H.J. Lu <hjl.tools@gmail.com> | |
5 | + | |
6 | + PR bootstrap/95413 | |
7 | + * cet.m4: Replace save_CFLAGS and save_LDFLAGS with | |
8 | + cet_save_CFLAGS and cet_save_LDFLAGS. | |
9 | + | |
1 | 10 | 2020-05-16 H.J. Lu <hongjiu.lu@intel.com> |
2 | 11 | |
3 | 12 | Sync with GCC |
@@ -7,13 +7,14 @@ GCC_ENABLE(cet, auto, ,[enable Intel CET in target libraries], | ||
7 | 7 | permit yes|no|auto) |
8 | 8 | AC_MSG_CHECKING([for CET support]) |
9 | 9 | |
10 | +# NB: Avoid nested save_CFLAGS and save_LDFLAGS. | |
10 | 11 | case "$host" in |
11 | 12 | i[[34567]]86-*-linux* | x86_64-*-linux*) |
12 | 13 | case "$enable_cet" in |
13 | 14 | auto) |
14 | 15 | # Check if target supports multi-byte NOPs |
15 | 16 | # and if assembler supports CET insn. |
16 | - save_CFLAGS="$CFLAGS" | |
17 | + cet_save_CFLAGS="$CFLAGS" | |
17 | 18 | CFLAGS="$CFLAGS -fcf-protection" |
18 | 19 | AC_COMPILE_IFELSE( |
19 | 20 | [AC_LANG_PROGRAM( |
@@ -27,7 +28,7 @@ asm ("setssbsy"); | ||
27 | 28 | ])], |
28 | 29 | [enable_cet=yes], |
29 | 30 | [enable_cet=no]) |
30 | - CFLAGS="$save_CFLAGS" | |
31 | + CFLAGS="$cet_save_CFLAGS" | |
31 | 32 | ;; |
32 | 33 | yes) |
33 | 34 | # Check if assembler supports CET. |
@@ -64,7 +65,7 @@ AC_MSG_CHECKING([for CET support]) | ||
64 | 65 | case "$host" in |
65 | 66 | i[[34567]]86-*-linux* | x86_64-*-linux*) |
66 | 67 | may_have_cet=yes |
67 | - save_CFLAGS="$CFLAGS" | |
68 | + cet_save_CFLAGS="$CFLAGS" | |
68 | 69 | CFLAGS="$CFLAGS -fcf-protection" |
69 | 70 | case "$enable_cet" in |
70 | 71 | auto) |
@@ -93,7 +94,7 @@ asm ("setssbsy"); | ||
93 | 94 | [AC_MSG_ERROR([assembler with CET support is required for --enable-cet])]) |
94 | 95 | ;; |
95 | 96 | esac |
96 | - CFLAGS="$save_CFLAGS" | |
97 | + CFLAGS="$cet_save_CFLAGS" | |
97 | 98 | ;; |
98 | 99 | *) |
99 | 100 | may_have_cet=no |
@@ -101,9 +102,9 @@ asm ("setssbsy"); | ||
101 | 102 | ;; |
102 | 103 | esac |
103 | 104 | |
104 | -save_CFLAGS="$CFLAGS" | |
105 | +cet_save_CFLAGS="$CFLAGS" | |
105 | 106 | CFLAGS="$CFLAGS -fcf-protection=none" |
106 | -save_LDFLAGS="$LDFLAGS" | |
107 | +cet_save_LDFLAGS="$LDFLAGS" | |
107 | 108 | LDFLAGS="$LDFLAGS -Wl,-z,ibt,-z,shstk" |
108 | 109 | if test x$may_have_cet = xyes; then |
109 | 110 | # Check whether -fcf-protection=none -Wl,-z,ibt,-z,shstk work. |
@@ -159,6 +160,6 @@ if test x$enable_cet = xyes; then | ||
159 | 160 | else |
160 | 161 | AC_MSG_RESULT([no]) |
161 | 162 | fi |
162 | -CFLAGS="$save_CFLAGS" | |
163 | -LDFLAGS="$save_LDFLAGS" | |
163 | +CFLAGS="$cet_save_CFLAGS" | |
164 | +LDFLAGS="$cet_save_LDFLAGS" | |
164 | 165 | ]) |
@@ -1,3 +1,17 @@ | ||
1 | +2020-06-24 H.J. Lu <hongjiu.lu@intel.com> | |
2 | + | |
3 | + Sync with GCC | |
4 | + 2020-06-23 Nick Alcock <nick.alcock@oracle.com> | |
5 | + | |
6 | + * libiberty.h (bsearch_r): New. | |
7 | + | |
8 | + 2020-04-17 Martin Liska <mliska@suse.cz> | |
9 | + Jonathan Yong <10walls@gmail.com> | |
10 | + | |
11 | + PR gcov-profile/94570 | |
12 | + * filenames.h (defined): Do not define HAVE_DOS_BASED_FILE_SYSTEM | |
13 | + for CYGWIN. | |
14 | + | |
1 | 15 | 2020-06-22 Alex Coplan <alex.coplan@arm.com> |
2 | 16 | |
3 | 17 | * opcode/aarch64.h (AARCH64_FEATURE_SHA2): Normalize. |
@@ -32,7 +32,8 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. | ||
32 | 32 | extern "C" { |
33 | 33 | #endif |
34 | 34 | |
35 | -#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) | |
35 | +#if defined(__MSDOS__) || (defined(_WIN32) && ! defined(__CYGWIN__)) || \ | |
36 | + defined(__OS2__) | |
36 | 37 | # ifndef HAVE_DOS_BASED_FILE_SYSTEM |
37 | 38 | # define HAVE_DOS_BASED_FILE_SYSTEM 1 |
38 | 39 | # endif |
@@ -641,6 +641,13 @@ extern int pexecute (const char *, char * const *, const char *, | ||
641 | 641 | |
642 | 642 | extern int pwait (int, int *, int); |
643 | 643 | |
644 | +/* Like bsearch, but takes and passes on an argument like qsort_r. */ | |
645 | + | |
646 | +extern void *bsearch_r (register const void *, const void *, | |
647 | + size_t, register size_t, | |
648 | + register int (*)(const void *, const void *, void *), | |
649 | + void *); | |
650 | + | |
644 | 651 | #if defined(HAVE_DECL_ASPRINTF) && !HAVE_DECL_ASPRINTF |
645 | 652 | /* Like sprintf but provides a pointer to malloc'd storage, which must |
646 | 653 | be freed by the caller. */ |
@@ -1,3 +1,53 @@ | ||
1 | +2020-06-23 Nick Alcock <nick.alcock@oracle.com> | |
2 | + | |
3 | + * bsearch_r.c: New file. | |
4 | + * Makefile.in (CFILES): Add bsearch_r.c. | |
5 | + (REQUIRED_OFILES): Add bsearch_r.o. | |
6 | + * functions.texi: Regenerate. | |
7 | + | |
8 | +2020-05-29 H.J. Lu <hjl.tools@gmail.com> | |
9 | + | |
10 | + PR bootstrap/95413 | |
11 | + * configure: Regenerated. | |
12 | + | |
13 | +2020-05-15 Iain Buclaw <ibuclaw@gdcproject.org> | |
14 | + | |
15 | + * d-demangle.c (dlang_attributes): Add @live attribute. | |
16 | + * testsuite/d-demangle-expected: Add new tests. | |
17 | + | |
18 | +2020-05-14 Rainer Schuetze <r.sagitario@gmx.de> | |
19 | + Iain Buclaw <ibuclaw@gdcproject.org> | |
20 | + | |
21 | + * d-demangle.c (enum dlang_symbol_kinds): Remove enum. | |
22 | + (struct dlang_info): New struct | |
23 | + (dlang_decode_backref): New function. | |
24 | + (dlang_backref): New function. | |
25 | + (dlang_symbol_backref): New function. | |
26 | + (dlang_type_backref): New function. | |
27 | + (dlang_symbol_name_p): New function. | |
28 | + (dlang_function_type_noreturn): New function. | |
29 | + (dlang_function_type): Add 'info' parameter. Decode function type | |
30 | + with dlang_function_type_noreturn. | |
31 | + (dlang_function_args): Add 'info' parameter. | |
32 | + (dlang_type): Add 'info' parameter. Handle back referenced types. | |
33 | + (dlang_identifier): Replace 'kind' parameter with 'info'. Handle back | |
34 | + referenced symbols. Split off decoding of plain identifiers to... | |
35 | + (dlang_lname): ...here. | |
36 | + (dlang_parse_mangle): Replace 'kind' parameter with 'info'. Decode | |
37 | + function type and return with dlang_type. | |
38 | + (dlang_parse_qualified): Replace 'kind' parameter with 'info', add | |
39 | + 'suffix_modifier' parameter. Decode function type with | |
40 | + dlang_function_type_noreturn. | |
41 | + (dlang_parse_tuple): Add 'info' parameter. | |
42 | + (dlang_template_symbol_param): New function. | |
43 | + (dlang_template_args): Add 'info' parameter. Decode symbol parameter | |
44 | + with dlang_template_symbol_param. Handle back referenced values, and | |
45 | + externally mangled parameters. | |
46 | + (dlang_parse_template): Add 'info' parameter. | |
47 | + (dlang_demangle_init_info): New function. | |
48 | + (dlang_demangle): Initialize and pass 'info' parameter. | |
49 | + * testsuite/d-demangle-expected: Add new tests. | |
50 | + | |
1 | 51 | 2020-05-12 H.J. Lu <hongjiu.lu@intel.com> |
2 | 52 | |
3 | 53 | PR bootstrap/94998 |
@@ -124,7 +124,7 @@ COMPILE.c = $(CC) -c @DEFS@ $(CFLAGS) $(CPPFLAGS) -I. -I$(INCDIR) \ | ||
124 | 124 | # CONFIGURED_OFILES and funcs in configure.ac. Also run "make maint-deps" |
125 | 125 | # to build the new rules. |
126 | 126 | CFILES = alloca.c argv.c asprintf.c atexit.c \ |
127 | - basename.c bcmp.c bcopy.c bsearch.c bzero.c \ | |
127 | + basename.c bcmp.c bcopy.c bsearch.c bsearch_r.c bzero.c \ | |
128 | 128 | calloc.c choose-temp.c clock.c concat.c cp-demangle.c \ |
129 | 129 | cp-demint.c cplus-dem.c crc32.c \ |
130 | 130 | d-demangle.c dwarfnames.c dyn-string.c \ |
@@ -168,6 +168,7 @@ REQUIRED_OFILES = \ | ||
168 | 168 | ./regex.$(objext) ./cplus-dem.$(objext) ./cp-demangle.$(objext) \ |
169 | 169 | ./md5.$(objext) ./sha1.$(objext) ./alloca.$(objext) \ |
170 | 170 | ./argv.$(objext) \ |
171 | + ./bsearch_r.$(objext) \ | |
171 | 172 | ./choose-temp.$(objext) ./concat.$(objext) \ |
172 | 173 | ./cp-demint.$(objext) ./crc32.$(objext) ./d-demangle.$(objext) \ |
173 | 174 | ./dwarfnames.$(objext) ./dyn-string.$(objext) \ |
@@ -601,6 +602,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir | ||
601 | 602 | else true; fi |
602 | 603 | $(COMPILE.c) $(srcdir)/bsearch.c $(OUTPUT_OPTION) |
603 | 604 | |
605 | +./bsearch_r.$(objext): $(srcdir)/bsearch_r.c config.h $(INCDIR)/ansidecl.h | |
606 | + if [ x"$(PICFLAG)" != x ]; then \ | |
607 | + $(COMPILE.c) $(PICFLAG) $(srcdir)/bsearch_r.c -o pic/$@; \ | |
608 | + else true; fi | |
609 | + if [ x"$(NOASANFLAG)" != x ]; then \ | |
610 | + $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/bsearch_r.c -o noasan/$@; \ | |
611 | + else true; fi | |
612 | + $(COMPILE.c) $(srcdir)/bsearch_r.c $(OUTPUT_OPTION) | |
613 | + | |
604 | 614 | ./bzero.$(objext): $(srcdir)/bzero.c |
605 | 615 | if [ x"$(PICFLAG)" != x ]; then \ |
606 | 616 | $(COMPILE.c) $(PICFLAG) $(srcdir)/bzero.c -o pic/$@; \ |
@@ -0,0 +1,93 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 1990 Regents of the University of California. | |
3 | + * All rights reserved. | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without | |
6 | + * modification, are permitted provided that the following conditions | |
7 | + * are met: | |
8 | + * 1. Redistributions of source code must retain the above copyright | |
9 | + * notice, this list of conditions and the following disclaimer. | |
10 | + * 2. Redistributions in binary form must reproduce the above copyright | |
11 | + * notice, this list of conditions and the following disclaimer in the | |
12 | + * documentation and/or other materials provided with the distribution. | |
13 | + * 3. [rescinded 22 July 1999] | |
14 | + * 4. Neither the name of the University nor the names of its contributors | |
15 | + * may be used to endorse or promote products derived from this software | |
16 | + * without specific prior written permission. | |
17 | + * | |
18 | + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
19 | + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
20 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
21 | + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
22 | + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
23 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
24 | + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
25 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
26 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
27 | + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
28 | + * SUCH DAMAGE. | |
29 | + */ | |
30 | + | |
31 | +/* | |
32 | + | |
33 | +@deftypefn Supplemental void* bsearch_r (const void *@var{key}, @ | |
34 | + const void *@var{base}, size_t @var{nmemb}, size_t @var{size}, @ | |
35 | + int (*@var{compar})(const void *, const void *, void *), void *@var{arg}) | |
36 | + | |
37 | +Performs a search over an array of @var{nmemb} elements pointed to by | |
38 | +@var{base} for a member that matches the object pointed to by @var{key}. | |
39 | +The size of each member is specified by @var{size}. The array contents | |
40 | +should be sorted in ascending order according to the @var{compar} | |
41 | +comparison function. This routine should take three arguments: the first | |
42 | +two point to the @var{key} and to an array member, and the last is passed | |
43 | +down unchanged from @code{bsearch_r}'s last argument. It should return an | |
44 | +integer less than, equal to, or greater than zero if the @var{key} object | |
45 | +is respectively less than, matching, or greater than the array member. | |
46 | + | |
47 | +@end deftypefn | |
48 | + | |
49 | +*/ | |
50 | + | |
51 | +#include "config.h" | |
52 | +#include "ansidecl.h" | |
53 | +#include <sys/types.h> /* size_t */ | |
54 | +#include <stdio.h> | |
55 | + | |
56 | +/* | |
57 | + * Perform a binary search. | |
58 | + * | |
59 | + * The code below is a bit sneaky. After a comparison fails, we | |
60 | + * divide the work in half by moving either left or right. If lim | |
61 | + * is odd, moving left simply involves halving lim: e.g., when lim | |
62 | + * is 5 we look at item 2, so we change lim to 2 so that we will | |
63 | + * look at items 0 & 1. If lim is even, the same applies. If lim | |
64 | + * is odd, moving right again involes halving lim, this time moving | |
65 | + * the base up one item past p: e.g., when lim is 5 we change base | |
66 | + * to item 3 and make lim 2 so that we will look at items 3 and 4. | |
67 | + * If lim is even, however, we have to shrink it by one before | |
68 | + * halving: e.g., when lim is 4, we still looked at item 2, so we | |
69 | + * have to make lim 3, then halve, obtaining 1, so that we will only | |
70 | + * look at item 3. | |
71 | + */ | |
72 | +void * | |
73 | +bsearch_r (register const void *key, const void *base0, | |
74 | + size_t nmemb, register size_t size, | |
75 | + register int (*compar)(const void *, const void *, void *), | |
76 | + void *arg) | |
77 | +{ | |
78 | + register const char *base = (const char *) base0; | |
79 | + register int lim, cmp; | |
80 | + register const void *p; | |
81 | + | |
82 | + for (lim = nmemb; lim != 0; lim >>= 1) { | |
83 | + p = base + (lim >> 1) * size; | |
84 | + cmp = (*compar)(key, p, arg); | |
85 | + if (cmp == 0) | |
86 | + return (void *)p; | |
87 | + if (cmp > 0) { /* key > p: move right */ | |
88 | + base = (const char *)p + size; | |
89 | + lim--; | |
90 | + } /* else move left */ | |
91 | + } | |
92 | + return (NULL); | |
93 | +} |
@@ -5286,7 +5286,7 @@ $as_echo_n "checking for CET support... " >&6; } | ||
5286 | 5286 | case "$host" in |
5287 | 5287 | i[34567]86-*-linux* | x86_64-*-linux*) |
5288 | 5288 | may_have_cet=yes |
5289 | - save_CFLAGS="$CFLAGS" | |
5289 | + cet_save_CFLAGS="$CFLAGS" | |
5290 | 5290 | CFLAGS="$CFLAGS -fcf-protection" |
5291 | 5291 | case "$enable_cet" in |
5292 | 5292 | auto) |
@@ -5337,7 +5337,7 @@ fi | ||
5337 | 5337 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext |
5338 | 5338 | ;; |
5339 | 5339 | esac |
5340 | - CFLAGS="$save_CFLAGS" | |
5340 | + CFLAGS="$cet_save_CFLAGS" | |
5341 | 5341 | ;; |
5342 | 5342 | *) |
5343 | 5343 | may_have_cet=no |
@@ -5345,9 +5345,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | ||
5345 | 5345 | ;; |
5346 | 5346 | esac |
5347 | 5347 | |
5348 | -save_CFLAGS="$CFLAGS" | |
5348 | +cet_save_CFLAGS="$CFLAGS" | |
5349 | 5349 | CFLAGS="$CFLAGS -fcf-protection=none" |
5350 | -save_LDFLAGS="$LDFLAGS" | |
5350 | +cet_save_LDFLAGS="$LDFLAGS" | |
5351 | 5351 | LDFLAGS="$LDFLAGS -Wl,-z,ibt,-z,shstk" |
5352 | 5352 | if test x$may_have_cet = xyes; then |
5353 | 5353 | # Check whether -fcf-protection=none -Wl,-z,ibt,-z,shstk work. |
@@ -5438,8 +5438,8 @@ else | ||
5438 | 5438 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 |
5439 | 5439 | $as_echo "no" >&6; } |
5440 | 5440 | fi |
5441 | -CFLAGS="$save_CFLAGS" | |
5442 | -LDFLAGS="$save_LDFLAGS" | |
5441 | +CFLAGS="$cet_save_CFLAGS" | |
5442 | +LDFLAGS="$cet_save_LDFLAGS" | |
5443 | 5443 | |
5444 | 5444 | |
5445 | 5445 |
@@ -160,37 +160,42 @@ string_prepend (string *p, const char *s) | ||
160 | 160 | } |
161 | 161 | } |
162 | 162 | |
163 | -/* What kinds of symbol we could be parsing. */ | |
164 | -enum dlang_symbol_kinds | |
163 | +/* Demangle information structure we pass around. */ | |
164 | +struct dlang_info | |
165 | 165 | { |
166 | - /* Top-level symbol, needs it's type checked. */ | |
167 | - dlang_top_level, | |
168 | - /* Function symbol, needs it's type checked. */ | |
169 | - dlang_function, | |
170 | - /* Strongly typed name, such as for classes, structs and enums. */ | |
171 | - dlang_type_name, | |
172 | - /* Template identifier. */ | |
173 | - dlang_template_ident, | |
174 | - /* Template symbol parameter. */ | |
175 | - dlang_template_param | |
166 | + /* The string we are demangling. */ | |
167 | + const char *s; | |
168 | + /* The index of the last back reference. */ | |
169 | + int last_backref; | |
176 | 170 | }; |
177 | 171 | |
172 | +/* Pass as the LEN to dlang_parse_template if symbol length is not known. */ | |
173 | +enum { TEMPLATE_LENGTH_UNKNOWN = -1 }; | |
174 | + | |
178 | 175 | /* Prototypes for forward referenced functions */ |
179 | -static const char *dlang_function_args (string *, const char *); | |
176 | +static const char *dlang_function_type (string *, const char *, | |
177 | + struct dlang_info *); | |
180 | 178 | |
181 | -static const char *dlang_type (string *, const char *); | |
179 | +static const char *dlang_function_args (string *, const char *, | |
180 | + struct dlang_info *); | |
181 | + | |
182 | +static const char *dlang_type (string *, const char *, struct dlang_info *); | |
182 | 183 | |
183 | 184 | static const char *dlang_value (string *, const char *, const char *, char); |
184 | 185 | |
185 | 186 | static const char *dlang_parse_qualified (string *, const char *, |
186 | - enum dlang_symbol_kinds); | |
187 | + struct dlang_info *, int); | |
187 | 188 | |
188 | 189 | static const char *dlang_parse_mangle (string *, const char *, |
189 | - enum dlang_symbol_kinds); | |
190 | + struct dlang_info *); | |
191 | + | |
192 | +static const char *dlang_parse_tuple (string *, const char *, | |
193 | + struct dlang_info *); | |
190 | 194 | |
191 | -static const char *dlang_parse_tuple (string *, const char *); | |
195 | +static const char *dlang_parse_template (string *, const char *, | |
196 | + struct dlang_info *, long); | |
192 | 197 | |
193 | -static const char *dlang_parse_template (string *, const char *, long); | |
198 | +static const char *dlang_lname (string *, const char *, long); | |
194 | 199 | |
195 | 200 | |
196 | 201 | /* Extract the number from MANGLED, and assign the result to RET. |
@@ -267,6 +272,175 @@ dlang_call_convention_p (const char *mangled) | ||
267 | 272 | } |
268 | 273 | } |
269 | 274 | |
275 | +/* Extract the back reference position from MANGLED, and assign the result | |
276 | + to RET. Return the remaining string on success or NULL on failure. */ | |
277 | +static const char * | |
278 | +dlang_decode_backref (const char *mangled, long *ret) | |
279 | +{ | |
280 | + /* Return NULL if trying to extract something that isn't a digit. */ | |
281 | + if (mangled == NULL || !ISALPHA (*mangled)) | |
282 | + return NULL; | |
283 | + | |
284 | + /* Any identifier or non-basic type that has been emitted to the mangled | |
285 | + symbol before will not be emitted again, but is referenced by a special | |
286 | + sequence encoding the relative position of the original occurrence in the | |
287 | + mangled symbol name. | |
288 | + | |
289 | + Numbers in back references are encoded with base 26 by upper case letters | |
290 | + A-Z for higher digits but lower case letters a-z for the last digit. | |
291 | + | |
292 | + NumberBackRef: | |
293 | + [a-z] | |
294 | + [A-Z] NumberBackRef | |
295 | + ^ | |
296 | + */ | |
297 | + (*ret) = 0; | |
298 | + | |
299 | + while (ISALPHA (*mangled)) | |
300 | + { | |
301 | + (*ret) *= 26; | |
302 | + | |
303 | + /* If an overflow occured when multiplying by 26, the result | |
304 | + will not be a multiple of 26. */ | |
305 | + if ((*ret % 26) != 0) | |
306 | + return NULL; | |
307 | + | |
308 | + if (mangled[0] >= 'a' && mangled[0] <= 'z') | |
309 | + { | |
310 | + (*ret) += mangled[0] - 'a'; | |
311 | + return mangled + 1; | |
312 | + } | |
313 | + | |
314 | + (*ret) += mangled[0] - 'A'; | |
315 | + mangled++; | |
316 | + } | |
317 | + | |
318 | + return NULL; | |
319 | +} | |
320 | + | |
321 | +/* Extract the symbol pointed at by the back reference and assign the result | |
322 | + to RET. Return the remaining string on success or NULL on failure. */ | |
323 | +static const char * | |
324 | +dlang_backref (const char *mangled, const char **ret, struct dlang_info *info) | |
325 | +{ | |
326 | + (*ret) = NULL; | |
327 | + | |
328 | + if (mangled == NULL || *mangled != 'Q') | |
329 | + return NULL; | |
330 | + | |
331 | + /* Position of 'Q'. */ | |
332 | + const char *qpos = mangled; | |
333 | + long refpos; | |
334 | + mangled++; | |
335 | + | |
336 | + mangled = dlang_decode_backref (mangled, &refpos); | |
337 | + if (mangled == NULL) | |
338 | + return NULL; | |
339 | + | |
340 | + if (refpos <= 0 || refpos > qpos - info->s) | |
341 | + return NULL; | |
342 | + | |
343 | + /* Set the position of the back reference. */ | |
344 | + (*ret) = qpos - refpos; | |
345 | + | |
346 | + return mangled; | |
347 | +} | |
348 | + | |
349 | +/* Demangle a back referenced symbol from MANGLED and append it to DECL. | |
350 | + Return the remaining string on success or NULL on failure. */ | |
351 | +static const char * | |
352 | +dlang_symbol_backref (string *decl, const char *mangled, | |
353 | + struct dlang_info *info) | |
354 | +{ | |
355 | + /* An identifier back reference always points to a digit 0 to 9. | |
356 | + | |
357 | + IdentifierBackRef: | |
358 | + Q NumberBackRef | |
359 | + ^ | |
360 | + */ | |
361 | + const char *backref; | |
362 | + long len; | |
363 | + | |
364 | + /* Get position of the back reference. */ | |
365 | + mangled = dlang_backref (mangled, &backref, info); | |
366 | + | |
367 | + /* Must point to a simple identifier. */ | |
368 | + backref = dlang_number (backref, &len); | |
369 | + if (backref == NULL) | |
370 | + return NULL; | |
371 | + | |
372 | + backref = dlang_lname (decl, backref, len); | |
373 | + if (backref == NULL) | |
374 | + return NULL; | |
375 | + | |
376 | + return mangled; | |
377 | +} | |
378 | + | |
379 | +/* Demangle a back referenced type from MANGLED and append it to DECL. | |
380 | + IS_FUNCTION is 1 if the back referenced type is expected to be a function. | |
381 | + Return the remaining string on success or NULL on failure. */ | |
382 | +static const char * | |
383 | +dlang_type_backref (string *decl, const char *mangled, struct dlang_info *info, | |
384 | + int is_function) | |
385 | +{ | |
386 | + /* A type back reference always points to a letter. | |
387 | + | |
388 | + TypeBackRef: | |
389 | + Q NumberBackRef | |
390 | + ^ | |
391 | + */ | |
392 | + const char *backref; | |
393 | + | |
394 | + /* If we appear to be moving backwards through the mangle string, then | |
395 | + bail as this may be a recursive back reference. */ | |
396 | + if (mangled - info->s >= info->last_backref) | |
397 | + return NULL; | |
398 | + | |
399 | + int save_refpos = info->last_backref; | |
400 | + info->last_backref = mangled - info->s; | |
401 | + | |
402 | + /* Get position of the back reference. */ | |
403 | + mangled = dlang_backref (mangled, &backref, info); | |
404 | + | |
405 | + /* Must point to a type. */ | |
406 | + if (is_function) | |
407 | + backref = dlang_function_type (decl, backref, info); | |
408 | + else | |
409 | + backref = dlang_type (decl, backref, info); | |
410 | + | |
411 | + info->last_backref = save_refpos; | |
412 | + | |
413 | + if (backref == NULL) | |
414 | + return NULL; | |
415 | + | |
416 | + return mangled; | |
417 | +} | |
418 | + | |
419 | +/* Extract the beginning of a symbol name from MANGLED and | |
420 | + return 1 on success or 0 on failure. */ | |
421 | +static int | |
422 | +dlang_symbol_name_p (const char *mangled, struct dlang_info *info) | |
423 | +{ | |
424 | + long ret; | |
425 | + const char *qref = mangled; | |
426 | + | |
427 | + if (ISDIGIT (*mangled)) | |
428 | + return 1; | |
429 | + | |
430 | + if (mangled[0] == '_' && mangled[1] == '_' | |
431 | + && (mangled[2] == 'T' || mangled[2] == 'U')) | |
432 | + return 1; | |
433 | + | |
434 | + if (*mangled != 'Q') | |
435 | + return 0; | |
436 | + | |
437 | + mangled = dlang_decode_backref (mangled + 1, &ret); | |
438 | + if (mangled == NULL || ret <= 0 || ret > qref - info->s) | |
439 | + return 0; | |
440 | + | |
441 | + return ISDIGIT (qref[-ret]); | |
442 | +} | |
443 | + | |
270 | 444 | /* Demangle the calling convention from MANGLED and append it to DECL. |
271 | 445 | Return the remaining string on success or NULL on failure. */ |
272 | 446 | static const char * |
@@ -404,6 +578,10 @@ dlang_attributes (string *decl, const char *mangled) | ||
404 | 578 | mangled++; |
405 | 579 | string_append (decl, "scope "); |
406 | 580 | continue; |
581 | + case 'm': /* @live */ | |
582 | + mangled++; | |
583 | + string_append (decl, "@live "); | |
584 | + continue; | |
407 | 585 | |
408 | 586 | default: /* unknown attribute */ |
409 | 587 | return NULL; |
@@ -414,13 +592,39 @@ dlang_attributes (string *decl, const char *mangled) | ||
414 | 592 | return mangled; |
415 | 593 | } |
416 | 594 | |
595 | +/* Demangle the function type from MANGLED without the return type. | |
596 | + The arguments are appended to ARGS, the calling convention is appended | |
597 | + to CALL and attributes are appended to ATTR. Any of these can be NULL | |
598 | + to throw the information away. Return the remaining string on success | |
599 | + or NULL on failure. */ | |
600 | +static const char * | |
601 | +dlang_function_type_noreturn (string *args, string *call, string *attr, | |
602 | + const char *mangled, struct dlang_info *info) | |
603 | +{ | |
604 | + string dump; | |
605 | + string_init (&dump); | |
606 | + | |
607 | + /* Skip over calling convention and attributes. */ | |
608 | + mangled = dlang_call_convention (call ? call : &dump, mangled); | |
609 | + mangled = dlang_attributes (attr ? attr : &dump, mangled); | |
610 | + | |
611 | + if (args) | |
612 | + string_append (args, "("); | |
613 | + | |
614 | + mangled = dlang_function_args (args ? args : &dump, mangled, info); | |
615 | + if (args) | |
616 | + string_append (args, ")"); | |
617 | + | |
618 | + string_delete (&dump); | |
619 | + return mangled; | |
620 | +} | |
621 | + | |
417 | 622 | /* Demangle the function type from MANGLED and append it to DECL. |
418 | 623 | Return the remaining string on success or NULL on failure. */ |
419 | 624 | static const char * |
420 | -dlang_function_type (string *decl, const char *mangled) | |
625 | +dlang_function_type (string *decl, const char *mangled, struct dlang_info *info) | |
421 | 626 | { |
422 | 627 | string attr, args, type; |
423 | - size_t szattr, szargs, sztype; | |
424 | 628 | |
425 | 629 | if (mangled == NULL || *mangled == '\0') |
426 | 630 | return NULL; |
@@ -435,27 +639,16 @@ dlang_function_type (string *decl, const char *mangled) | ||
435 | 639 | string_init (&args); |
436 | 640 | string_init (&type); |
437 | 641 | |
438 | - /* Function call convention. */ | |
439 | - mangled = dlang_call_convention (decl, mangled); | |
440 | - | |
441 | - /* Function attributes. */ | |
442 | - mangled = dlang_attributes (&attr, mangled); | |
443 | - szattr = string_length (&attr); | |
444 | - | |
445 | - /* Function arguments. */ | |
446 | - mangled = dlang_function_args (&args, mangled); | |
447 | - szargs = string_length (&args); | |
642 | + mangled = dlang_function_type_noreturn (&args, decl, &attr, mangled, info); | |
448 | 643 | |
449 | 644 | /* Function return type. */ |
450 | - mangled = dlang_type (&type, mangled); | |
451 | - sztype = string_length (&type); | |
645 | + mangled = dlang_type (&type, mangled, info); | |
452 | 646 | |
453 | 647 | /* Append to decl in order. */ |
454 | - string_appendn (decl, type.b, sztype); | |
455 | - string_append (decl, "("); | |
456 | - string_appendn (decl, args.b, szargs); | |
457 | - string_append (decl, ") "); | |
458 | - string_appendn (decl, attr.b, szattr); | |
648 | + string_appendn (decl, type.b, string_length (&type)); | |
649 | + string_appendn (decl, args.b, string_length (&args)); | |
650 | + string_append (decl, " "); | |
651 | + string_appendn (decl, attr.b, string_length (&attr)); | |
459 | 652 | |
460 | 653 | string_delete (&attr); |
461 | 654 | string_delete (&args); |
@@ -466,7 +659,7 @@ dlang_function_type (string *decl, const char *mangled) | ||
466 | 659 | /* Demangle the argument list from MANGLED and append it to DECL. |
467 | 660 | Return the remaining string on success or NULL on failure. */ |
468 | 661 | static const char * |
469 | -dlang_function_args (string *decl, const char *mangled) | |
662 | +dlang_function_args (string *decl, const char *mangled, struct dlang_info *info) | |
470 | 663 | { |
471 | 664 | size_t n = 0; |
472 | 665 |
@@ -519,7 +712,7 @@ dlang_function_args (string *decl, const char *mangled) | ||
519 | 712 | string_append (decl, "lazy "); |
520 | 713 | break; |
521 | 714 | } |
522 | - mangled = dlang_type (decl, mangled); | |
715 | + mangled = dlang_type (decl, mangled, info); | |
523 | 716 | } |
524 | 717 | |
525 | 718 | return mangled; |
@@ -528,7 +721,7 @@ dlang_function_args (string *decl, const char *mangled) | ||
528 | 721 | /* Demangle the type from MANGLED and append it to DECL. |
529 | 722 | Return the remaining string on success or NULL on failure. */ |
530 | 723 | static const char * |
531 | -dlang_type (string *decl, const char *mangled) | |
724 | +dlang_type (string *decl, const char *mangled, struct dlang_info *info) | |
532 | 725 | { |
533 | 726 | if (mangled == NULL || *mangled == '\0') |
534 | 727 | return NULL; |
@@ -538,19 +731,19 @@ dlang_type (string *decl, const char *mangled) | ||
538 | 731 | case 'O': /* shared(T) */ |
539 | 732 | mangled++; |
540 | 733 | string_append (decl, "shared("); |
541 | - mangled = dlang_type (decl, mangled); | |
734 | + mangled = dlang_type (decl, mangled, info); | |
542 | 735 | string_append (decl, ")"); |
543 | 736 | return mangled; |
544 | 737 | case 'x': /* const(T) */ |
545 | 738 | mangled++; |
546 | 739 | string_append (decl, "const("); |
547 | - mangled = dlang_type (decl, mangled); | |
740 | + mangled = dlang_type (decl, mangled, info); | |
548 | 741 | string_append (decl, ")"); |
549 | 742 | return mangled; |
550 | 743 | case 'y': /* immutable(T) */ |
551 | 744 | mangled++; |
552 | 745 | string_append (decl, "immutable("); |
553 | - mangled = dlang_type (decl, mangled); | |
746 | + mangled = dlang_type (decl, mangled, info); | |
554 | 747 | string_append (decl, ")"); |
555 | 748 | return mangled; |
556 | 749 | case 'N': |
@@ -559,7 +752,7 @@ dlang_type (string *decl, const char *mangled) | ||
559 | 752 | { |
560 | 753 | mangled++; |
561 | 754 | string_append (decl, "inout("); |
562 | - mangled = dlang_type (decl, mangled); | |
755 | + mangled = dlang_type (decl, mangled, info); | |
563 | 756 | string_append (decl, ")"); |
564 | 757 | return mangled; |
565 | 758 | } |
@@ -567,7 +760,7 @@ dlang_type (string *decl, const char *mangled) | ||
567 | 760 | { |
568 | 761 | mangled++; |
569 | 762 | string_append (decl, "__vector("); |
570 | - mangled = dlang_type (decl, mangled); | |
763 | + mangled = dlang_type (decl, mangled, info); | |
571 | 764 | string_append (decl, ")"); |
572 | 765 | return mangled; |
573 | 766 | } |
@@ -575,7 +768,7 @@ dlang_type (string *decl, const char *mangled) | ||
575 | 768 | return NULL; |
576 | 769 | case 'A': /* dynamic array (T[]) */ |
577 | 770 | mangled++; |
578 | - mangled = dlang_type (decl, mangled); | |
771 | + mangled = dlang_type (decl, mangled, info); | |
579 | 772 | string_append (decl, "[]"); |
580 | 773 | return mangled; |
581 | 774 | case 'G': /* static array (T[N]) */ |
@@ -590,7 +783,7 @@ dlang_type (string *decl, const char *mangled) | ||
590 | 783 | num++; |
591 | 784 | mangled++; |
592 | 785 | } |
593 | - mangled = dlang_type (decl, mangled); | |
786 | + mangled = dlang_type (decl, mangled, info); | |
594 | 787 | string_append (decl, "["); |
595 | 788 | string_appendn (decl, numptr, num); |
596 | 789 | string_append (decl, "]"); |
@@ -603,10 +796,10 @@ dlang_type (string *decl, const char *mangled) | ||
603 | 796 | mangled++; |
604 | 797 | |
605 | 798 | string_init (&type); |
606 | - mangled = dlang_type (&type, mangled); | |
799 | + mangled = dlang_type (&type, mangled, info); | |
607 | 800 | sztype = string_length (&type); |
608 | 801 | |
609 | - mangled = dlang_type (decl, mangled); | |
802 | + mangled = dlang_type (decl, mangled, info); | |
610 | 803 | string_append (decl, "["); |
611 | 804 | string_appendn (decl, type.b, sztype); |
612 | 805 | string_append (decl, "]"); |
@@ -618,7 +811,7 @@ dlang_type (string *decl, const char *mangled) | ||
618 | 811 | mangled++; |
619 | 812 | if (!dlang_call_convention_p (mangled)) |
620 | 813 | { |
621 | - mangled = dlang_type (decl, mangled); | |
814 | + mangled = dlang_type (decl, mangled, info); | |
622 | 815 | string_append (decl, "*"); |
623 | 816 | return mangled; |
624 | 817 | } |
@@ -630,7 +823,7 @@ dlang_type (string *decl, const char *mangled) | ||
630 | 823 | case 'R': /* function T (C++) */ |
631 | 824 | case 'Y': /* function T (Objective-C) */ |
632 | 825 | /* Function pointer types don't include the trailing asterisk. */ |
633 | - mangled = dlang_function_type (decl, mangled); | |
826 | + mangled = dlang_function_type (decl, mangled, info); | |
634 | 827 | string_append (decl, "function"); |
635 | 828 | return mangled; |
636 | 829 | case 'I': /* ident T */ |
@@ -639,7 +832,7 @@ dlang_type (string *decl, const char *mangled) | ||
639 | 832 | case 'E': /* enum T */ |
640 | 833 | case 'T': /* typedef T */ |
641 | 834 | mangled++; |
642 | - return dlang_parse_qualified (decl, mangled, dlang_type_name); | |
835 | + return dlang_parse_qualified (decl, mangled, info, 0); | |
643 | 836 | case 'D': /* delegate T */ |
644 | 837 | { |
645 | 838 | string mods; |
@@ -650,7 +843,12 @@ dlang_type (string *decl, const char *mangled) | ||
650 | 843 | mangled = dlang_type_modifiers (&mods, mangled); |
651 | 844 | szmods = string_length (&mods); |
652 | 845 | |
653 | - mangled = dlang_function_type (decl, mangled); | |
846 | + /* Back referenced function type. */ | |
847 | + if (*mangled == 'Q') | |
848 | + mangled = dlang_type_backref (decl, mangled, info, 1); | |
849 | + else | |
850 | + mangled = dlang_function_type (decl, mangled, info); | |
851 | + | |
654 | 852 | string_append (decl, "delegate"); |
655 | 853 | string_appendn (decl, mods.b, szmods); |
656 | 854 |
@@ -659,7 +857,7 @@ dlang_type (string *decl, const char *mangled) | ||
659 | 857 | } |
660 | 858 | case 'B': /* tuple T */ |
661 | 859 | mangled++; |
662 | - return dlang_parse_tuple (decl, mangled); | |
860 | + return dlang_parse_tuple (decl, mangled, info); | |
663 | 861 | |
664 | 862 | /* Basic types */ |
665 | 863 | case 'n': |
@@ -773,6 +971,10 @@ dlang_type (string *decl, const char *mangled) | ||
773 | 971 | } |
774 | 972 | return NULL; |
775 | 973 | |
974 | + /* Back referenced type. */ | |
975 | + case 'Q': | |
976 | + return dlang_type_backref (decl, mangled, info, 0); | |
977 | + | |
776 | 978 | default: /* unhandled */ |
777 | 979 | return NULL; |
778 | 980 | } |
@@ -781,152 +983,127 @@ dlang_type (string *decl, const char *mangled) | ||
781 | 983 | /* Extract the identifier from MANGLED and append it to DECL. |
782 | 984 | Return the remaining string on success or NULL on failure. */ |
783 | 985 | static const char * |
784 | -dlang_identifier (string *decl, const char *mangled, | |
785 | - enum dlang_symbol_kinds kind) | |
986 | +dlang_identifier (string *decl, const char *mangled, struct dlang_info *info) | |
786 | 987 | { |
787 | 988 | long len; |
788 | - const char *endptr = dlang_number (mangled, &len); | |
789 | 989 | |
790 | - if (endptr == NULL || len == 0) | |
990 | + if (mangled == NULL || *mangled == '\0') | |
791 | 991 | return NULL; |
792 | 992 | |
793 | - /* In template parameter symbols, the first character of the mangled | |
794 | - name can be a digit. This causes ambiguity issues because the | |
795 | - digits of the two numbers are adjacent. */ | |
796 | - if (kind == dlang_template_param) | |
797 | - { | |
798 | - long psize = len; | |
799 | - const char *pend; | |
800 | - int saved = string_length (decl); | |
801 | - | |
802 | - /* Work backwards until a match is found. */ | |
803 | - for (pend = endptr; endptr != NULL; pend--) | |
804 | - { | |
805 | - mangled = pend; | |
993 | + if (*mangled == 'Q') | |
994 | + return dlang_symbol_backref (decl, mangled, info); | |
806 | 995 | |
807 | - /* Reached the beginning of the pointer to the name length, | |
808 | - try parsing the entire symbol. */ | |
809 | - if (psize == 0) | |
810 | - { | |
811 | - psize = len; | |
812 | - pend = endptr; | |
813 | - endptr = NULL; | |
814 | - } | |
996 | + /* May be a template instance without a length prefix. */ | |
997 | + if (mangled[0] == '_' && mangled[1] == '_' | |
998 | + && (mangled[2] == 'T' || mangled[2] == 'U')) | |
999 | + return dlang_parse_template (decl, mangled, info, TEMPLATE_LENGTH_UNKNOWN); | |
815 | 1000 | |
816 | - /* Check whether template parameter is a function with a valid | |
817 | - return type or an untyped identifier. */ | |
818 | - if (ISDIGIT (*mangled)) | |
819 | - mangled = dlang_parse_qualified (decl, mangled, | |
820 | - dlang_template_ident); | |
821 | - else if (strncmp (mangled, "_D", 2) == 0) | |
822 | - mangled = dlang_parse_mangle (decl, mangled, dlang_function); | |
1001 | + const char *endptr = dlang_number (mangled, &len); | |
823 | 1002 | |
824 | - /* Check for name length mismatch. */ | |
825 | - if (mangled && (mangled - pend) == psize) | |
826 | - return mangled; | |
1003 | + if (endptr == NULL || len == 0) | |
1004 | + return NULL; | |
827 | 1005 | |
828 | - psize /= 10; | |
829 | - string_setlength (decl, saved); | |
830 | - } | |
1006 | + if (strlen (endptr) < (size_t) len) | |
1007 | + return NULL; | |
831 | 1008 | |
832 | - /* No match on any combinations. */ | |
833 | - return NULL; | |
834 | - } | |
835 | - else | |
836 | - { | |
837 | - if (strlen (endptr) < (size_t) len) | |
838 | - return NULL; | |
1009 | + mangled = endptr; | |
839 | 1010 | |
840 | - mangled = endptr; | |
1011 | + /* May be a template instance with a length prefix. */ | |
1012 | + if (len >= 5 && mangled[0] == '_' && mangled[1] == '_' | |
1013 | + && (mangled[2] == 'T' || mangled[2] == 'U')) | |
1014 | + return dlang_parse_template (decl, mangled, info, len); | |
841 | 1015 | |
842 | - /* May be a template instance. */ | |
843 | - if (len >= 5 && mangled[0] == '_' && mangled[1] == '_' | |
844 | - && (mangled[2] == 'T' || mangled[2] == 'U')) | |
845 | - return dlang_parse_template (decl, mangled, len); | |
1016 | + return dlang_lname (decl, mangled, len); | |
1017 | +} | |
846 | 1018 | |
847 | - switch (len) | |
1019 | +/* Extract the plain identifier from MANGLED and prepend/append it to DECL | |
1020 | + with special treatment for some magic compiler generted symbols. | |
1021 | + Return the remaining string on success or NULL on failure. */ | |
1022 | +static const char * | |
1023 | +dlang_lname (string *decl, const char *mangled, long len) | |
1024 | +{ | |
1025 | + switch (len) | |
1026 | + { | |
1027 | + case 6: | |
1028 | + if (strncmp (mangled, "__ctor", len) == 0) | |
848 | 1029 | { |
849 | - case 6: | |
850 | - if (strncmp (mangled, "__ctor", len) == 0) | |
851 | - { | |
852 | - /* Constructor symbol for a class/struct. */ | |
853 | - string_append (decl, "this"); | |
854 | - mangled += len; | |
855 | - return mangled; | |
856 | - } | |
857 | - else if (strncmp (mangled, "__dtor", len) == 0) | |
858 | - { | |
859 | - /* Destructor symbol for a class/struct. */ | |
860 | - string_append (decl, "~this"); | |
861 | - mangled += len; | |
862 | - return mangled; | |
863 | - } | |
864 | - else if (strncmp (mangled, "__initZ", len+1) == 0) | |
865 | - { | |
866 | - /* The static initialiser for a given symbol. */ | |
867 | - string_prepend (decl, "initializer for "); | |
868 | - string_setlength (decl, string_length (decl) - 1); | |
869 | - mangled += len; | |
870 | - return mangled; | |
871 | - } | |
872 | - else if (strncmp (mangled, "__vtblZ", len+1) == 0) | |
873 | - { | |
874 | - /* The vtable symbol for a given class. */ | |
875 | - string_prepend (decl, "vtable for "); | |
876 | - string_setlength (decl, string_length (decl) - 1); | |
877 | - mangled += len; | |
878 | - return mangled; | |
879 | - } | |
880 | - break; | |
881 | - | |
882 | - case 7: | |
883 | - if (strncmp (mangled, "__ClassZ", len+1) == 0) | |
884 | - { | |
885 | - /* The classinfo symbol for a given class. */ | |
886 | - string_prepend (decl, "ClassInfo for "); | |
887 | - string_setlength (decl, string_length (decl) - 1); | |
888 | - mangled += len; | |
889 | - return mangled; | |
890 | - } | |
891 | - break; | |
1030 | + /* Constructor symbol for a class/struct. */ | |
1031 | + string_append (decl, "this"); | |
1032 | + mangled += len; | |
1033 | + return mangled; | |
1034 | + } | |
1035 | + else if (strncmp (mangled, "__dtor", len) == 0) | |
1036 | + { | |
1037 | + /* Destructor symbol for a class/struct. */ | |
1038 | + string_append (decl, "~this"); | |
1039 | + mangled += len; | |
1040 | + return mangled; | |
1041 | + } | |
1042 | + else if (strncmp (mangled, "__initZ", len + 1) == 0) | |
1043 | + { | |
1044 | + /* The static initialiser for a given symbol. */ | |
1045 | + string_prepend (decl, "initializer for "); | |
1046 | + string_setlength (decl, string_length (decl) - 1); | |
1047 | + mangled += len; | |
1048 | + return mangled; | |
1049 | + } | |
1050 | + else if (strncmp (mangled, "__vtblZ", len + 1) == 0) | |
1051 | + { | |
1052 | + /* The vtable symbol for a given class. */ | |
1053 | + string_prepend (decl, "vtable for "); | |
1054 | + string_setlength (decl, string_length (decl) - 1); | |
1055 | + mangled += len; | |
1056 | + return mangled; | |
1057 | + } | |
1058 | + break; | |
892 | 1059 | |
893 | - case 10: | |
894 | - if (strncmp (mangled, "__postblitMFZ", len+3) == 0) | |
895 | - { | |
896 | - /* Postblit symbol for a struct. */ | |
897 | - string_append (decl, "this(this)"); | |
898 | - mangled += len + 3; | |
899 | - return mangled; | |
900 | - } | |
901 | - break; | |
1060 | + case 7: | |
1061 | + if (strncmp (mangled, "__ClassZ", len + 1) == 0) | |
1062 | + { | |
1063 | + /* The classinfo symbol for a given class. */ | |
1064 | + string_prepend (decl, "ClassInfo for "); | |
1065 | + string_setlength (decl, string_length (decl) - 1); | |
1066 | + mangled += len; | |
1067 | + return mangled; | |
1068 | + } | |
1069 | + break; | |
902 | 1070 | |
903 | - case 11: | |
904 | - if (strncmp (mangled, "__InterfaceZ", len+1) == 0) | |
905 | - { | |
906 | - /* The interface symbol for a given class. */ | |
907 | - string_prepend (decl, "Interface for "); | |
908 | - string_setlength (decl, string_length (decl) - 1); | |
909 | - mangled += len; | |
910 | - return mangled; | |
911 | - } | |
912 | - break; | |
1071 | + case 10: | |
1072 | + if (strncmp (mangled, "__postblitMFZ", len + 3) == 0) | |
1073 | + { | |
1074 | + /* Postblit symbol for a struct. */ | |
1075 | + string_append (decl, "this(this)"); | |
1076 | + mangled += len + 3; | |
1077 | + return mangled; | |
1078 | + } | |
1079 | + break; | |
913 | 1080 | |
914 | - case 12: | |
915 | - if (strncmp (mangled, "__ModuleInfoZ", len+1) == 0) | |
916 | - { | |
917 | - /* The ModuleInfo symbol for a given module. */ | |
918 | - string_prepend (decl, "ModuleInfo for "); | |
919 | - string_setlength (decl, string_length (decl) - 1); | |
920 | - mangled += len; | |
921 | - return mangled; | |
922 | - } | |
923 | - break; | |
1081 | + case 11: | |
1082 | + if (strncmp (mangled, "__InterfaceZ", len + 1) == 0) | |
1083 | + { | |
1084 | + /* The interface symbol for a given class. */ | |
1085 | + string_prepend (decl, "Interface for "); | |
1086 | + string_setlength (decl, string_length (decl) - 1); | |
1087 | + mangled += len; | |
1088 | + return mangled; | |
924 | 1089 | } |
1090 | + break; | |
925 | 1091 | |
926 | - string_appendn (decl, mangled, len); | |
927 | - mangled += len; | |
1092 | + case 12: | |
1093 | + if (strncmp (mangled, "__ModuleInfoZ", len + 1) == 0) | |
1094 | + { | |
1095 | + /* The ModuleInfo symbol for a given module. */ | |
1096 | + string_prepend (decl, "ModuleInfo for "); | |
1097 | + string_setlength (decl, string_length (decl) - 1); | |
1098 | + mangled += len; | |
1099 | + return mangled; | |
1100 | + } | |
1101 | + break; | |
928 | 1102 | } |
929 | 1103 | |
1104 | + string_appendn (decl, mangled, len); | |
1105 | + mangled += len; | |
1106 | + | |
930 | 1107 | return mangled; |
931 | 1108 | } |
932 | 1109 |
@@ -1347,22 +1524,22 @@ dlang_value (string *decl, const char *mangled, const char *name, char type) | ||
1347 | 1524 | /* Extract and demangle the symbol in MANGLED and append it to DECL. |
1348 | 1525 | Returns the remaining signature on success or NULL on failure. */ |
1349 | 1526 | static const char * |
1350 | -dlang_parse_mangle (string *decl, const char *mangled, | |
1351 | - enum dlang_symbol_kinds kind) | |
1527 | +dlang_parse_mangle (string *decl, const char *mangled, struct dlang_info *info) | |
1352 | 1528 | { |
1353 | 1529 | /* A D mangled symbol is comprised of both scope and type information. |
1354 | 1530 | |
1355 | 1531 | MangleName: |
1356 | 1532 | _D QualifiedName Type |
1357 | - _D QualifiedName M Type | |
1358 | 1533 | _D QualifiedName Z |
1359 | 1534 | ^ |
1360 | 1535 | The caller should have guaranteed that the start pointer is at the |
1361 | 1536 | above location. |
1537 | + Note that type is never a function type, but only the return type of | |
1538 | + a function or the type of a variable. | |
1362 | 1539 | */ |
1363 | 1540 | mangled += 2; |
1364 | 1541 | |
1365 | - mangled = dlang_parse_qualified (decl, mangled, dlang_top_level); | |
1542 | + mangled = dlang_parse_qualified (decl, mangled, info, 1); | |
1366 | 1543 | |
1367 | 1544 | if (mangled != NULL) |
1368 | 1545 | { |
@@ -1371,68 +1548,40 @@ dlang_parse_mangle (string *decl, const char *mangled, | ||
1371 | 1548 | mangled++; |
1372 | 1549 | else |
1373 | 1550 | { |
1374 | - string mods; | |
1375 | - int saved; | |
1376 | - | |
1377 | - /* Skip over 'this' parameter. */ | |
1378 | - if (*mangled == 'M') | |
1379 | - mangled++; | |
1380 | - | |
1381 | - /* Save the type modifiers for appending at the end if needed. */ | |
1382 | - string_init (&mods); | |
1383 | - mangled = dlang_type_modifiers (&mods, mangled); | |
1384 | - | |
1385 | - if (mangled && dlang_call_convention_p (mangled)) | |
1386 | - { | |
1387 | - /* Skip over calling convention and attributes. */ | |
1388 | - saved = string_length (decl); | |
1389 | - mangled = dlang_call_convention (decl, mangled); | |
1390 | - mangled = dlang_attributes (decl, mangled); | |
1391 | - string_setlength (decl, saved); | |
1392 | - | |
1393 | - string_append (decl, "("); | |
1394 | - mangled = dlang_function_args (decl, mangled); | |
1395 | - string_append (decl, ")"); | |
1396 | - | |
1397 | - /* Add any const/immutable/shared modifier. */ | |
1398 | - string_appendn (decl, mods.b, string_length (&mods)); | |
1399 | - } | |
1400 | - | |
1401 | - /* Consume the decl type of symbol. */ | |
1402 | - saved = string_length (decl); | |
1403 | - mangled = dlang_type (decl, mangled); | |
1404 | - string_setlength (decl, saved); | |
1551 | + /* Discard the declaration or return type. */ | |
1552 | + string type; | |
1405 | 1553 | |
1406 | - string_delete (&mods); | |
1554 | + string_init (&type); | |
1555 | + mangled = dlang_type (&type, mangled, info); | |
1556 | + string_delete (&type); | |
1407 | 1557 | } |
1408 | 1558 | } |
1409 | 1559 | |
1410 | - /* Check that the entire symbol was successfully demangled. */ | |
1411 | - if (kind == dlang_top_level) | |
1412 | - { | |
1413 | - if (mangled == NULL || *mangled != '\0') | |
1414 | - return NULL; | |
1415 | - } | |
1416 | - | |
1417 | 1560 | return mangled; |
1418 | 1561 | } |
1419 | 1562 | |
1420 | 1563 | /* Extract and demangle the qualified symbol in MANGLED and append it to DECL. |
1564 | + SUFFIX_MODIFIERS is 1 if we are printing modifiers on this after the symbol. | |
1421 | 1565 | Returns the remaining signature on success or NULL on failure. */ |
1422 | 1566 | static const char * |
1423 | 1567 | dlang_parse_qualified (string *decl, const char *mangled, |
1424 | - enum dlang_symbol_kinds kind) | |
1568 | + struct dlang_info *info, int suffix_modifiers) | |
1425 | 1569 | { |
1426 | 1570 | /* Qualified names are identifiers separated by their encoded length. |
1427 | 1571 | Nested functions also encode their argument types without specifying |
1428 | 1572 | what they return. |
1429 | 1573 | |
1430 | 1574 | QualifiedName: |
1431 | - SymbolName | |
1432 | - SymbolName QualifiedName | |
1433 | - SymbolName TypeFunctionNoReturn QualifiedName | |
1434 | - SymbolName M TypeModifiers TypeFunctionNoReturn QualifiedName | |
1575 | + SymbolFunctionName | |
1576 | + SymbolFunctionName QualifiedName | |
1435 | 1577 | ^ |
1578 | + | |
1579 | + SymbolFunctionName: | |
1580 | + SymbolName | |
1581 | + SymbolName TypeFunctionNoReturn | |
1582 | + SymbolName M TypeFunctionNoReturn | |
1583 | + SymbolName M TypeModifiers TypeFunctionNoReturn | |
1584 | + | |
1436 | 1585 | The start pointer should be at the above location. |
1437 | 1586 | */ |
1438 | 1587 | size_t n = 0; |
@@ -1445,49 +1594,45 @@ dlang_parse_qualified (string *decl, const char *mangled, | ||
1445 | 1594 | while (*mangled == '0') |
1446 | 1595 | mangled++; |
1447 | 1596 | |
1448 | - mangled = dlang_identifier (decl, mangled, kind); | |
1597 | + mangled = dlang_identifier (decl, mangled, info); | |
1449 | 1598 | |
1450 | 1599 | /* Consume the encoded arguments. However if this is not followed by the |
1451 | - next encoded length, then this is not a continuation of a qualified | |
1452 | - name, in which case we backtrack and return the current unconsumed | |
1453 | - position of the mangled decl. */ | |
1600 | + next encoded length or mangle type, then this is not a continuation of | |
1601 | + a qualified name, in which case we backtrack and return the current | |
1602 | + unconsumed position of the mangled decl. */ | |
1454 | 1603 | if (mangled && (*mangled == 'M' || dlang_call_convention_p (mangled))) |
1455 | 1604 | { |
1605 | + string mods; | |
1456 | 1606 | const char *start = mangled; |
1457 | 1607 | int saved = string_length (decl); |
1458 | 1608 | |
1609 | + /* Save the type modifiers for appending at the end if needed. */ | |
1610 | + string_init (&mods); | |
1611 | + | |
1459 | 1612 | /* Skip over 'this' parameter and type modifiers. */ |
1460 | 1613 | if (*mangled == 'M') |
1461 | 1614 | { |
1462 | 1615 | mangled++; |
1463 | - mangled = dlang_type_modifiers (decl, mangled); | |
1616 | + mangled = dlang_type_modifiers (&mods, mangled); | |
1464 | 1617 | string_setlength (decl, saved); |
1465 | 1618 | } |
1466 | 1619 | |
1467 | - /* The rule we expect to match in the mangled string is: | |
1468 | - | |
1469 | - TypeFunctionNoReturn: | |
1470 | - CallConvention FuncAttrs Arguments ArgClose | |
1471 | - | |
1472 | - The calling convention and function attributes are not included | |
1473 | - in the demangled string. */ | |
1474 | - mangled = dlang_call_convention (decl, mangled); | |
1475 | - mangled = dlang_attributes (decl, mangled); | |
1476 | - string_setlength (decl, saved); | |
1620 | + mangled = dlang_function_type_noreturn (decl, NULL, NULL, | |
1621 | + mangled, info); | |
1622 | + if (suffix_modifiers) | |
1623 | + string_appendn (decl, mods.b, string_length (&mods)); | |
1477 | 1624 | |
1478 | - string_append (decl, "("); | |
1479 | - mangled = dlang_function_args (decl, mangled); | |
1480 | - string_append (decl, ")"); | |
1481 | - | |
1482 | - if (mangled == NULL || !ISDIGIT (*mangled)) | |
1625 | + if (mangled == NULL || *mangled == '\0') | |
1483 | 1626 | { |
1484 | 1627 | /* Did not match the rule we were looking for. */ |
1485 | 1628 | mangled = start; |
1486 | 1629 | string_setlength (decl, saved); |
1487 | 1630 | } |
1631 | + | |
1632 | + string_delete (&mods); | |
1488 | 1633 | } |
1489 | 1634 | } |
1490 | - while (mangled && ISDIGIT (*mangled)); | |
1635 | + while (mangled && dlang_symbol_name_p (mangled, info)); | |
1491 | 1636 | |
1492 | 1637 | return mangled; |
1493 | 1638 | } |
@@ -1495,7 +1640,7 @@ dlang_parse_qualified (string *decl, const char *mangled, | ||
1495 | 1640 | /* Demangle the tuple from MANGLED and append it to DECL. |
1496 | 1641 | Return the remaining string on success or NULL on failure. */ |
1497 | 1642 | static const char * |
1498 | -dlang_parse_tuple (string *decl, const char *mangled) | |
1643 | +dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info) | |
1499 | 1644 | { |
1500 | 1645 | long elements; |
1501 | 1646 |
@@ -1507,7 +1652,7 @@ dlang_parse_tuple (string *decl, const char *mangled) | ||
1507 | 1652 | |
1508 | 1653 | while (elements--) |
1509 | 1654 | { |
1510 | - mangled = dlang_type (decl, mangled); | |
1655 | + mangled = dlang_type (decl, mangled, info); | |
1511 | 1656 | if (mangled == NULL) |
1512 | 1657 | return NULL; |
1513 | 1658 |
@@ -1519,10 +1664,71 @@ dlang_parse_tuple (string *decl, const char *mangled) | ||
1519 | 1664 | return mangled; |
1520 | 1665 | } |
1521 | 1666 | |
1667 | +/* Demangle the template symbol parameter from MANGLED and append it to DECL. | |
1668 | + Return the remaining string on success or NULL on failure. */ | |
1669 | +static const char * | |
1670 | +dlang_template_symbol_param (string *decl, const char *mangled, | |
1671 | + struct dlang_info *info) | |
1672 | +{ | |
1673 | + if (strncmp (mangled, "_D", 2) == 0 | |
1674 | + && dlang_symbol_name_p (mangled + 2, info)) | |
1675 | + return dlang_parse_mangle (decl, mangled, info); | |
1676 | + | |
1677 | + if (*mangled == 'Q') | |
1678 | + return dlang_parse_qualified (decl, mangled, info, 0); | |
1679 | + | |
1680 | + long len; | |
1681 | + const char *endptr = dlang_number (mangled, &len); | |
1682 | + | |
1683 | + if (endptr == NULL || len == 0) | |
1684 | + return NULL; | |
1685 | + | |
1686 | + /* In template parameter symbols generated by the frontend up to 2.076, | |
1687 | + the symbol length is encoded and the first character of the mangled | |
1688 | + name can be a digit. This causes ambiguity issues because the digits | |
1689 | + of the two numbers are adjacent. */ | |
1690 | + long psize = len; | |
1691 | + const char *pend; | |
1692 | + int saved = string_length (decl); | |
1693 | + | |
1694 | + /* Work backwards until a match is found. */ | |
1695 | + for (pend = endptr; endptr != NULL; pend--) | |
1696 | + { | |
1697 | + mangled = pend; | |
1698 | + | |
1699 | + /* Reached the beginning of the pointer to the name length, | |
1700 | + try parsing the entire symbol. */ | |
1701 | + if (psize == 0) | |
1702 | + { | |
1703 | + psize = len; | |
1704 | + pend = endptr; | |
1705 | + endptr = NULL; | |
1706 | + } | |
1707 | + | |
1708 | + /* Check whether template parameter is a function with a valid | |
1709 | + return type or an untyped identifier. */ | |
1710 | + if (dlang_symbol_name_p (mangled, info)) | |
1711 | + mangled = dlang_parse_qualified (decl, mangled, info, 0); | |
1712 | + else if (strncmp (mangled, "_D", 2) == 0 | |
1713 | + && dlang_symbol_name_p (mangled + 2, info)) | |
1714 | + mangled = dlang_parse_mangle (decl, mangled, info); | |
1715 | + | |
1716 | + /* Check for name length mismatch. */ | |
1717 | + if (mangled && (endptr == NULL || (mangled - pend) == psize)) | |
1718 | + return mangled; | |
1719 | + | |
1720 | + psize /= 10; | |
1721 | + string_setlength (decl, saved); | |
1722 | + } | |
1723 | + | |
1724 | + /* No match on any combinations. */ | |
1725 | + return NULL; | |
1726 | +} | |
1727 | + | |
1522 | 1728 | /* Demangle the argument list from MANGLED and append it to DECL. |
1523 | 1729 | Return the remaining string on success or NULL on failure. */ |
1524 | 1730 | static const char * |
1525 | -dlang_template_args (string *decl, const char *mangled) | |
1731 | +dlang_template_args (string *decl, const char *mangled, struct dlang_info *info) | |
1526 | 1732 | { |
1527 | 1733 | size_t n = 0; |
1528 | 1734 |
@@ -1546,11 +1752,11 @@ dlang_template_args (string *decl, const char *mangled) | ||
1546 | 1752 | { |
1547 | 1753 | case 'S': /* Symbol parameter. */ |
1548 | 1754 | mangled++; |
1549 | - mangled = dlang_identifier (decl, mangled, dlang_template_param); | |
1755 | + mangled = dlang_template_symbol_param (decl, mangled, info); | |
1550 | 1756 | break; |
1551 | 1757 | case 'T': /* Type parameter. */ |
1552 | 1758 | mangled++; |
1553 | - mangled = dlang_type (decl, mangled); | |
1759 | + mangled = dlang_type (decl, mangled, info); | |
1554 | 1760 | break; |
1555 | 1761 | case 'V': /* Value parameter. */ |
1556 | 1762 | { |
@@ -1561,10 +1767,20 @@ dlang_template_args (string *decl, const char *mangled) | ||
1561 | 1767 | mangled++; |
1562 | 1768 | type = *mangled; |
1563 | 1769 | |
1770 | + if (type == 'Q') | |
1771 | + { | |
1772 | + /* Value type is a back reference, peek at the real type. */ | |
1773 | + const char *backref; | |
1774 | + if (dlang_backref (mangled, &backref, info) == NULL) | |
1775 | + return NULL; | |
1776 | + | |
1777 | + type = *backref; | |
1778 | + } | |
1779 | + | |
1564 | 1780 | /* In the few instances where the type is actually desired in |
1565 | 1781 | the output, it should precede the value from dlang_value. */ |
1566 | 1782 | string_init (&name); |
1567 | - mangled = dlang_type (&name, mangled); | |
1783 | + mangled = dlang_type (&name, mangled, info); | |
1568 | 1784 | string_need (&name, 1); |
1569 | 1785 | *(name.p) = '\0'; |
1570 | 1786 |
@@ -1572,7 +1788,20 @@ dlang_template_args (string *decl, const char *mangled) | ||
1572 | 1788 | string_delete (&name); |
1573 | 1789 | break; |
1574 | 1790 | } |
1791 | + case 'X': /* Externally mangled parameter. */ | |
1792 | + { | |
1793 | + long len; | |
1794 | + const char *endptr; | |
1575 | 1795 | |
1796 | + mangled++; | |
1797 | + endptr = dlang_number (mangled, &len); | |
1798 | + if (endptr == NULL || strlen (endptr) < (size_t) len) | |
1799 | + return NULL; | |
1800 | + | |
1801 | + string_appendn (decl, endptr, len); | |
1802 | + mangled = endptr + len; | |
1803 | + break; | |
1804 | + } | |
1576 | 1805 | default: |
1577 | 1806 | return NULL; |
1578 | 1807 | } |
@@ -1582,12 +1811,14 @@ dlang_template_args (string *decl, const char *mangled) | ||
1582 | 1811 | } |
1583 | 1812 | |
1584 | 1813 | /* Extract and demangle the template symbol in MANGLED, expected to |
1585 | - be made up of LEN characters, and append it to DECL. | |
1814 | + be made up of LEN characters (-1 if unknown), and append it to DECL. | |
1586 | 1815 | Returns the remaining signature on success or NULL on failure. */ |
1587 | 1816 | static const char * |
1588 | -dlang_parse_template (string *decl, const char *mangled, long len) | |
1817 | +dlang_parse_template (string *decl, const char *mangled, | |
1818 | + struct dlang_info *info, long len) | |
1589 | 1819 | { |
1590 | 1820 | const char *start = mangled; |
1821 | + string args; | |
1591 | 1822 | |
1592 | 1823 | /* Template instance names have the types and values of its parameters |
1593 | 1824 | encoded into it. |
@@ -1601,26 +1832,40 @@ dlang_parse_template (string *decl, const char *mangled, long len) | ||
1601 | 1832 | */ |
1602 | 1833 | |
1603 | 1834 | /* Template symbol. */ |
1604 | - if (!ISDIGIT (mangled[3]) || mangled[3] == '0') | |
1835 | + if (!dlang_symbol_name_p (mangled + 3, info) || mangled[3] == '0') | |
1605 | 1836 | return NULL; |
1606 | 1837 | |
1607 | 1838 | mangled += 3; |
1608 | 1839 | |
1609 | 1840 | /* Template identifier. */ |
1610 | - mangled = dlang_identifier (decl, mangled, dlang_template_ident); | |
1841 | + mangled = dlang_identifier (decl, mangled, info); | |
1611 | 1842 | |
1612 | 1843 | /* Template arguments. */ |
1844 | + string_init (&args); | |
1845 | + mangled = dlang_template_args (&args, mangled, info); | |
1846 | + | |
1613 | 1847 | string_append (decl, "!("); |
1614 | - mangled = dlang_template_args (decl, mangled); | |
1848 | + string_appendn (decl, args.b, string_length (&args)); | |
1615 | 1849 | string_append (decl, ")"); |
1616 | 1850 | |
1851 | + string_delete (&args); | |
1852 | + | |
1617 | 1853 | /* Check for template name length mismatch. */ |
1618 | - if (mangled && (mangled - start) != len) | |
1854 | + if (len != TEMPLATE_LENGTH_UNKNOWN && mangled && (mangled - start) != len) | |
1619 | 1855 | return NULL; |
1620 | 1856 | |
1621 | 1857 | return mangled; |
1622 | 1858 | } |
1623 | 1859 | |
1860 | +/* Initialize the information structure we use to pass around information. */ | |
1861 | +static void | |
1862 | +dlang_demangle_init_info (const char *mangled, int last_backref, | |
1863 | + struct dlang_info *info) | |
1864 | +{ | |
1865 | + info->s = mangled; | |
1866 | + info->last_backref = last_backref; | |
1867 | +} | |
1868 | + | |
1624 | 1869 | /* Extract and demangle the symbol in MANGLED. Returns the demangled |
1625 | 1870 | signature on success or NULL on failure. */ |
1626 | 1871 |
@@ -1644,7 +1889,13 @@ dlang_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) | ||
1644 | 1889 | } |
1645 | 1890 | else |
1646 | 1891 | { |
1647 | - if (dlang_parse_mangle (&decl, mangled, dlang_top_level) == NULL) | |
1892 | + struct dlang_info info; | |
1893 | + | |
1894 | + dlang_demangle_init_info (mangled, strlen (mangled), &info); | |
1895 | + mangled = dlang_parse_mangle (&decl, mangled, &info); | |
1896 | + | |
1897 | + /* Check that the entire symbol was successfully demangled. */ | |
1898 | + if (mangled == NULL || *mangled != '\0') | |
1648 | 1899 | string_delete (&decl); |
1649 | 1900 | } |
1650 | 1901 |
@@ -84,6 +84,23 @@ is respectively less than, matching, or greater than the array member. | ||
84 | 84 | |
85 | 85 | @end deftypefn |
86 | 86 | |
87 | +@c bsearch_r.c:33 | |
88 | +@deftypefn Supplemental void* bsearch_r (const void *@var{key}, @ | |
89 | + const void *@var{base}, size_t @var{nmemb}, size_t @var{size}, @ | |
90 | + int (*@var{compar})(const void *, const void *, void *), void *@var{arg}) | |
91 | + | |
92 | +Performs a search over an array of @var{nmemb} elements pointed to by | |
93 | +@var{base} for a member that matches the object pointed to by @var{key}. | |
94 | +The size of each member is specified by @var{size}. The array contents | |
95 | +should be sorted in ascending order according to the @var{compar} | |
96 | +comparison function. This routine should take three arguments: the first | |
97 | +two point to the @var{key} and to an array member, and the last is passed | |
98 | +down unchanged from @code{bsearch_r}'s last argument. It should return an | |
99 | +integer less than, equal to, or greater than zero if the @var{key} object | |
100 | +is respectively less than, matching, or greater than the array member. | |
101 | + | |
102 | +@end deftypefn | |
103 | + | |
87 | 104 | @c argv.c:138 |
88 | 105 | @deftypefn Extension char** buildargv (char *@var{sp}) |
89 | 106 |
@@ -175,7 +192,7 @@ Concatenate zero or more of strings and return the result in freshly | ||
175 | 192 | |
176 | 193 | @end deftypefn |
177 | 194 | |
178 | -@c argv.c:487 | |
195 | +@c argv.c:495 | |
179 | 196 | @deftypefn Extension int countargv (char * const *@var{argv}) |
180 | 197 | |
181 | 198 | Return the number of elements in @var{argv}. |
@@ -240,7 +257,7 @@ symbolic name or message. | ||
240 | 257 | |
241 | 258 | @end deftypefn |
242 | 259 | |
243 | -@c argv.c:344 | |
260 | +@c argv.c:352 | |
244 | 261 | @deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp}) |
245 | 262 | |
246 | 263 | The @var{argcp} and @code{argvp} arguments are pointers to the usual |
@@ -462,6 +462,10 @@ _D8demangle4testFDFNiZaZv | ||
462 | 462 | demangle.test(char() @nogc delegate) |
463 | 463 | # |
464 | 464 | --format=dlang |
465 | +_D8demangle4testFDFNmZaZv | |
466 | +demangle.test(char() @live delegate) | |
467 | +# | |
468 | +--format=dlang | |
465 | 469 | _D8demangle4testFDFNaNbZaZv |
466 | 470 | demangle.test(char() pure nothrow delegate) |
467 | 471 | # |
@@ -538,6 +542,10 @@ _D8demangle4testFPFNiZaZv | ||
538 | 542 | demangle.test(char() @nogc function) |
539 | 543 | # |
540 | 544 | --format=dlang |
545 | +_D8demangle4testFPFNmZaZv | |
546 | +demangle.test(char() @live function) | |
547 | +# | |
548 | +--format=dlang | |
541 | 549 | _D8demangle4testFPFNaNbZaZv |
542 | 550 | demangle.test(char() pure nothrow function) |
543 | 551 | # |
@@ -1326,3 +1334,75 @@ _D1_B699999999961* | ||
1326 | 1334 | --format=dlang |
1327 | 1335 | _D5__T1fVHacA6666666666_ |
1328 | 1336 | _D5__T1fVHacA6666666666_ |
1337 | +# | |
1338 | +--format=dlang | |
1339 | +_D3std5range15__T4iotaTtTtTtZ4iotaFtttZ6Result7opIndexMNgFNaNbNiNfmZNgt | |
1340 | +std.range.iota!(ushort, ushort, ushort).iota(ushort, ushort, ushort).Result.opIndex(ulong) inout | |
1341 | +# | |
1342 | +--format=dlang | |
1343 | +_D3std6format77__T6getNthVAyaa13_696e7465676572207769647468S233std6traits10isIntegralTiTkTkZ6getNthFNaNfkkkZi | |
1344 | +std.format.getNth!("integer width", std.traits.isIntegral, int, uint, uint).getNth(uint, uint, uint) | |
1345 | +# | |
1346 | +--format=dlang | |
1347 | +_D3std11parallelism42__T16RoundRobinBufferTDFKAaZvTDxFNaNdNeZbZ16RoundRobinBuffer5primeMFZv | |
1348 | +std.parallelism.RoundRobinBuffer!(void(ref char[]) delegate, bool() pure @property @trusted delegate const).RoundRobinBuffer.prime() | |
1349 | +# | |
1350 | +--format=dlang | |
1351 | +_D4core4stdc5errnoQgFZi | |
1352 | +core.stdc.errno.errno() | |
1353 | +# | |
1354 | +--format=dlang | |
1355 | +_D4testFS10structnameQnZb | |
1356 | +test(structname, structname) | |
1357 | +# | |
1358 | +--format=dlang | |
1359 | +_D3std11parallelism__T4TaskS8unittest3cmpTAyaTQeZQBb6__dtorMFNfZv | |
1360 | +std.parallelism.Task!(unittest.cmp, immutable(char)[], immutable(char)[]).Task.~this() | |
1361 | +# | |
1362 | +--format=dlang | |
1363 | +_D13testexpansion44__T1sTS13testexpansion8__T1sTiZ1sFiZ6ResultZ1sFS13testexpansion8__T1sTiZ1sFiZ6ResultZ6Result3fooMFNaNfZv | |
1364 | +testexpansion.s!(testexpansion.s!(int).s(int).Result).s(testexpansion.s!(int).s(int).Result).Result.foo() | |
1365 | +# | |
1366 | +--format=dlang | |
1367 | +_D13testexpansion__T1sTSQw__TQjTiZQoFiZ6ResultZQBbFQBcZQq3fooMFNaNfZv | |
1368 | +testexpansion.s!(testexpansion.s!(int).s(int).Result).s(testexpansion.s!(int).s(int).Result).Result.foo() | |
1369 | +# | |
1370 | +--format=dlang | |
1371 | +_D3std4conv__T7enumRepTyAaTEQBa12experimental9allocator15building_blocks15stats_collector7OptionsVQCti64ZQDnyQDh | |
1372 | +std.conv.enumRep!(immutable(char[]), std.experimental.allocator.building_blocks.stats_collector.Options, 64).enumRep | |
1373 | +# | |
1374 | +--format=dlang | |
1375 | +_D3std12experimental9allocator6common__T10reallocateTSQCaQBzQBo15building_blocks17kernighan_ritchie__T8KRRegionTSQEhQEgQDvQCh14null_allocator13NullAllocatorZQCdZQErFNaNbNiKQEpKAvmZb | |
1376 | +std.experimental.allocator.common.reallocate!(std.experimental.allocator.building_blocks.kernighan_ritchie.KRRegion!(std.experimental.allocator.building_blocks.null_allocator.NullAllocator).KRRegion).reallocate(ref std.experimental.allocator.building_blocks.kernighan_ritchie.KRRegion!(std.experimental.allocator.building_blocks.null_allocator.NullAllocator).KRRegion, ref void[], ulong) | |
1377 | +# | |
1378 | +--format=dlang | |
1379 | +_D3std9exception__T11doesPointToTASQBh5regex8internal2ir10NamedGroupTQBkTvZQCeFNaNbNiNeKxASQDlQCeQCbQBvQBvKxQtZb | |
1380 | +std.exception.doesPointTo!(std.regex.internal.ir.NamedGroup[], std.regex.internal.ir.NamedGroup[], void).doesPointTo(ref const(std.regex.internal.ir.NamedGroup[]), ref const(std.regex.internal.ir.NamedGroup[])) | |
1381 | +# | |
1382 | +--format=dlang | |
1383 | +_D3std9algorithm9iteration__T14SplitterResultS_DQBu3uni7isWhiteFNaNbNiNfwZbTAyaZQBz9__xtoHashFNbNeKxSQDvQDuQDn__TQDgS_DQEnQCtQCsQCnTQCeZQEdZm | |
1384 | +std.algorithm.iteration.SplitterResult!(std.uni.isWhite(dchar), immutable(char)[]).SplitterResult.__xtoHash(ref const(std.algorithm.iteration.SplitterResult!(std.uni.isWhite, immutable(char)[]).SplitterResult)) | |
1385 | +# | |
1386 | +--format=dlang | |
1387 | +_D3std8typecons__T7TypedefTCQBaQz19__unittestL6513_208FNfZ7MyClassVQBonVAyanZQCh6__ctorMFNaNbNcNiNfQCuZSQDyQDx__TQDrTQDmVQDqnVQCcnZQEj | |
1388 | +std.typecons.Typedef!(std.typecons.__unittestL6513_208().MyClass, null, null).Typedef.this(std.typecons.__unittestL6513_208().MyClass) | |
1389 | +# | |
1390 | +--format=dlang | |
1391 | +_D3std6getopt__TQkTAyaTDFNaNbNiNfQoZvTQtTDQsZQBnFNfKAQBiQBlQBkQBrQyZSQCpQCo12GetoptResult | |
1392 | +std.getopt.getopt!(immutable(char)[], void(immutable(char)[]) pure nothrow @nogc @safe delegate, immutable(char)[], void(immutable(char)[]) pure nothrow @nogc @safe delegate).getopt(ref immutable(char)[][], immutable(char)[], void(immutable(char)[]) pure nothrow @nogc @safe delegate, immutable(char)[], void(immutable(char)[]) pure nothrow @nogc @safe delegate) | |
1393 | +# | |
1394 | +--format=dlang | |
1395 | +_D3std5regex8internal9kickstart__T7ShiftOrTaZQl11ShiftThread__T3setS_DQCqQCpQCmQCg__TQBzTaZQCfQBv10setInvMaskMFNaNbNiNfkkZvZQCjMFNaNfwZv | |
1396 | +std.regex.internal.kickstart.ShiftOr!(char).ShiftOr.ShiftThread.set!(std.regex.internal.kickstart.ShiftOr!(char).ShiftOr.ShiftThread.setInvMask(uint, uint)).set(dchar) | |
1397 | +# | |
1398 | +--format=dlang | |
1399 | +_D3std5stdio4File__T8lockImplX10LockFileExTykZQBaMFmmykZi | |
1400 | +std.stdio.File.lockImpl!(LockFileEx, immutable(uint)).lockImpl(ulong, ulong, immutable(uint)) | |
1401 | +# | |
1402 | +--format=dlang | |
1403 | +_D3std9algorithm9iteration__T12FilterResultSQBq8typecons__T5TupleTiVAyaa1_61TiVQla1_62TiVQva1_63ZQBm__T6renameVHiQBtA2i0a1_63i2a1_61ZQBeMFNcZ9__lambda1TAiZQEw9__xtoHashFNbNeKxSQGsQGrQGk__TQGdSQHiQFs__TQFmTiVQFja1_61TiVQFua1_62TiVQGfa1_63ZQGx__TQFlVQFhA2i0a1_63i2a1_61ZQGjMFNcZQFfTQEyZQJvZm | |
1404 | +std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", int, "c").Tuple.rename!([0:"c", 2:"a"]).rename().__lambda1, int[]).FilterResult.__xtoHash(ref const(std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", int, "c").Tuple.rename!([0:"c", 2:"a"]).rename().__lambda1, int[]).FilterResult)) | |
1405 | +# | |
1406 | +--format=dlang | |
1407 | +_D3std3uni__T6toCaseS_DQvQt12toLowerIndexFNaNbNiNewZtVii1043S_DQCjQCi10toLowerTabFNaNbNiNemZwSQDo5ascii7toLowerTAyaZQDzFNaNeQmZ14__foreachbody2MFNaNeKmKwZ14__foreachbody3MFNaNeKwZi | |
1408 | +std.uni.toCase!(std.uni.toLowerIndex(dchar), 1043, std.uni.toLowerTab(ulong), std.ascii.toLower, immutable(char)[]).toCase(immutable(char)[]).__foreachbody2(ref ulong, ref dchar).__foreachbody3(ref dchar) |