Commit 9ed182dc by Jason Merrill Committed by Jason Merrill

decl.c (qualify_lookup): Handle templates.

	* decl.c (qualify_lookup): Handle templates.
	* decl2.c (do_using_directive): Don't pass ancestor.
	* decl.c (push_using_directive): Calculate ancestor.
	* decl2.c (do_nonmember_using_decl): Allow for type shadowing.
	* decl.c (pushdecl): Move type shadowing handling from here...
	(duplicate_decls): ...to here.
	* decl.c (set_identifier_local_value_with_scope): New fn.
	(pushdecl): Use it.
	(set_identifier_local_value, lookup_type_current_level): New fns.
	* decl2.c (do_local_using_decl): Handle types and binding level
	stuff properly.

From-SVN: r21223
parent 3cab3dc8
1998-07-16 Jason Merrill <jason@yorick.cygnus.com> 1998-07-16 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (qualify_lookup): Handle templates.
* decl2.c (do_using_directive): Don't pass ancestor.
* decl.c (push_using_directive): Calculate ancestor.
* decl2.c (do_nonmember_using_decl): Allow for type shadowing.
* decl.c (pushdecl): Move type shadowing handling from here...
(duplicate_decls): ...to here.
* decl.c (set_identifier_local_value_with_scope): New fn.
(pushdecl): Use it.
(set_identifier_local_value, lookup_type_current_level): New fns.
* decl2.c (do_local_using_decl): Handle types and binding level
stuff properly.
* init.c (build_offset_ref): Don't call mark_used on an OVERLOAD. * init.c (build_offset_ref): Don't call mark_used on an OVERLOAD.
* decl.c (select_decl): Extract a lone function from an OVERLOAD. * decl.c (select_decl): Extract a lone function from an OVERLOAD.
(lookup_namespace_name): Likewise. (lookup_namespace_name): Likewise.
......
...@@ -2379,7 +2379,7 @@ extern void pushdecl_nonclass_level PROTO((tree)); ...@@ -2379,7 +2379,7 @@ extern void pushdecl_nonclass_level PROTO((tree));
#endif #endif
extern tree pushdecl_namespace_level PROTO((tree)); extern tree pushdecl_namespace_level PROTO((tree));
extern tree push_using_decl PROTO((tree, tree)); extern tree push_using_decl PROTO((tree, tree));
extern tree push_using_directive PROTO((tree, tree)); extern tree push_using_directive PROTO((tree));
extern void push_class_level_binding PROTO((tree, tree)); extern void push_class_level_binding PROTO((tree, tree));
extern tree push_using_decl PROTO((tree, tree)); extern tree push_using_decl PROTO((tree, tree));
extern tree implicitly_declare PROTO((tree)); extern tree implicitly_declare PROTO((tree));
...@@ -2403,9 +2403,11 @@ extern tree lookup_name_nonclass PROTO((tree)); ...@@ -2403,9 +2403,11 @@ extern tree lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree)); extern tree lookup_function_nonclass PROTO((tree, tree));
extern tree lookup_name PROTO((tree, int)); extern tree lookup_name PROTO((tree, int));
extern tree lookup_name_current_level PROTO((tree)); extern tree lookup_name_current_level PROTO((tree));
extern tree lookup_type_current_level PROTO((tree));
extern tree lookup_name_namespace_only PROTO((tree)); extern tree lookup_name_namespace_only PROTO((tree));
extern void begin_only_namespace_names PROTO((void)); extern void begin_only_namespace_names PROTO((void));
extern void end_only_namespace_names PROTO((void)); extern void end_only_namespace_names PROTO((void));
extern tree namespace_ancestor PROTO((tree, tree));
extern int lookup_using_namespace PROTO((tree,tree,tree,tree,int)); extern int lookup_using_namespace PROTO((tree,tree,tree,tree,int));
extern int qualified_lookup_using_namespace PROTO((tree,tree,tree,int)); extern int qualified_lookup_using_namespace PROTO((tree,tree,tree,int));
extern tree auto_function PROTO((tree, tree, enum built_in_function)); extern tree auto_function PROTO((tree, tree, enum built_in_function));
......
...@@ -2159,6 +2159,26 @@ set_identifier_type_value (id, type) ...@@ -2159,6 +2159,26 @@ set_identifier_type_value (id, type)
set_identifier_type_value_with_scope (id, type, inner_binding_level); set_identifier_type_value_with_scope (id, type, inner_binding_level);
} }
void
set_identifier_local_value_with_scope (id, val, b)
tree id, val;
struct binding_level *b;
{
tree oldlocal;
my_friendly_assert (! b->namespace_p, 980716);
oldlocal = IDENTIFIER_LOCAL_VALUE (id);
b->shadowed = tree_cons (id, oldlocal, b->shadowed);
IDENTIFIER_LOCAL_VALUE (id) = val;
}
void
set_identifier_local_value (id, val)
tree id, val;
{
set_identifier_local_value_with_scope (id, val, current_binding_level);
}
/* Return the type associated with id. */ /* Return the type associated with id. */
tree tree
...@@ -2646,12 +2666,30 @@ duplicate_decls (newdecl, olddecl) ...@@ -2646,12 +2666,30 @@ duplicate_decls (newdecl, olddecl)
} }
else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
{ {
if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
&& TREE_CODE (newdecl) != TYPE_DECL
&& ! (TREE_CODE (newdecl) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL))
|| (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
&& TREE_CODE (olddecl) != TYPE_DECL
&& ! (TREE_CODE (olddecl) == TEMPLATE_DECL
&& (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
== TYPE_DECL))))
{
/* We do nothing special here, because C++ does such nasty
things with TYPE_DECLs. Instead, just let the TYPE_DECL
get shadowed, and know that if we need to find a TYPE_DECL
for a given name, we can look in the IDENTIFIER_TYPE_VALUE
slot of the identifier. */
return 0;
}
if ((TREE_CODE (newdecl) == FUNCTION_DECL if ((TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (olddecl)) && DECL_FUNCTION_TEMPLATE_P (olddecl))
|| (TREE_CODE (olddecl) == FUNCTION_DECL || (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (newdecl))) && DECL_FUNCTION_TEMPLATE_P (newdecl)))
return 0; return 0;
cp_error ("`%#D' redeclared as different kind of symbol", newdecl); cp_error ("`%#D' redeclared as different kind of symbol", newdecl);
if (TREE_CODE (olddecl) == TREE_LIST) if (TREE_CODE (olddecl) == TREE_LIST)
olddecl = TREE_VALUE (olddecl); olddecl = TREE_VALUE (olddecl);
...@@ -3319,24 +3357,7 @@ pushdecl (x) ...@@ -3319,24 +3357,7 @@ pushdecl (x)
} }
else if (TREE_CODE (t) != TREE_CODE (x)) else if (TREE_CODE (t) != TREE_CODE (x))
{ {
if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t) if (duplicate_decls (x, t))
&& TREE_CODE (x) != TYPE_DECL
&& ! (TREE_CODE (x) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (x)) == TYPE_DECL))
|| (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
&& TREE_CODE (t) != TYPE_DECL
&& ! (TREE_CODE (t) == TEMPLATE_DECL
&& (TREE_CODE (DECL_TEMPLATE_RESULT (t))
== TYPE_DECL))))
{
/* We do nothing special here, because C++ does such nasty
things with TYPE_DECLs. Instead, just let the TYPE_DECL
get shadowed, and know that if we need to find a TYPE_DECL
for a given name, we can look in the IDENTIFIER_TYPE_VALUE
slot of the identifier. */
;
}
else if (duplicate_decls (x, t))
return t; return t;
} }
else if (duplicate_decls (x, t)) else if (duplicate_decls (x, t))
...@@ -3519,10 +3540,7 @@ pushdecl (x) ...@@ -3519,10 +3540,7 @@ pushdecl (x)
if (TREE_CODE (x) != TYPE_DECL if (TREE_CODE (x) != TYPE_DECL
|| t == NULL_TREE || t == NULL_TREE
|| ! DECL_ARTIFICIAL (x)) || ! DECL_ARTIFICIAL (x))
{ set_identifier_local_value_with_scope (name, x, b);
b->shadowed = tree_cons (name, oldlocal, b->shadowed);
IDENTIFIER_LOCAL_VALUE (name) = x;
}
/* If this is a TYPE_DECL, push it into the type value slot. */ /* If this is a TYPE_DECL, push it into the type value slot. */
if (TREE_CODE (x) == TYPE_DECL) if (TREE_CODE (x) == TYPE_DECL)
...@@ -3851,12 +3869,11 @@ push_using_decl (scope, name) ...@@ -3851,12 +3869,11 @@ push_using_decl (scope, name)
TREE_LIST otherwise. */ TREE_LIST otherwise. */
tree tree
push_using_directive (used, ancestor) push_using_directive (used)
tree used; tree used;
tree ancestor;
{ {
tree ud = current_binding_level->using_directives; tree ud = current_binding_level->using_directives;
tree iter; tree iter, ancestor;
/* Check if we already have this. */ /* Check if we already have this. */
if (purpose_member (used, ud) != NULL_TREE) if (purpose_member (used, ud) != NULL_TREE)
...@@ -3864,8 +3881,9 @@ push_using_directive (used, ancestor) ...@@ -3864,8 +3881,9 @@ push_using_directive (used, ancestor)
/* Recursively add all namespaces used. */ /* Recursively add all namespaces used. */
for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
push_using_directive (TREE_PURPOSE (iter), ancestor); push_using_directive (TREE_PURPOSE (iter));
ancestor = namespace_ancestor (current_decl_namespace (), used);
ud = current_binding_level->using_directives; ud = current_binding_level->using_directives;
ud = perm_tree_cons (used, ancestor, ud); ud = perm_tree_cons (used, ancestor, ud);
current_binding_level->using_directives = ud; current_binding_level->using_directives = ud;
...@@ -4859,7 +4877,10 @@ qualify_lookup (val, flags) ...@@ -4859,7 +4877,10 @@ qualify_lookup (val, flags)
return val; return val;
if (LOOKUP_NAMESPACES_ONLY (flags) && TREE_CODE (val) != NAMESPACE_DECL) if (LOOKUP_NAMESPACES_ONLY (flags) && TREE_CODE (val) != NAMESPACE_DECL)
return NULL_TREE; return NULL_TREE;
if (LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL) if (LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL
&& ! ((flags & LOOKUP_TEMPLATES_EXPECTED)
&& TREE_CODE (val) == TEMPLATE_DECL
&& DECL_CLASS_TEMPLATE_P (val)))
return NULL_TREE; return NULL_TREE;
return val; return val;
} }
...@@ -5133,16 +5154,41 @@ lookup_name_current_level (name) ...@@ -5133,16 +5154,41 @@ lookup_name_current_level (name)
struct binding_level *b = current_binding_level; struct binding_level *b = current_binding_level;
while (1) while (1)
{ {
for (t = b->names; t; t = TREE_CHAIN (t)) if (purpose_member (name, b->shadowed))
if (DECL_NAME (t) == name || DECL_ASSEMBLER_NAME (t) == name) return IDENTIFIER_LOCAL_VALUE (name);
goto out; if (b->keep == 2)
b = b->level_chain;
else
break;
}
}
return t;
}
/* Like lookup_name_current_level, but for types. */
tree
lookup_type_current_level (name)
tree name;
{
register tree t = NULL_TREE;
my_friendly_assert (! current_binding_level->namespace_p, 980716);
if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
&& REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
{
struct binding_level *b = current_binding_level;
while (1)
{
if (purpose_member (name, b->type_shadowed))
return REAL_IDENTIFIER_TYPE_VALUE (name);
if (b->keep == 2) if (b->keep == 2)
b = b->level_chain; b = b->level_chain;
else else
break; break;
} }
out:
;
} }
return t; return t;
......
...@@ -58,7 +58,6 @@ static int finish_vtable_vardecl PROTO((tree, tree)); ...@@ -58,7 +58,6 @@ static int finish_vtable_vardecl PROTO((tree, tree));
static int prune_vtable_vardecl PROTO((tree, tree)); static int prune_vtable_vardecl PROTO((tree, tree));
static void finish_sigtable_vardecl PROTO((tree, tree)); static void finish_sigtable_vardecl PROTO((tree, tree));
static int is_namespace_ancestor PROTO((tree, tree)); static int is_namespace_ancestor PROTO((tree, tree));
static tree namespace_ancestor PROTO((tree, tree));
static void add_using_namespace PROTO((tree, tree, int)); static void add_using_namespace PROTO((tree, tree, int));
static tree ambiguous_decl PROTO((tree, tree, tree,int)); static tree ambiguous_decl PROTO((tree, tree, tree,int));
static tree build_anon_union_vars PROTO((tree, tree*, int, int)); static tree build_anon_union_vars PROTO((tree, tree*, int, int));
...@@ -3839,7 +3838,7 @@ is_namespace_ancestor (root, child) ...@@ -3839,7 +3838,7 @@ is_namespace_ancestor (root, child)
/* Return the namespace that is the common ancestor /* Return the namespace that is the common ancestor
of two given namespaces. */ of two given namespaces. */
static tree tree
namespace_ancestor (ns1, ns2) namespace_ancestor (ns1, ns2)
tree ns1, ns2; tree ns1, ns2;
{ {
...@@ -4495,10 +4494,16 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) ...@@ -4495,10 +4494,16 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls))) if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls)))
{ {
tree tmp, tmp1; tree tmp, tmp1;
if (oldval && !is_overloaded_fn (oldval))
{
duplicate_decls (OVL_CURRENT (BINDING_VALUE (decls)), oldval);
oldval = NULL_TREE;
}
*newval = oldval; *newval = oldval;
for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp)) for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
{ {
/* Compare each new function with each old one. /* Compare each new function with each old one.
If the old function was also used, there is no conflict. */ If the old function was also used, there is no conflict. */
for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1)) for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
...@@ -4522,8 +4527,8 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) ...@@ -4522,8 +4527,8 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
else else
{ {
*newval = BINDING_VALUE (decls); *newval = BINDING_VALUE (decls);
if (oldval && oldval != *newval && !duplicate_decls (*newval, oldval)) if (oldval)
*newval = oldval; duplicate_decls (*newval, oldval);
} }
*newtype = BINDING_TYPE (decls); *newtype = BINDING_TYPE (decls);
...@@ -4563,27 +4568,28 @@ do_toplevel_using_decl (decl) ...@@ -4563,27 +4568,28 @@ do_toplevel_using_decl (decl)
return; return;
} }
/* Process a using-declaration at function scope. */
void void
do_local_using_decl (decl) do_local_using_decl (decl)
tree decl; tree decl;
{ {
tree scope, name; tree scope, name;
tree oldval, oldtype, newval, newtype; tree oldval, oldtype, newval, newtype;
decl = validate_nonmember_using_decl (decl, &scope, &name); decl = validate_nonmember_using_decl (decl, &scope, &name);
if (decl == NULL_TREE) if (decl == NULL_TREE)
return; return;
/* XXX nested values */ oldval = lookup_name_current_level (name);
oldval = IDENTIFIER_LOCAL_VALUE (name); oldtype = lookup_type_current_level (name);
/* XXX get local type */
oldtype = NULL_TREE;
do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
if (newval) if (newval)
/* XXX update bindings */ set_identifier_local_value (name, newval);
IDENTIFIER_LOCAL_VALUE (name) = newval; if (newtype)
/* XXX type */ set_identifier_type_value (name, newtype);
} }
tree tree
...@@ -4638,9 +4644,7 @@ do_using_directive (namespace) ...@@ -4638,9 +4644,7 @@ do_using_directive (namespace)
} }
namespace = ORIGINAL_NAMESPACE (namespace); namespace = ORIGINAL_NAMESPACE (namespace);
if (!toplevel_bindings_p ()) if (!toplevel_bindings_p ())
push_using_directive push_using_directive (namespace);
(namespace, namespace_ancestor (current_decl_namespace(),
current_namespace));
else else
/* direct usage */ /* direct usage */
add_using_namespace (current_namespace, namespace, 0); add_using_namespace (current_namespace, namespace, 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment