diff options
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/cp-demangle.c | 260 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 53 |
2 files changed, 289 insertions, 24 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 8413dcd..ad533f6 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -347,9 +347,9 @@ struct d_print_info /* Number of times d_print_comp was recursively called. Should not be bigger than MAX_RECURSION_COUNT. */ int recursion; - /* Non-zero if we're printing a lambda argument. A template - parameter reference actually means 'auto', a pack expansion means T... */ - int is_lambda_arg; + /* 1 more than the number of explicit template parms of a lambda. Template + parm references >= are actually 'auto'. */ + int lambda_tpl_parms; /* The current index into any template argument packs we are using for printing, or -1 to print the whole pack. */ int pack_index; @@ -491,6 +491,10 @@ static struct demangle_component *d_local_name (struct d_info *); static int d_discriminator (struct d_info *); +static struct demangle_component *d_template_parm (struct d_info *, int *bad); + +static struct demangle_component *d_template_head (struct d_info *, int *bad); + static struct demangle_component *d_lambda (struct d_info *); static struct demangle_component *d_unnamed_type (struct d_info *); @@ -1028,6 +1032,10 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_TPARM_OBJ: case DEMANGLE_COMPONENT_STRUCTURED_BINDING: case DEMANGLE_COMPONENT_MODULE_INIT: + case DEMANGLE_COMPONENT_TEMPLATE_HEAD: + case DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM: + case DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM: + case DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM: if (left == NULL) return NULL; break; @@ -1050,6 +1058,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_CONST: case DEMANGLE_COMPONENT_ARGLIST: case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: + case DEMANGLE_COMPONENT_TEMPLATE_TYPE_PARM: FNQUAL_COMPONENT_CASE: break; @@ -3877,32 +3886,120 @@ d_discriminator (struct d_info *di) return 1; } -/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */ +/* <template-parm> ::= Ty + ::= Tn <type> + ::= Tt <template-head> E + ::= Tp <template-parm> */ static struct demangle_component * -d_lambda (struct d_info *di) +d_template_parm (struct d_info *di, int *bad) { - struct demangle_component *tl; - struct demangle_component *ret; - int num; + if (d_peek_char (di) != 'T') + return NULL; + + struct demangle_component *op; + enum demangle_component_type kind; + switch (d_peek_next_char (di)) + { + default: + return NULL; + + case 'p': /* Pack */ + d_advance (di, 2); + op = d_template_parm (di, bad); + kind = DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM; + if (!op) + { + *bad = 1; + return NULL; + } + break; + + case 'y': /* Typename */ + d_advance (di, 2); + op = NULL; + kind = DEMANGLE_COMPONENT_TEMPLATE_TYPE_PARM; + break; + + case 'n': /* Non-Type */ + d_advance (di, 2); + op = cplus_demangle_type (di); + kind = DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM; + if (!op) + { + *bad = 1; + return NULL; + } + break; + + case 't': /* Template */ + d_advance (di, 2); + op = d_template_head (di, bad); + kind = DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM; + if (!op || !d_check_char (di, 'E')) + { + *bad = 1; + return NULL; + } + } + + return d_make_comp (di, kind, op, NULL); +} + +/* <template-head> ::= <template-head>? <template-parm> */ + +static struct demangle_component * +d_template_head (struct d_info *di, int *bad) +{ + struct demangle_component *res = NULL, **slot = &res; + struct demangle_component *op; + + while ((op = d_template_parm (di, bad))) + { + *slot = op; + slot = &d_right (op); + } + + /* Wrap it in a template head, to make concatenating with any parm list, and + printing simpler. */ + if (res) + res = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_HEAD, res, NULL); + return res; +} + +/* <closure-type-name> ::= Ul <template-head>? <lambda-sig> E [ <nonnegative number> ] _ */ + +static struct demangle_component * +d_lambda (struct d_info *di) +{ if (! d_check_char (di, 'U')) return NULL; if (! d_check_char (di, 'l')) return NULL; - tl = d_parmlist (di); + int bad = 0; + struct demangle_component *head = d_template_head (di, &bad); + if (bad) + return NULL; + + struct demangle_component *tl = d_parmlist (di); if (tl == NULL) return NULL; + if (head) + { + d_right (head) = tl; + tl = head; + } if (! d_check_char (di, 'E')) return NULL; - num = d_compact_number (di); + int num = d_compact_number (di); if (num < 0) return NULL; - ret = d_make_empty (di); + struct demangle_component *ret = d_make_empty (di); if (ret) { ret->type = DEMANGLE_COMPONENT_LAMBDA; @@ -4254,6 +4351,11 @@ d_count_templates_scopes (struct d_print_info *dpi, case DEMANGLE_COMPONENT_MODULE_PARTITION: case DEMANGLE_COMPONENT_MODULE_INIT: case DEMANGLE_COMPONENT_FIXED_TYPE: + case DEMANGLE_COMPONENT_TEMPLATE_HEAD: + case DEMANGLE_COMPONENT_TEMPLATE_TYPE_PARM: + case DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM: + case DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM: + case DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM: break; case DEMANGLE_COMPONENT_TEMPLATE: @@ -4384,7 +4486,7 @@ d_print_init (struct d_print_info *dpi, demangle_callbackref callback, dpi->demangle_failure = 0; dpi->recursion = 0; - dpi->is_lambda_arg = 0; + dpi->lambda_tpl_parms = 0; dpi->component_stack = NULL; @@ -4881,6 +4983,33 @@ d_maybe_print_designated_init (struct d_print_info *dpi, int options, return 1; } +static void +d_print_lambda_parm_name (struct d_print_info *dpi, int type, unsigned index) +{ + const char *str; + switch (type) + { + default: + dpi->demangle_failure = 1; + str = ""; + break; + + case DEMANGLE_COMPONENT_TEMPLATE_TYPE_PARM: + str = "$T"; + break; + + case DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM: + str = "$N"; + break; + + case DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM: + str = "$TT"; + break; + } + d_append_string (dpi, str); + d_append_num (dpi, index); +} + /* Subroutine to handle components. */ static void @@ -5135,7 +5264,21 @@ d_print_comp_inner (struct d_print_info *dpi, int options, } case DEMANGLE_COMPONENT_TEMPLATE_PARAM: - if (dpi->is_lambda_arg) + if (dpi->lambda_tpl_parms > dc->u.s_number.number + 1) + { + const struct demangle_component *a + = d_left (dpi->templates->template_decl); + unsigned c; + for (c = dc->u.s_number.number; a && c; c--) + a = d_right (a); + if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM) + a = d_left (a); + if (!a) + dpi->demangle_failure = 1; + else + d_print_lambda_parm_name (dpi, a->type, dc->u.s_number.number); + } + else if (dpi->lambda_tpl_parms) { /* Show the template parm index, as that's how g++ displays these, and future proofs us against potential @@ -5316,7 +5459,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options, { /* Handle reference smashing: & + && = &. */ struct demangle_component *sub = d_left (dc); - if (!dpi->is_lambda_arg + if (!dpi->lambda_tpl_parms && sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM) { struct d_saved_scope *scope = d_get_saved_scope (dpi, sub); @@ -5942,7 +6085,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options, { struct demangle_component *a = NULL; - if (!dpi->is_lambda_arg) + if (!dpi->lambda_tpl_parms) a = d_find_pack (dpi, d_left (dc)); if (a == NULL) { @@ -5994,15 +6137,50 @@ d_print_comp_inner (struct d_print_info *dpi, int options, return; case DEMANGLE_COMPONENT_LAMBDA: - d_append_string (dpi, "{lambda("); - /* Generic lambda auto parms are mangled as the template type - parm they are. */ - dpi->is_lambda_arg++; - d_print_comp (dpi, options, dc->u.s_unary_num.sub); - dpi->is_lambda_arg--; - d_append_string (dpi, ")#"); - d_append_num (dpi, dc->u.s_unary_num.num + 1); - d_append_char (dpi, '}'); + { + d_append_string (dpi, "{lambda"); + struct demangle_component *parms = dc->u.s_unary_num.sub; + struct d_print_template dpt; + /* Generic lambda auto parms are mangled as the (synthedic) template + type parm they are. We need to tell the printer that (a) we're in + a lambda, and (b) the number of synthetic parms. */ + int saved_tpl_parms = dpi->lambda_tpl_parms; + dpi->lambda_tpl_parms = 0; + /* Hang any lambda head as-if template args. */ + dpt.template_decl = NULL; + dpt.next = dpi->templates; + dpi->templates = &dpt; + if (parms && parms->type == DEMANGLE_COMPONENT_TEMPLATE_HEAD) + { + dpt.template_decl = parms; + + d_append_char (dpi, '<'); + struct demangle_component *parm; + for (parm = d_left (parms); parm; parm = d_right (parm)) + { + if (dpi->lambda_tpl_parms++) + d_append_string (dpi, ", "); + d_print_comp (dpi, options, parm); + d_append_char (dpi, ' '); + if (parm->type == DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM) + parm = d_left (parm); + d_print_lambda_parm_name (dpi, parm->type, + dpi->lambda_tpl_parms - 1); + } + d_append_char (dpi, '>'); + + parms = d_right (parms); + } + dpi->lambda_tpl_parms++; + + d_append_char (dpi, '('); + d_print_comp (dpi, options, parms); + dpi->lambda_tpl_parms = saved_tpl_parms; + dpi->templates = dpt.next; + 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: @@ -6018,6 +6196,40 @@ d_print_comp_inner (struct d_print_info *dpi, int options, d_append_char (dpi, ']'); return; + case DEMANGLE_COMPONENT_TEMPLATE_HEAD: + { + d_append_char (dpi, '<'); + int count = 0; + struct demangle_component *parm; + for (parm = d_left (dc); parm; parm = d_right (parm)) + { + if (count++) + d_append_string (dpi, ", "); + d_print_comp (dpi, options, parm); + } + d_append_char (dpi, '>'); + } + return; + + case DEMANGLE_COMPONENT_TEMPLATE_TYPE_PARM: + d_append_string (dpi, "typename"); + return; + + case DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM: + d_print_comp (dpi, options, d_left (dc)); + return; + + case DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM: + d_append_string (dpi, "template"); + d_print_comp (dpi, options, d_left (dc)); + d_append_string (dpi, " class"); + return; + + case DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM: + d_print_comp (dpi, options, d_left (dc)); + d_append_string (dpi, "..."); + return; + default: d_print_error (dpi); return; diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index ee8fdfd..d9bc7ed 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -1606,3 +1606,56 @@ int foo<q::{lambda()#1}, q::{lambda()#2}>(q::{lambda()#1}&&, q::{lambda()#2}&&) _ZNK2L1MUlDpT_E_clIJiPiEEEvS1_ void L1::{lambda((auto:1)...)#1}::operator()<int, int*>(int, int*) const +_ZZN1XIfLj0EE2FnEvENKUlTyfT_E_clIiEEDafS1_ +auto X<float, 0u>::Fn()::{lambda<typename $T0>(float, $T0)#1}::operator()<int>(float, int) const + +_ZZN1XIfLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_ +auto X<float, 0u>::Fn()::{lambda<typename $T0>($T0)#1}::operator()<int>(int) const + +_ZZN1XIfLj1EE2FnEvENKUlTyfT_E_clIiEEDafS1_ +auto X<float, 1u>::Fn()::{lambda<typename $T0>(float, $T0)#1}::operator()<int>(float, int) const + +_ZZN1XIfLj1EE2FnEvENKUlTyT_E_clIiEEDaS1_ +auto X<float, 1u>::Fn()::{lambda<typename $T0>($T0)#1}::operator()<int>(int) const + +_ZZN1XIiLj0EE2FnEvENKUlTyiT_E_clIiEEDaiS1_ +auto X<int, 0u>::Fn()::{lambda<typename $T0>(int, $T0)#1}::operator()<int>(int, int) const + +_ZZN1XIiLj0EE2FnEvENKUlTyT_E_clIiEEDaS1_ +auto X<int, 0u>::Fn()::{lambda<typename $T0>($T0)#1}::operator()<int>(int) const + +_ZNK10l_tpl_autoMUlTyT_T0_E_clIiiEEDaS0_S1_ +auto l_tpl_auto::{lambda<typename $T0>($T0, auto:2)#1}::operator()<int, int>(int, int) const + +_ZNK12l_tpl_nt_aryMUlTniRAT__iE_clILi2EEEDaS1_ +auto l_tpl_nt_ary::{lambda<int $N0>(int (&) [$N0])#1}::operator()<2>(int (&) [2]) const + +_ZNK13l_tpl_nt_autoMUlTnDavE_clILi0EEEDav +auto l_tpl_nt_auto::{lambda<auto $N0>()#1}::operator()<0>() const + +_ZNK9l_tpl_tplMUlTtTyTnjER3TPLIT_EE_clI1UEEDaS3_ +auto l_tpl_tpl::{lambda<template<typename, unsigned int> class $TT0>(TPL<$TT0>&)#1}::operator()<U>(TPL<U>&) const + +_ZNK13l_tpl_tpl_tplMUlTtTtTyTnjEER6TPLTPLIT_EE_clI3TPLEEDaS3_ +auto l_tpl_tpl_tpl::{lambda<template<template<typename, unsigned int> class> class $TT0>(TPLTPL<$TT0>&)#1}::operator()<TPL>(TPLTPL<TPL>&) const + +_ZNK5l_varMUlTpTyDpT_E_clIJiiiEEEDaS1_ +auto l_var::{lambda<typename... $T0>(($T0)...)#1}::operator()<int, int, int>(int, int, int) const + +_ZNK6l_var2MUlTpTniDpRAT__iE_clIJLi2ELi2EEEEDaS2_ +auto l_var2::{lambda<int... $N0>((int (&) [$N0])...)#1}::operator()<2, 2>(int (&) [2], int (&) [2]) const + +_ZNK6l_var3MUlTtTpTniETpTniRT_IJXspT0_EEEE_clI1XJLi1ELi2ELi3EEEEDaS2_ +auto l_var3::{lambda<template<int...> class $TT0, int... $N1>($TT0<($N1)...>&)#1}::operator()<X, 1, 2, 3>(X<1, 2, 3>&) const + +_ZNK6l_var4MUlTpTtTyTnjER1YIJDpT_EEE_clIJ1US7_EEEDaS4_ +auto l_var4::{lambda<template<typename, unsigned int> class... $TT0>(Y<($TT0)...>&)#1}::operator()<U, U>(Y<U, U>&) const + +_ZZ2FnILi1EEvvENKUlTyT_E_clIiEEDaS0_ +auto Fn<1>()::{lambda<typename $T0>($T0)#1}::operator()<int>(int) const + +_ZZ1fvENKUlTyP1XIT_EPS_IiEE_clIcEEDaS2_S4_ +auto f()::{lambda<typename $T0>(X<$T0>*, X<int>*)#1}::operator()<char>(X<char>*, X<int>*) const + +_ZZN1XIiE1FEvENKUliE_clEi +X<int>::F()::{lambda(int)#1}::operator()(int) const |