diff options
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r-- | gcc/cp/name-lookup.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index f02bf269fad..f990a3bd616 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3850,9 +3850,33 @@ qualified_lookup_using_namespace (tree name, tree scope, POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node); } +/* Subroutine of outer_binding. + Returns TRUE if BINDING is a binding to a template parameter of SCOPE, + FALSE otherwise. */ +static bool +binding_to_template_parms_of_scope_p (cxx_binding *binding, + cxx_scope *scope) +{ + tree binding_value; + + if (!binding || !scope) + return false; + + binding_value = binding->value ? binding->value : binding->type; + + return (scope + && scope->this_entity + && get_template_info (scope->this_entity) + && parameter_of_template_p (binding_value, + TI_TEMPLATE (get_template_info \ + (scope->this_entity)))); +} + /* Return the innermost non-namespace binding for NAME from a scope - containing BINDING, or, if BINDING is NULL, the current scope. If - CLASS_P is false, then class bindings are ignored. */ + containing BINDING, or, if BINDING is NULL, the current scope. + Please note that for a given template, the template parameters are + considered to be in the scope containing the current scope. + If CLASS_P is false, then class bindings are ignored. */ cxx_binding * outer_binding (tree name, @@ -3900,6 +3924,12 @@ outer_binding (tree name, return class_binding; } } + /* If SCOPE is a template and if NAME binds to one of its template parameters + return the binding, otherwise we might miss it. */ + if (outer_scope && outer_scope->kind == sk_template_parms + && binding_to_template_parms_of_scope_p (outer, scope)) + return outer; + scope = scope->level_chain; } |