From f0f338480a89e47f0912f886b7c30215cbe97a37 Mon Sep 17 00:00:00 2001 From: Alex Samuel Date: Mon, 28 Aug 2000 05:22:30 +0000 Subject: [PATCH] mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo. * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo. (write_encoding): Pass another argument to write_name. (write_name): Add ignore_local_scope parameter. Fix handling of local names. (write_nested_name): Use write_unqualified_name. (write_prefix): Likewise. Skip out on FUNCTION_DECLs. (write_template_prefix): Use write_unqualified_name. (write_component): Remove. (write_local_name): Add parameter. Use direct local entity to discriminator calculation. (write_class_enum_type): Pass another argument to write_name. (write_template_template_arg): Likewise. (make_guard_variable): Likewise. From-SVN: r36013 --- gcc/cp/ChangeLog | 16 ++++++ gcc/cp/mangle.c | 133 +++++++++++++++++++++++++++-------------------- 2 files changed, 93 insertions(+), 56 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 507edd876a0..8f0617f4fcb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2000-08-27 Alex Samuel + + * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo. + (write_encoding): Pass another argument to write_name. + (write_name): Add ignore_local_scope parameter. Fix handling of + local names. + (write_nested_name): Use write_unqualified_name. + (write_prefix): Likewise. Skip out on FUNCTION_DECLs. + (write_template_prefix): Use write_unqualified_name. + (write_component): Remove. + (write_local_name): Add parameter. Use direct local entity to + discriminator calculation. + (write_class_enum_type): Pass another argument to write_name. + (write_template_template_arg): Likewise. + (make_guard_variable): Likewise. + 2000-08-27 Jason Merrill * decl.c (pushdecl): Matching decls for local externs are found in diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 0747ebcbf34..98f59ab6c5f 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -78,14 +78,11 @@ CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser that hard to distinguish A from A, where A is the type as instantiated outside of the template, and A is the type used - without parameters inside the template. The logic here is - historical magic that apparently produces the right result. */ + without parameters inside the template. */ #define CLASSTYPE_TEMPLATE_ID_P(NODE) \ (TYPE_LANG_SPECIFIC (NODE) != NULL \ && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ - && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)) \ - || (TREE_CODE (CP_DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE (NODE))) \ - == FUNCTION_DECL))) + && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))) /* Things we only need one of. This module is not reentrant. */ static struct globals @@ -148,13 +145,12 @@ static int find_substitution PARAMS ((tree)); static void write_mangled_name PARAMS ((tree)); static void write_encoding PARAMS ((tree)); -static void write_name PARAMS ((tree)); +static void write_name PARAMS ((tree, int)); static void write_unscoped_name PARAMS ((tree)); static void write_unscoped_template_name PARAMS ((tree)); static void write_nested_name PARAMS ((tree)); static void write_prefix PARAMS ((tree)); static void write_template_prefix PARAMS ((tree)); -static void write_component PARAMS ((tree)); static void write_unqualified_name PARAMS ((tree)); static void write_source_name PARAMS ((tree)); static void write_number PARAMS ((unsigned HOST_WIDE_INT, int, @@ -183,7 +179,7 @@ static void write_substitution PARAMS ((int)); static int discriminator_for_local_entity PARAMS ((tree)); static int discriminator_for_string_literal PARAMS ((tree, tree)); static void write_discriminator PARAMS ((int)); -static void write_local_name PARAMS ((tree, tree)); +static void write_local_name PARAMS ((tree, tree, tree)); static void dump_substitution_candidates PARAMS ((void)); static const char *mangle_decl_string PARAMS ((tree)); @@ -630,7 +626,7 @@ write_encoding (decl) return; } - write_name (decl); + write_name (decl, /*ignore_local_scope=*/0); if (TREE_CODE (decl) == FUNCTION_DECL) { tree fn_type; @@ -651,11 +647,18 @@ write_encoding (decl) /* ::= ::= ::= - ::= */ + ::= + + If IGNORE_LOCAL_SCOPE is non-zero, this production of is + called from , which mangles the enclosing scope + elsewhere and then uses this function to mangle just the part + underneath the function scope. So don't use the + production, to avoid an infinite recursion. */ static void -write_name (decl) +write_name (decl, ignore_local_scope) tree decl; + int ignore_local_scope; { tree context; @@ -688,12 +691,44 @@ write_name (decl) /* Everything else gets an . */ write_unscoped_name (decl); } - /* Handle local names. */ - else if (TREE_CODE (context) == FUNCTION_DECL) - write_local_name (context, decl); - /* Other decls get a to encode their scope. */ else - write_nested_name (decl); + { + /* Handle local names, unless we asked not to (that is, invoked + under , to handle only the part of the name under + the local scope). */ + if (!ignore_local_scope) + { + /* Scan up the list of scope context, looking for a + function. If we find one, this entity is in local + function scope. local_entity tracks context one scope + level down, so it will contain the element that's + directly in that function's scope, either decl or one of + its enclosing scopes. */ + tree local_entity = decl; + while (context != NULL && context != global_namespace) + { + /* Make sure we're always dealing with decls. */ + if (context != NULL && TYPE_P (context)) + context = TYPE_NAME (context); + /* Is this a function? */ + if (TREE_CODE (context) == FUNCTION_DECL) + { + /* Yes, we have local scope. Use the + production for the innermost function scope. */ + write_local_name (context, local_entity, decl); + return; + } + /* Up one scope level. */ + local_entity = context; + context = CP_DECL_CONTEXT (context); + } + + /* No local scope found? Fall through to . */ + } + + /* Other decls get a to encode their scope. */ + write_nested_name (decl); + } } /* ::= @@ -737,7 +772,7 @@ write_unscoped_template_name (decl) /* Write the nested name, including CV-qualifiers, of DECL. - ::= N [] E + ::= N [] E ::= N [] E ::= [r] [V] [K] */ @@ -773,12 +808,12 @@ write_nested_name (decl) { /* No, just use */ write_prefix (DECL_CONTEXT (decl)); - write_component (decl); + write_unqualified_name (decl); } write_char ('E'); } -/* ::= +/* ::= > ::= ::= # empty ::= */ @@ -803,6 +838,14 @@ write_prefix (node) if (DECL_P (node)) /* Node is a decl. */ { + /* If this is a function decl, that means we've hit function + scope, so this prefix must be for a local name. In this + case, we're under the production, which encodes + the enclosing function scope elsewhere. So don't continue + here. */ + if (TREE_CODE (node) == FUNCTION_DECL) + return; + decl = node; decl_is_template_id (decl, &template_info); } @@ -824,7 +867,7 @@ write_prefix (node) /* Not templated. */ { write_prefix (CP_DECL_CONTEXT (decl)); - write_component (decl); + write_unqualified_name (decl); } add_substitution (node); @@ -886,39 +929,11 @@ write_template_prefix (node) return; write_prefix (context); - write_component (decl); + write_unqualified_name (decl); add_substitution (substitution); } -/* ::= - ::= */ - -static void -write_component (decl) - tree decl; -{ - MANGLE_TRACE_TREE ("component", decl); - - switch (TREE_CODE (decl)) - { - case TEMPLATE_DECL: - case NAMESPACE_DECL: - case VAR_DECL: - case TYPE_DECL: - case FUNCTION_DECL: - case FIELD_DECL: - if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL) - write_local_name (CP_DECL_CONTEXT (decl), decl); - else - write_unqualified_name (decl); - break; - - default: - my_friendly_abort (2000509); - } -} - /* We don't need to handle thunks, vtables, or VTTs here. Those are mangled through special entry points. @@ -1160,14 +1175,17 @@ write_discriminator (discriminator) /* Mangle the name of a function-scope entity. FUNCTION is the FUNCTION_DECL for the enclosing function. ENTITY is the decl for - the entity itself. + the entity itself. LOCAL_ENTITY is the entity that's directly + scoped in FUNCTION_DECL, either ENTITY itself or an enclosing scope + of ENTITY. := Z E [] := Z E s [] */ static void -write_local_name (function, entity) +write_local_name (function, local_entity, entity) tree function; + tree local_entity; tree entity; { MANGLE_TRACE_TREE ("local-name", entity); @@ -1183,8 +1201,11 @@ write_local_name (function, entity) } else { - write_unqualified_name (entity); - write_discriminator (discriminator_for_local_entity (entity)); + /* Now the . Let write_name know its being called + from , so it doesn't try to process the enclosing + function scope again. */ + write_name (entity, /*ignore_local_scope=*/1); + write_discriminator (discriminator_for_local_entity (local_entity)); } } @@ -1540,7 +1561,7 @@ static void write_class_enum_type (type) tree type; { - write_name (TYPE_NAME (type)); + write_name (TYPE_NAME (type), /*ignore_local_scope=*/0); } /* Non-terminal . ARGS is a TREE_VEC of template @@ -1785,7 +1806,7 @@ write_template_template_arg (tree decl) if (find_substitution (decl)) return; - write_name (decl); + write_name (decl, /*ignore_local_scope=*/0); add_substitution (decl); } @@ -2219,6 +2240,6 @@ mangle_guard_variable (variable) { start_mangling (); write_string ("_ZGV"); - write_name (variable); + write_name (variable, /*ignore_local_scope=*/0); return get_identifier (finish_mangling ()); }