diff options
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r-- | libiberty/cp-demangle.c | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 7b8d0b4..c330052 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -425,7 +425,7 @@ is_ctor_dtor_or_conversion (struct demangle_component *); static struct demangle_component *d_encoding (struct d_info *, int); -static struct demangle_component *d_name (struct d_info *); +static struct demangle_component *d_name (struct d_info *, int); static struct demangle_component *d_nested_name (struct d_info *); @@ -484,7 +484,7 @@ static struct demangle_component *d_expression (struct d_info *); static struct demangle_component *d_expr_primary (struct d_info *); -static struct demangle_component *d_local_name (struct d_info *); +static struct demangle_component *d_local_name (struct d_info *, int); static int d_discriminator (struct d_info *); @@ -568,22 +568,6 @@ 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: \ @@ -594,6 +578,23 @@ is_fnqual_component_type (enum demangle_component_type type) case DEMANGLE_COMPONENT_NOEXCEPT: \ case DEMANGLE_COMPONENT_THROW_SPEC +/* True iff TYPE is a demangling component representing a + function-type-qualifier. */ + +static int +is_fnqual_component_type (enum demangle_component_type type) +{ + switch (type) + { + FNQUAL_COMPONENT_CASE: + return 1; + default: + break; + } + return 0; +} + + #ifdef CP_DEMANGLE_DEBUG static void @@ -1305,9 +1306,9 @@ d_encoding (struct d_info *di, int top_level) return d_special_name (di); else { - struct demangle_component *dc; + struct demangle_component *dc, *dcr; - dc = d_name (di); + dc = d_name (di, top_level); if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0) { @@ -1327,8 +1328,6 @@ d_encoding (struct d_info *di, int top_level) which is local to a function. */ if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME) { - struct demangle_component *dcr; - dcr = d_right (dc); while (is_fnqual_component_type (dcr->type)) dcr = d_left (dcr); @@ -1341,8 +1340,8 @@ d_encoding (struct d_info *di, int top_level) peek = d_peek_char (di); if (dc == NULL || peek == '\0' || peek == 'E') return dc; - return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc, - d_bare_function_type (di, has_return_type (dc))); + dcr = d_bare_function_type (di, has_return_type (dc)); + return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc, dcr); } } @@ -1384,7 +1383,7 @@ d_abi_tags (struct d_info *di, struct demangle_component *dc) */ static struct demangle_component * -d_name (struct d_info *di) +d_name (struct d_info *di, int top_level) { char peek = d_peek_char (di); struct demangle_component *dc; @@ -1395,7 +1394,7 @@ d_name (struct d_info *di) return d_nested_name (di); case 'Z': - return d_local_name (di); + return d_local_name (di, top_level); case 'U': return d_unqualified_name (di); @@ -2080,11 +2079,11 @@ d_special_name (struct d_info *di) case 'H': return d_make_comp (di, DEMANGLE_COMPONENT_TLS_INIT, - d_name (di), NULL); + d_name (di, 0), NULL); case 'W': return d_make_comp (di, DEMANGLE_COMPONENT_TLS_WRAPPER, - d_name (di), NULL); + d_name (di, 0), NULL); default: return NULL; @@ -2095,11 +2094,12 @@ d_special_name (struct d_info *di) switch (d_next_char (di)) { case 'V': - return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL); + return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, + d_name (di, 0), NULL); case 'R': { - struct demangle_component *name = d_name (di); + struct demangle_component *name = d_name (di, 0); return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, name, d_number_component (di)); } @@ -2935,7 +2935,7 @@ d_bare_function_type (struct d_info *di, int has_return_type) static struct demangle_component * d_class_enum_type (struct d_info *di) { - return d_name (di); + return d_name (di, 0); } /* <array-type> ::= A <(positive dimension) number> _ <(element) type> @@ -3568,9 +3568,10 @@ d_expr_primary (struct d_info *di) */ static struct demangle_component * -d_local_name (struct d_info *di) +d_local_name (struct d_info *di, int top_level) { struct demangle_component *function; + struct demangle_component *name; if (! d_check_char (di, 'Z')) return NULL; @@ -3585,13 +3586,10 @@ d_local_name (struct d_info *di) d_advance (di, 1); if (! d_discriminator (di)) return NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, - d_make_name (di, "string literal", - sizeof "string literal" - 1)); + name = d_make_name (di, "string literal", sizeof "string literal" - 1); } else { - struct demangle_component *name; int num = -1; if (d_peek_char (di) == 'd') @@ -3603,22 +3601,36 @@ d_local_name (struct d_info *di) return NULL; } - name = d_name (di); - 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; - } + name = d_name (di, 0); + + if (name + /* Lambdas and unnamed types have internal discriminators + and are not functions. */ + && name->type != DEMANGLE_COMPONENT_LAMBDA + && name->type != DEMANGLE_COMPONENT_UNNAMED_TYPE) + { + if (!top_level + && d_peek_char (di) != 0 /* Not end of string. */ + && d_peek_char (di) != 'E' /* Not end of nested encoding. */ + && d_peek_char (di) != '_') /* Not discriminator. */ + { + struct demangle_component *args; + + args = d_bare_function_type (di, has_return_type (name)); + name = d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, + name, args); + } + + /* Read and ignore an optional discriminator. */ + 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); } + + return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name); } /* <discriminator> ::= _ <number> # when number < 10 |