diff options
author | Jason Merrill <jason@gcc.gnu.org> | 2009-09-29 23:01:30 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-09-29 23:01:30 -0400 |
commit | d5f4edddeb609ad93c7a69ad4575b082de8dc707 (patch) | |
tree | a0717adf99d475ef98d9002044972a7ab9c3e5d6 /libiberty | |
parent | 300ea2831b894fc143539fe0319f39062b6e4daf (diff) | |
download | gcc-d5f4edddeb609ad93c7a69ad4575b082de8dc707.zip gcc-d5f4edddeb609ad93c7a69ad4575b082de8dc707.tar.gz gcc-d5f4edddeb609ad93c7a69ad4575b082de8dc707.tar.bz2 |
merge in cxx0x-lambdas-branch@152308
From-SVN: r152318
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 11 | ||||
-rw-r--r-- | libiberty/Makefile.in | 6 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 299 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 26 |
4 files changed, 274 insertions, 68 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index dd1c1a3..03a8479 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,14 @@ +2009-09-29 Jason Merrill <jason@redhat.com> + + * Makefile.in: Enable demangle target. + * cp-demangle.c (d_lambda, d_unnamed_type, d_make_default_arg): New. + (d_name, d_prefix, d_unqualified_name, d_local_name): Handle lambdas. + (d_parmlist): Factor out from d_bare_function_type. + (d_compact_number): Factor out from d_template_param and d_expression. + (d_append_num): Factor out from d_print_comp. + (d_print_comp, d_print_mod_list): Handle lambdas. + * testsuite/demangle-expected: Add lambda tests. + 2009-09-23 Matthew Gingell <gingell@adacore.com> * cplus-dem.c (ada_demangle): Ensure demangled is freed. diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 5d2adff..ba24c6d 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -371,10 +371,12 @@ TAGS: $(CFILES) etags `for i in $(CFILES); do echo $(srcdir)/$$i ; done` # The standalone demangler (c++filt) has been moved to binutils. -demangle: +# But make this target work anyway for demangler hacking. +demangle: $(ALL) $(srcdir)/cp-demangle.c @echo "The standalone demangler, now named c++filt, is now" @echo "a part of binutils." - @false + $(CC) @DEFS@ $(CFLAGS) $(CPPFLAGS) -I. -I$(INCDIR) $(HDEFINES) \ + $(srcdir)/cp-demangle.c -DSTANDALONE_DEMANGLER $(TARGETLIB) -o $@ ls: @echo Makefile $(CFILES) diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 2c7296f..43cf34a 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -408,6 +408,10 @@ static struct demangle_component *d_local_name (struct d_info *); static int d_discriminator (struct d_info *); +static struct demangle_component *d_lambda (struct d_info *); + +static struct demangle_component *d_unnamed_type (struct d_info *); + static int d_add_substitution (struct d_info *, struct demangle_component *); @@ -922,6 +926,20 @@ d_make_extended_operator (struct d_info *di, int args, return p; } +static struct demangle_component * +d_make_default_arg (struct d_info *di, int num, + struct demangle_component *sub) +{ + struct demangle_component *p = d_make_empty (di); + if (p) + { + p->type = DEMANGLE_COMPONENT_DEFAULT_ARG; + p->u.s_unary_num.num = num; + p->u.s_unary_num.sub = sub; + } + return p; +} + /* Add a new constructor component. */ static struct demangle_component * @@ -1153,8 +1171,9 @@ d_name (struct d_info *di) return d_local_name (di); case 'L': + case 'U': return d_unqualified_name (di); - + case 'S': { int subst; @@ -1276,6 +1295,7 @@ d_prefix (struct d_info *di) || IS_LOWER (peek) || peek == 'C' || peek == 'D' + || peek == 'U' || peek == 'L') dc = d_unqualified_name (di); else if (peek == 'S') @@ -1291,6 +1311,16 @@ d_prefix (struct d_info *di) dc = d_template_param (di); else if (peek == 'E') return ret; + else if (peek == 'M') + { + /* Initializer scope for a lambda. We don't need to represent + this; the normal code will just treat the variable as a type + scope, which gives appropriate output. */ + if (ret == NULL) + return NULL; + d_advance (di, 1); + continue; + } else return NULL; @@ -1347,6 +1377,18 @@ d_unqualified_name (struct d_info *di) return NULL; return ret; } + else if (peek == 'U') + { + switch (d_peek_next_char (di)) + { + case 'l': + return d_lambda (di); + case 't': + return d_unnamed_type (di); + default: + return NULL; + } + } else return NULL; } @@ -2242,50 +2284,30 @@ d_function_type (struct d_info *di) return ret; } -/* <bare-function-type> ::= [J]<type>+ */ +/* <type>+ */ static struct demangle_component * -d_bare_function_type (struct d_info *di, int has_return_type) +d_parmlist (struct d_info *di) { - struct demangle_component *return_type; struct demangle_component *tl; struct demangle_component **ptl; - char peek; - /* Detect special qualifier indicating that the first argument - is the return type. */ - peek = d_peek_char (di); - if (peek == 'J') - { - d_advance (di, 1); - has_return_type = 1; - } - - return_type = NULL; tl = NULL; ptl = &tl; while (1) { struct demangle_component *type; - peek = d_peek_char (di); + char peek = d_peek_char (di); if (peek == '\0' || peek == 'E') break; type = cplus_demangle_type (di); if (type == NULL) return NULL; - if (has_return_type) - { - return_type = type; - has_return_type = 0; - } - else - { - *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL); - if (*ptl == NULL) - return NULL; - ptl = &d_right (*ptl); - } + *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL); + if (*ptl == NULL) + return NULL; + ptl = &d_right (*ptl); } /* There should be at least one parameter type besides the optional @@ -2300,10 +2322,45 @@ d_bare_function_type (struct d_info *di, int has_return_type) && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID) { di->expansion -= d_left (tl)->u.s_builtin.type->len; - tl = NULL; + d_left (tl) = NULL; } - return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type, tl); + return tl; +} + +/* <bare-function-type> ::= [J]<type>+ */ + +static struct demangle_component * +d_bare_function_type (struct d_info *di, int has_return_type) +{ + struct demangle_component *return_type; + struct demangle_component *tl; + char peek; + + /* Detect special qualifier indicating that the first argument + is the return type. */ + peek = d_peek_char (di); + if (peek == 'J') + { + d_advance (di, 1); + has_return_type = 1; + } + + if (has_return_type) + { + return_type = cplus_demangle_type (di); + if (return_type == NULL) + return NULL; + } + else + return_type = NULL; + + tl = d_parmlist (di); + if (tl == NULL) + return NULL; + + return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, + return_type, tl); } /* <class-enum-type> ::= <name> */ @@ -2405,6 +2462,24 @@ d_pointer_to_member_type (struct d_info *di) return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem); } +/* <non-negative number> _ */ + +static long +d_compact_number (struct d_info *di) +{ + long num; + if (d_peek_char (di) == '_') + num = 0; + else if (d_peek_char (di) == 'n') + return -1; + else + num = d_number (di) + 1; + + if (! d_check_char (di, '_')) + return -1; + return num; +} + /* <template-param> ::= T_ ::= T <(parameter-2 non-negative) number> _ */ @@ -2417,17 +2492,8 @@ d_template_param (struct d_info *di) if (! d_check_char (di, 'T')) return NULL; - if (d_peek_char (di) == '_') - param = 0; - else - { - param = d_number (di); - if (param < 0) - return NULL; - param += 1; - } - - if (! d_check_char (di, '_')) + param = d_compact_number (di); + if (param < 0) return NULL; ++di->did_subs; @@ -2599,17 +2665,8 @@ d_expression (struct d_info *di) /* Function parameter used in a late-specified return type. */ int index; d_advance (di, 2); - if (d_peek_char (di) == '_') - index = 1; - else - { - index = d_number (di); - if (index < 0) - return NULL; - index += 2; - } - - if (! d_check_char (di, '_')) + index = d_compact_number (di); + if (index < 0) return NULL; return d_make_function_param (di, index); @@ -2802,10 +2859,31 @@ d_local_name (struct d_info *di) else { struct demangle_component *name; + int num = -1; + + if (d_peek_char (di) == 'd') + { + /* Default argument scope: d <number> _. */ + d_advance (di, 1); + num = d_compact_number (di); + if (num < 0) + return NULL; + } name = d_name (di); - if (! d_discriminator (di)) - return NULL; + if (name) + switch (name->type) + { + /* Lambdas and unnamed types have internal discriminators. */ + case DEMANGLE_COMPONENT_LAMBDA: + case DEMANGLE_COMPONENT_UNNAMED_TYPE: + break; + default: + if (! d_discriminator (di)) + return NULL; + } + if (num >= 0) + name = d_make_default_arg (di, num, name); return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name); } } @@ -2829,6 +2907,75 @@ d_discriminator (struct d_info *di) return 1; } +/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */ + +static struct demangle_component * +d_lambda (struct d_info *di) +{ + struct demangle_component *tl; + struct demangle_component *ret; + int num; + + if (! d_check_char (di, 'U')) + return NULL; + if (! d_check_char (di, 'l')) + return NULL; + + tl = d_parmlist (di); + if (tl == NULL) + return NULL; + + if (! d_check_char (di, 'E')) + return NULL; + + num = d_compact_number (di); + if (num < 0) + return NULL; + + ret = d_make_empty (di); + if (ret) + { + ret->type = DEMANGLE_COMPONENT_LAMBDA; + ret->u.s_unary_num.sub = tl; + ret->u.s_unary_num.num = num; + } + + if (! d_add_substitution (di, ret)) + return NULL; + + return ret; +} + +/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */ + +static struct demangle_component * +d_unnamed_type (struct d_info *di) +{ + struct demangle_component *ret; + long num; + + if (! d_check_char (di, 'U')) + return NULL; + if (! d_check_char (di, 't')) + return NULL; + + num = d_compact_number (di); + if (num < 0) + return NULL; + + ret = d_make_empty (di); + if (ret) + { + ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE; + ret->u.s_number.number = num; + } + + if (! d_add_substitution (di, ret)) + return NULL; + + return ret; +} + /* Add a new substitution. */ static int @@ -3122,6 +3269,14 @@ d_append_string (struct d_print_info *dpi, const char *s) d_append_buffer (dpi, s, strlen (s)); } +static inline void +d_append_num (struct d_print_info *dpi, long l) +{ + char buf[25]; + sprintf (buf,"%ld", l); + d_append_string (dpi, buf); +} + static inline char d_last_char (struct d_print_info *dpi) { @@ -3398,6 +3553,8 @@ d_print_comp (struct d_print_info *dpi, struct demangle_component *local_name; local_name = d_right (typed_name); + if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG) + local_name = local_name->u.s_unary_num.sub; while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS || local_name->type == DEMANGLE_COMPONENT_CONST_THIS) @@ -4048,13 +4205,10 @@ d_print_comp (struct d_print_info *dpi, return; case DEMANGLE_COMPONENT_FUNCTION_PARAM: - { - char buf[25]; - d_append_string (dpi, "parm#"); - sprintf(buf,"%ld", dc->u.s_number.number); - d_append_string (dpi, buf); - return; - } + d_append_string (dpi, "{parm#"); + d_append_num (dpi, dc->u.s_number.number + 1); + d_append_char (dpi, '}'); + return; case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: d_append_string (dpi, "global constructors keyed to "); @@ -4066,6 +4220,20 @@ d_print_comp (struct d_print_info *dpi, d_print_comp (dpi, dc->u.s_binary.left); return; + case DEMANGLE_COMPONENT_LAMBDA: + d_append_string (dpi, "{lambda("); + d_print_comp (dpi, dc->u.s_unary_num.sub); + d_append_string (dpi, ")#"); + d_append_num (dpi, dc->u.s_unary_num.num + 1); + d_append_char (dpi, '}'); + return; + + case DEMANGLE_COMPONENT_UNNAMED_TYPE: + d_append_string (dpi, "{unnamed type#"); + d_append_num (dpi, dc->u.s_number.number + 1); + d_append_char (dpi, '}'); + return; + default: d_print_error (dpi); return; @@ -4184,6 +4352,15 @@ d_print_mod_list (struct d_print_info *dpi, d_append_char (dpi, '.'); dc = d_right (mods->mod); + + if (dc->type == DEMANGLE_COMPONENT_DEFAULT_ARG) + { + d_append_string (dpi, "{default arg#"); + d_append_num (dpi, dc->u.s_unary_num.num + 1); + d_append_string (dpi, "}::"); + dc = dc->u.s_unary_num.sub; + } + while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS || dc->type == DEMANGLE_COMPONENT_CONST_THIS) diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 0c45118..6798154 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3885,11 +3885,11 @@ java resource java/util/iso4217.properties # decltype/param placeholder test --format=gnu-v3 _Z3addIidEDTplfp_fp0_ET_T0_ -decltype (parm#1+parm#2) add<int, double>(int, double) +decltype ({parm#1}+{parm#2}) add<int, double>(int, double) # decltype/fn call test --format=gnu-v3 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_ -decltype (g(parm#1, parm#2)) add3<int, double>(int, double) +decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double) # new (2008) built in types test --format=gnu-v3 _Z1fDfDdDeDhDsDi @@ -3901,12 +3901,28 @@ void f<int*, float*, double*>(int*, float*, double*) # '.' test --format=gnu-v3 _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_ -decltype ((parm#1.(g<double>))()) h<A<int>, double>(A<int>, double) +decltype (({parm#1}.(g<double>))()) h<A<int>, double>(A<int>, double) # test for typed function in decltype --format=gnu-v3 _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_ -decltype (parm#1+((x())())) A<int>::j<int>(int) +decltype ({parm#1}+((x())())) A<int>::j<int>(int) # test for expansion of function parameter pack --format=gnu-v3 _Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_ -decltype (f((parm#1+(1))...)) g<int, double>(int, double) +decltype (f(({parm#1}+(1))...)) g<int, double>(int, double) +# lambda tests +--format=gnu-v3 +_ZZ1giENKUlvE_clEv +g(int)::{lambda()#1}::operator()() const +--format=gnu-v3 +_Z4algoIZ1giEUlvE0_EiT_ +int algo<g(int)::{lambda()#2}>(g(int)::{lambda()#2}) +--format=gnu-v3 +_ZZN1S1fEiiEd0_NKUlvE0_clEv +S::f(int, int)::{default arg#2}::{lambda()#2}::operator()() const +--format=gnu-v3 +_ZNK1SIiE1xMUlvE1_clEv +S<int>::x::{lambda()#3}::operator()() const +--format=gnu-v3 +_Z1fN1SUt_E +f(S::{unnamed type#1}) |