From a4ddf8dc72f0ac10c3459a91949eb1bdb07ed10d Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 7 Nov 2016 23:09:29 +0000 Subject: [PATCH] Implement P0012R1, Make exception specifications part of the type system. libiberty/ * cp-demangle.c (is_fnqual_component_type): New. (d_encoding, d_print_comp_inner, d_print_mod_list): Use it. (FNQUAL_COMPONENT_CASE): New. (d_make_comp, has_return_type, d_print_comp_inner) (d_print_function_type): Use it. (next_is_type_qual): New. (d_cv_qualifiers, d_print_mod): Handle noexcept and throw-spec. include/ * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_NOEXCEPT, DEMANGLE_COMPONENT_THROW_SPEC. --- include/ChangeLog | 5 + include/demangle.h | 4 +- libiberty/ChangeLog | 10 ++ libiberty/cp-demangle.c | 181 ++++++++++++++++---------- libiberty/testsuite/demangle-expected | 10 ++ 5 files changed, 141 insertions(+), 69 deletions(-) diff --git a/include/ChangeLog b/include/ChangeLog index 8631956c141..96ddcc75695 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2016-11-07 Jason Merrill + + * demangle.h (enum demangle_component_type): Add + DEMANGLE_COMPONENT_NOEXCEPT, DEMANGLE_COMPONENT_THROW_SPEC. + 2016-11-18 Szabolcs Nagy * opcode/aarch64.h (enum aarch64_opnd): Add AARCH64_OPND_IMM_ROT1, diff --git a/include/demangle.h b/include/demangle.h index 3e1d95cc5a3..12f51cab358 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -449,7 +449,9 @@ enum demangle_component_type /* A transaction-safe function type. */ DEMANGLE_COMPONENT_TRANSACTION_SAFE, /* A cloned function. */ - DEMANGLE_COMPONENT_CLONE + DEMANGLE_COMPONENT_CLONE, + DEMANGLE_COMPONENT_NOEXCEPT, + DEMANGLE_COMPONENT_THROW_SPEC }; /* Types which are only used internally. */ diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 27c275b9e6c..e532460ccb2 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,13 @@ +2016-11-07 Jason Merrill + + * cp-demangle.c (is_fnqual_component_type): New. + (d_encoding, d_print_comp_inner, d_print_mod_list): Use it. + (FNQUAL_COMPONENT_CASE): New. + (d_make_comp, has_return_type, d_print_comp_inner) + (d_print_function_type): Use it. + (next_is_type_qual): New. + (d_cv_qualifiers, d_print_mod): Handle noexcept and throw-spec. + 2016-11-02 Mark Wielaard * cplus-dem.c (demangle_signature): Move fall through comment. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 46382ccee22..e239155c442 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -436,6 +436,8 @@ static struct demangle_component *d_operator_name (struct d_info *); static struct demangle_component *d_special_name (struct d_info *); +static struct demangle_component *d_parmlist (struct d_info *); + static int d_call_offset (struct d_info *, int); static struct demangle_component *d_ctor_dtor_name (struct d_info *); @@ -559,6 +561,32 @@ static int d_demangle_callback (const char *, int, demangle_callbackref, void *); static char *d_demangle (const char *, int, size_t *); +/* True iff TYPE is a demangling component representing a + function-type-qualifier. */ + +static int +is_fnqual_component_type (enum demangle_component_type type) +{ + return (type == DEMANGLE_COMPONENT_RESTRICT_THIS + || type == DEMANGLE_COMPONENT_VOLATILE_THIS + || type == DEMANGLE_COMPONENT_CONST_THIS + || type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS + || type == DEMANGLE_COMPONENT_TRANSACTION_SAFE + || type == DEMANGLE_COMPONENT_NOEXCEPT + || type == DEMANGLE_COMPONENT_THROW_SPEC + || type == DEMANGLE_COMPONENT_REFERENCE_THIS); +} + +#define FNQUAL_COMPONENT_CASE \ + case DEMANGLE_COMPONENT_RESTRICT_THIS: \ + case DEMANGLE_COMPONENT_VOLATILE_THIS: \ + case DEMANGLE_COMPONENT_CONST_THIS: \ + case DEMANGLE_COMPONENT_REFERENCE_THIS: \ + case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \ + case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \ + case DEMANGLE_COMPONENT_NOEXCEPT: \ + case DEMANGLE_COMPONENT_THROW_SPEC + #ifdef CP_DEMANGLE_DEBUG static void @@ -984,14 +1012,9 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_RESTRICT: case DEMANGLE_COMPONENT_VOLATILE: case DEMANGLE_COMPONENT_CONST: - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_TRANSACTION_SAFE: - case DEMANGLE_COMPONENT_REFERENCE_THIS: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: case DEMANGLE_COMPONENT_ARGLIST: case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: + FNQUAL_COMPONENT_CASE: break; /* Other types should not be seen here. */ @@ -1225,12 +1248,7 @@ has_return_type (struct demangle_component *dc) return 0; case DEMANGLE_COMPONENT_TEMPLATE: return ! is_ctor_dtor_or_conversion (d_left (dc)); - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_REFERENCE_THIS: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: - case DEMANGLE_COMPONENT_TRANSACTION_SAFE: + FNQUAL_COMPONENT_CASE: return has_return_type (d_left (dc)); } } @@ -1287,13 +1305,12 @@ d_encoding (struct d_info *di, int top_level) while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS || dc->type == DEMANGLE_COMPONENT_CONST_THIS - || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS) dc = d_left (dc); /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then - there may be CV-qualifiers on its right argument which + there may be function-qualifiers on its right argument which really apply here; this happens when parsing a class which is local to a function. */ if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME) @@ -1301,12 +1318,7 @@ d_encoding (struct d_info *di, int top_level) struct demangle_component *dcr; dcr = d_right (dc); - while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || dcr->type == DEMANGLE_COMPONENT_CONST_THIS - || dcr->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE - || dcr->type == DEMANGLE_COMPONENT_REFERENCE_THIS - || dcr->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS) + while (is_fnqual_component_type (dcr->type)) dcr = d_left (dcr); dc->u.s_binary.right = dcr; } @@ -2239,6 +2251,24 @@ d_ctor_dtor_name (struct d_info *di) } } +/* True iff we're looking at an order-insensitive type-qualifier, including + function-type-qualifiers. */ + +static int +next_is_type_qual (struct d_info *di) +{ + char peek = d_peek_char (di); + if (peek == 'r' || peek == 'V' || peek == 'K') + return 1; + if (peek == 'D') + { + peek = d_peek_next_char (di); + if (peek == 'x' || peek == 'o' || peek == 'O' || peek == 'w') + return 1; + } + return 0; +} + /* ::= ::= ::= @@ -2324,9 +2354,7 @@ cplus_demangle_type (struct d_info *di) __vector, and it treats it as order-sensitive when mangling names. */ - peek = d_peek_char (di); - if (peek == 'r' || peek == 'V' || peek == 'K' - || (peek == 'D' && d_peek_next_char (di) == 'x')) + if (next_is_type_qual (di)) { struct demangle_component **pret; @@ -2361,6 +2389,7 @@ cplus_demangle_type (struct d_info *di) can_subst = 1; + peek = d_peek_char (di); switch (peek) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': @@ -2648,10 +2677,10 @@ d_cv_qualifiers (struct d_info *di, pstart = pret; peek = d_peek_char (di); - while (peek == 'r' || peek == 'V' || peek == 'K' - || (peek == 'D' && d_peek_next_char (di) == 'x')) + while (next_is_type_qual (di)) { enum demangle_component_type t; + struct demangle_component *right = NULL; d_advance (di, 1); if (peek == 'r') @@ -2677,12 +2706,41 @@ d_cv_qualifiers (struct d_info *di, } else { - t = DEMANGLE_COMPONENT_TRANSACTION_SAFE; - di->expansion += sizeof "transaction_safe"; - d_advance (di, 1); + peek = d_next_char (di); + if (peek == 'x') + { + t = DEMANGLE_COMPONENT_TRANSACTION_SAFE; + di->expansion += sizeof "transaction_safe"; + } + else if (peek == 'o' + || peek == 'O') + { + t = DEMANGLE_COMPONENT_NOEXCEPT; + di->expansion += sizeof "noexcept"; + if (peek == 'O') + { + right = d_expression (di); + if (right == NULL) + return NULL; + if (! d_check_char (di, 'E')) + return NULL; + } + } + else if (peek == 'w') + { + t = DEMANGLE_COMPONENT_THROW_SPEC; + di->expansion += sizeof "throw"; + right = d_parmlist (di); + if (right == NULL) + return NULL; + if (! d_check_char (di, 'E')) + return NULL; + } + else + return NULL; } - *pret = d_make_comp (di, t, NULL, NULL); + *pret = d_make_comp (di, t, NULL, right); if (*pret == NULL) return NULL; pret = &d_left (*pret); @@ -3973,6 +4031,8 @@ d_count_templates_scopes (int *num_templates, int *num_scopes, case DEMANGLE_COMPONENT_REFERENCE_THIS: case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: case DEMANGLE_COMPONENT_TRANSACTION_SAFE: + case DEMANGLE_COMPONENT_NOEXCEPT: + case DEMANGLE_COMPONENT_THROW_SPEC: case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: case DEMANGLE_COMPONENT_POINTER: case DEMANGLE_COMPONENT_COMPLEX: @@ -4587,12 +4647,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options, adpm[i].templates = dpi->templates; ++i; - if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS - && typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS - && typed_name->type != DEMANGLE_COMPONENT_CONST_THIS - && typed_name->type != DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS - && typed_name->type != DEMANGLE_COMPONENT_TRANSACTION_SAFE - && typed_name->type != DEMANGLE_COMPONENT_REFERENCE_THIS) + if (!is_fnqual_component_type (typed_name->type)) break; typed_name = d_left (typed_name); @@ -4629,13 +4684,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options, d_print_error (dpi); return; } - while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || local_name->type == DEMANGLE_COMPONENT_CONST_THIS - || local_name->type == DEMANGLE_COMPONENT_REFERENCE_THIS - || local_name->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE - || (local_name->type - == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)) + while (is_fnqual_component_type (local_name->type)) { if (i >= sizeof adpm / sizeof adpm[0]) { @@ -4960,16 +5009,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options, } /* Fall through. */ - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_REFERENCE_THIS: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: case DEMANGLE_COMPONENT_POINTER: case DEMANGLE_COMPONENT_COMPLEX: case DEMANGLE_COMPONENT_IMAGINARY: - case DEMANGLE_COMPONENT_TRANSACTION_SAFE: + FNQUAL_COMPONENT_CASE: modifier: { /* We keep a list of modifiers on the stack. */ @@ -5674,13 +5718,7 @@ d_print_mod_list (struct d_print_info *dpi, int options, if (mods->printed || (! suffix - && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS - || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS - || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS - || mods->mod->type == DEMANGLE_COMPONENT_REFERENCE_THIS - || mods->mod->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE - || (mods->mod->type - == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)))) + && (is_fnqual_component_type (mods->mod->type)))) { d_print_mod_list (dpi, options, mods->next, suffix); return; @@ -5733,12 +5771,7 @@ d_print_mod_list (struct d_print_info *dpi, int options, 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 - || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS - || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE - || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS) + while (is_fnqual_component_type (dc->type)) dc = d_left (dc); d_print_comp (dpi, options, dc); @@ -5777,6 +5810,24 @@ d_print_mod (struct d_print_info *dpi, int options, case DEMANGLE_COMPONENT_TRANSACTION_SAFE: d_append_string (dpi, " transaction_safe"); return; + case DEMANGLE_COMPONENT_NOEXCEPT: + d_append_string (dpi, " noexcept"); + if (d_right (mod)) + { + d_append_char (dpi, '('); + d_print_comp (dpi, options, d_right (mod)); + d_append_char (dpi, ')'); + } + return; + case DEMANGLE_COMPONENT_THROW_SPEC: + d_append_string (dpi, " throw"); + if (d_right (mod)) + { + d_append_char (dpi, '('); + d_print_comp (dpi, options, d_right (mod)); + d_append_char (dpi, ')'); + } + return; case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: d_append_char (dpi, ' '); d_print_comp (dpi, options, d_right (mod)); @@ -5864,12 +5915,7 @@ d_print_function_type (struct d_print_info *dpi, int options, need_space = 1; need_paren = 1; break; - case DEMANGLE_COMPONENT_RESTRICT_THIS: - case DEMANGLE_COMPONENT_VOLATILE_THIS: - case DEMANGLE_COMPONENT_CONST_THIS: - case DEMANGLE_COMPONENT_REFERENCE_THIS: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: - case DEMANGLE_COMPONENT_TRANSACTION_SAFE: + FNQUAL_COMPONENT_CASE: break; default: break; @@ -6411,7 +6457,6 @@ is_ctor_or_dtor (const char *mangled, case DEMANGLE_COMPONENT_CONST_THIS: case DEMANGLE_COMPONENT_REFERENCE_THIS: case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: - case DEMANGLE_COMPONENT_TRANSACTION_SAFE: default: dc = NULL; break; diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index a56776355bf..5badc3e5849 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4596,3 +4596,13 @@ __10%0__S4_0T0T0 # Inheriting constructor _ZN1DCI11BEi D::B(int) + +# exception-specification (C++17) +_Z1fIvJiELb0EEvPDOT1_EFT_DpT0_E +void f(void (*)(int) noexcept(false)) + +_Z1fIvJiELb0EEvPDoFT_DpT0_E +void f(void (*)(int) noexcept) + +_Z1fIvJiELb0EEvPDwiEFT_DpT0_E +void f(void (*)(int) throw(int)) -- 2.30.2