summaryrefslogtreecommitdiff
path: root/libiberty/cp-demangle.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-11-07 18:09:29 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-11-07 18:09:29 -0500
commit51dc660315ef83dcb907f3bd3a0a56abb9efed7a (patch)
treec9f9278ab8d390747f291ff0e7146959604797d2 /libiberty/cp-demangle.c
parent452811eb53e9c0457f99f4f23a4ca10354c088e1 (diff)
downloadgcc-51dc660315ef83dcb907f3bd3a0a56abb9efed7a.tar.gz
Implement P0012R1, Make exception specifications part of the type system.
gcc/cp/ * cp-tree.h (enum tsubst_flags): Add tf_fndecl_type. (flag_noexcept_type, ce_type): New. * call.c (build_conv): Add ck_fnptr. (enum conversion_kind): Change ck_tsafe to ck_fnptr. (convert_like_real): Likewise. (standard_conversion): Likewise. Allow function pointer conversions for pointers to member functions. (reference_compatible_p): Allow function pointer conversions. (direct_reference_binding): Likewise. (reference_binding): Reference-compatible is no longer a subset of reference-related. (is_subseq): Also strip ck_lvalue after next_conversion. * class.c (instantiate_type): Check fnptr_conv_p. (resolve_address_of_overloaded_function): Likewise. * cvt.c (can_convert_tx_safety): Now static. (noexcept_conv_p, fnptr_conv_p, strip_fnptr_conv): New. * decl.c (flag_noexcept_type): Define. (cxx_init_decl_processing): Set it. (bad_specifiers): Check it. (grokdeclarator) [cdk_function]: Add exception-spec to type here. * lambda.c (maybe_add_lambda_conv_op): Add exception-spec to returned pointer. * mangle.c (struct globals): Add need_cxx1z_warning. (mangle_decl): Check it. (write_exception_spec): New. (write_function_type): Call it. (canonicalize_for_substitution): Handle exception spec. (write_type): Likewise. (write_encoding): Set processing_template_decl across mangling of partially-instantiated type. * pt.c (determine_specialization): Pass tf_fndecl_type. (tsubst_decl, fn_type_unification): Likewise. (tsubst): Strip tf_fndecl_type, pass it to tsubst_exception_specification. (convert_nontype_argument_function): Handle function pointer conversion. (convert_nontype_argument): Likewise. (unify, for_each_template_parm_r): Walk into noexcept-specifier. * rtti.c (ptr_initializer): Encode noexcept. * tree.c (canonical_eh_spec): New. (build_exception_variant): Use it. * typeck.c (composite_pointer_type): Handle fnptr conversion. (comp_except_specs): Compare canonical EH specs. (structural_comptypes): Call it. gcc/c-family/ * c.opt (Wc++1z-compat): New. * c-cppbuiltin.c (c_cpp_builtins): Add __cpp_noexcept_function_type. libstdc++-v3/ * include/bits/c++config (_GLIBCXX_NOEXCEPT_PARM) (_GLIBCXX_NOEXCEPT_QUAL): New. * include/std/type_traits (is_function): Use them. * libsubc++/new (launder): Likewise. * libsupc++/cxxabi.h (__pbase_type_info::__masks): Add __noexcept_mask. * libsupc++/pbase_type_info.cc (__do_catch): Handle function pointer conversion. 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. From-SVN: r241944
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r--libiberty/cp-demangle.c181
1 files changed, 113 insertions, 68 deletions
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;
+}
+
/* <type> ::= <builtin-type>
::= <function-type>
::= <class-enum-type>
@@ -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;