aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r--gcc/cp/name-lookup.c34
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;
}