diff options
author | Nathan Sidwell <nathan@acm.org> | 2022-03-08 10:53:39 -0800 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2022-05-18 03:58:55 -0700 |
commit | 65851d65fb36e847a9b8ef3b0519f06d29865a14 (patch) | |
tree | 47d29098e9f89fc6696255364f0f7e147ea726ec | |
parent | 86f64400a5692499856d41462461327b93f82b8d (diff) | |
download | gcc-65851d65fb36e847a9b8ef3b0519f06d29865a14.zip gcc-65851d65fb36e847a9b8ef3b0519f06d29865a14.tar.gz gcc-65851d65fb36e847a9b8ef3b0519f06d29865a14.tar.bz2 |
demangler: Reorganize for module demangling
Module demangling requires some changes in how substitutions are
handled. This adjusts things to make that possible.
libiberty/
* cp-demangle.c (d_name): Add SUBSTABLE parameter,
push substitution if requested. Adjust unscoped name handling.
(d_prefix): Reorder main loop. Adjust all calls.
(d_unqualified_name): Add SCOPE parameter, create qualified
name here. Adjust all calls.
(cplus_demangle_type): Do not handle 'S' here, leave all
to d_class_enum_type.
(d_class_enum_type): Add SUBSTABLE parameter.
-rw-r--r-- | libiberty/cp-demangle.c | 222 |
1 files changed, 83 insertions, 139 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index fc618fa..cf451c5 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -425,13 +425,14 @@ 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 substable); static struct demangle_component *d_nested_name (struct d_info *); static struct demangle_component *d_prefix (struct d_info *, int); -static struct demangle_component *d_unqualified_name (struct d_info *); +static struct demangle_component *d_unqualified_name (struct d_info *, + struct demangle_component *scope); static struct demangle_component *d_source_name (struct d_info *); @@ -462,7 +463,7 @@ static struct demangle_component * d_bare_function_type (struct d_info *, int); static struct demangle_component * -d_class_enum_type (struct d_info *); +d_class_enum_type (struct d_info *, int); static struct demangle_component *d_array_type (struct d_info *); @@ -1323,7 +1324,7 @@ d_encoding (struct d_info *di, int top_level) dc = d_special_name (di); else { - dc = d_name (di); + dc = d_name (di, 0); if (!dc) /* Failed already. */; @@ -1417,80 +1418,64 @@ 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 substable) { char peek = d_peek_char (di); - struct demangle_component *dc; + struct demangle_component *dc = NULL; + int subst = 0; switch (peek) { case 'N': - return d_nested_name (di); + dc = d_nested_name (di); + break; case 'Z': - return d_local_name (di); + dc = d_local_name (di); + break; case 'U': - return d_unqualified_name (di); + dc = d_unqualified_name (di, NULL); + break; case 'S': { - int subst; - - if (d_peek_next_char (di) != 't') - { - dc = d_substitution (di, 0); - subst = 1; - } - else + if (d_peek_next_char (di) == 't') { d_advance (di, 2); - dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, - d_make_name (di, "std", 3), - d_unqualified_name (di)); + dc = d_make_name (di, "std", 3); di->expansion += 3; - subst = 0; - } - - if (d_peek_char (di) != 'I') - { - /* The grammar does not permit this case to occur if we - called d_substitution() above (i.e., subst == 1). We - don't bother to check. */ } else { - /* This is <template-args>, which means that we just saw - <unscoped-template-name>, which is a substitution - candidate if we didn't just get it from a - substitution. */ - if (! subst) - { - if (! d_add_substitution (di, dc)) - return NULL; - } - dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc, - d_template_args (di)); + dc = d_substitution (di, 0); + if (!dc) + return NULL; + subst = 1; } - - return dc; } + /* FALLTHROUGH */ case 'L': default: - dc = d_unqualified_name (di); + if (!subst) + dc = d_unqualified_name (di, dc); if (d_peek_char (di) == 'I') { /* This is <template-args>, which means that we just saw <unscoped-template-name>, which is a substitution candidate. */ - if (! d_add_substitution (di, dc)) + if (!subst && !d_add_substitution (di, dc)) return NULL; dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc, d_template_args (di)); + subst = 0; } - return dc; + break; } + if (substable && !subst && !d_add_substitution (di, dc)) + return NULL; + return dc; } /* <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E @@ -1546,54 +1531,51 @@ d_nested_name (struct d_info *di) if not (in an unresolved-name). */ static struct demangle_component * -d_prefix (struct d_info *di, int subst) +d_prefix (struct d_info *di, int substable) { struct demangle_component *ret = NULL; - while (1) + for (;;) { - char peek; - enum demangle_component_type comb_type; - struct demangle_component *dc; - - peek = d_peek_char (di); - if (peek == '\0') - return NULL; + char peek = d_peek_char (di); /* The older code accepts a <local-name> here, but I don't see that in the grammar. The older code does not accept a <template-param> here. */ - comb_type = DEMANGLE_COMPONENT_QUAL_NAME; - if (peek == 'D') + if (peek == 'D' + && (d_peek_next_char (di) == 'T' + || d_peek_next_char (di) == 't')) { - char peek2 = d_peek_next_char (di); - if (peek2 == 'T' || peek2 == 't') - /* Decltype. */ - dc = cplus_demangle_type (di); - else - /* Destructor name. */ - dc = d_unqualified_name (di); + /* Decltype. */ + if (ret) + return NULL; + ret = cplus_demangle_type (di); } - else if (IS_DIGIT (peek) - || IS_LOWER (peek) - || peek == 'C' - || peek == 'U' - || peek == 'L') - dc = d_unqualified_name (di); else if (peek == 'S') - dc = d_substitution (di, 1); + { + if (ret) + return NULL; + ret = d_substitution (di, 1); + if (!ret) + return NULL; + continue; + } else if (peek == 'I') { if (ret == NULL) return NULL; - comb_type = DEMANGLE_COMPONENT_TEMPLATE; - dc = d_template_args (di); + struct demangle_component *dc = d_template_args (di); + if (!dc) + return NULL; + ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, dc); } else if (peek == 'T') - dc = d_template_param (di); - else if (peek == 'E') - return ret; + { + if (ret) + return NULL; + ret = d_template_param (di); + } else if (peek == 'M') { /* Initializer scope for a lambda. We don't need to represent @@ -1602,22 +1584,21 @@ d_prefix (struct d_info *di, int subst) if (ret == NULL) return NULL; d_advance (di, 1); - continue; } else - return NULL; + ret = d_unqualified_name (di, ret); - if (ret == NULL) - ret = dc; - else - ret = d_make_comp (di, comb_type, ret, dc); + if (!ret) + break; - if (peek != 'S' && d_peek_char (di) != 'E' && subst) - { - if (! d_add_substitution (di, ret)) - return NULL; - } + if (d_peek_char (di) == 'E') + break; + + if (substable && !d_add_substitution (di, ret)) + return NULL; } + + return ret; } /* <unqualified-name> ::= <operator-name> [<abi-tags>] @@ -1629,7 +1610,7 @@ d_prefix (struct d_info *di, int subst) */ static struct demangle_component * -d_unqualified_name (struct d_info *di) +d_unqualified_name (struct d_info *di, struct demangle_component *scope) { struct demangle_component *ret; char peek; @@ -1709,6 +1690,9 @@ d_unqualified_name (struct d_info *di) if (d_peek_char (di) == 'B') ret = d_abi_tags (di, ret); + if (scope) + ret = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, scope, ret); + return ret; } @@ -2149,11 +2133,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); case 'A': return d_make_comp (di, DEMANGLE_COMPONENT_TPARM_OBJ, @@ -2169,11 +2153,11 @@ d_special_name (struct d_info *di) { case 'V': return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, - d_name (di), NULL); + 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)); } @@ -2504,13 +2488,6 @@ cplus_demangle_type (struct d_info *di) ret = d_function_type (di); break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'N': - case 'Z': - ret = d_class_enum_type (di); - break; - case 'A': ret = d_array_type (di); break; @@ -2581,39 +2558,6 @@ cplus_demangle_type (struct d_info *di) } break; - case 'S': - /* If this is a special substitution, then it is the start of - <class-enum-type>. */ - { - char peek_next; - - peek_next = d_peek_next_char (di); - if (IS_DIGIT (peek_next) - || peek_next == '_' - || IS_UPPER (peek_next)) - { - ret = d_substitution (di, 0); - /* The substituted name may have been a template name and - may be followed by tepmlate args. */ - if (d_peek_char (di) == 'I') - ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, - d_template_args (di)); - else - can_subst = 0; - } - else - { - ret = d_class_enum_type (di); - /* If the substitution was a complete type, then it is not - a new substitution candidate. However, if the - substitution was followed by template arguments, then - the whole thing is a substitution candidate. */ - if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD) - can_subst = 0; - } - } - break; - case 'O': d_advance (di, 1); ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE, @@ -2754,7 +2698,7 @@ cplus_demangle_type (struct d_info *di) break; default: - return NULL; + return d_class_enum_type (di, 1); } if (can_subst) @@ -3027,9 +2971,9 @@ d_bare_function_type (struct d_info *di, int has_return_type) /* <class-enum-type> ::= <name> */ static struct demangle_component * -d_class_enum_type (struct d_info *di) +d_class_enum_type (struct d_info *di, int substable) { - return d_name (di); + return d_name (di, substable); } /* <array-type> ::= A <(positive dimension) number> _ <(element) type> @@ -3358,11 +3302,11 @@ d_unresolved_name (struct d_info *di) } else type = cplus_demangle_type (di); - name = d_unqualified_name (di); + name = d_unqualified_name (di, type); if (d_peek_char (di) == 'I') name = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name, d_template_args (di)); - return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name); + return name; } /* <expression> ::= <(unary) operator-name> <expression> @@ -3431,7 +3375,7 @@ d_expression_1 (struct d_info *di) /* operator-function-id, i.e. operator+(t). */ d_advance (di, 2); - name = d_unqualified_name (di); + name = d_unqualified_name (di, NULL); if (name == NULL) return NULL; if (d_peek_char (di) == 'I') @@ -3539,7 +3483,7 @@ d_expression_1 (struct d_info *di) /* fold-expression. */ left = d_operator_name (di); else if (!strcmp (code, "di")) - left = d_unqualified_name (di); + left = d_unqualified_name (di, NULL); else left = d_expression_1 (di); if (!strcmp (code, "cl")) @@ -3557,7 +3501,7 @@ d_expression_1 (struct d_info *di) d_unqualified_name rather than d_expression_1 here for old mangled names that didn't add 'on' before operator names. */ - right = d_unqualified_name (di); + right = d_unqualified_name (di, NULL); if (d_peek_char (di) == 'I') right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, right, d_template_args (di)); @@ -3767,7 +3711,7 @@ d_local_name (struct d_info *di) return NULL; } - name = d_name (di); + name = d_name (di, 0); if (name /* Lambdas and unnamed types have internal discriminators |