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
This commit is contained in:
parent
3cab3dc87e
commit
9ed182dca4
4 changed files with 115 additions and 49 deletions
|
@ -1,5 +1,19 @@
|
|||
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.
|
||||
* decl.c (select_decl): Extract a lone function from an OVERLOAD.
|
||||
(lookup_namespace_name): Likewise.
|
||||
|
|
|
@ -2379,7 +2379,7 @@ extern void pushdecl_nonclass_level PROTO((tree));
|
|||
#endif
|
||||
extern tree pushdecl_namespace_level PROTO((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 tree push_using_decl PROTO((tree, tree));
|
||||
extern tree implicitly_declare PROTO((tree));
|
||||
|
@ -2403,9 +2403,11 @@ extern tree lookup_name_nonclass PROTO((tree));
|
|||
extern tree lookup_function_nonclass PROTO((tree, tree));
|
||||
extern tree lookup_name PROTO((tree, int));
|
||||
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 void begin_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 qualified_lookup_using_namespace PROTO((tree,tree,tree,int));
|
||||
extern tree auto_function PROTO((tree, tree, enum built_in_function));
|
||||
|
|
112
gcc/cp/decl.c
112
gcc/cp/decl.c
|
@ -2159,6 +2159,26 @@ set_identifier_type_value (id, type)
|
|||
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. */
|
||||
|
||||
tree
|
||||
|
@ -2646,12 +2666,30 @@ duplicate_decls (newdecl, olddecl)
|
|||
}
|
||||
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
|
||||
&& DECL_FUNCTION_TEMPLATE_P (olddecl))
|
||||
|| (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_TEMPLATE_P (newdecl)))
|
||||
return 0;
|
||||
|
||||
|
||||
cp_error ("`%#D' redeclared as different kind of symbol", newdecl);
|
||||
if (TREE_CODE (olddecl) == TREE_LIST)
|
||||
olddecl = TREE_VALUE (olddecl);
|
||||
|
@ -3319,24 +3357,7 @@ pushdecl (x)
|
|||
}
|
||||
else if (TREE_CODE (t) != TREE_CODE (x))
|
||||
{
|
||||
if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (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))
|
||||
if (duplicate_decls (x, t))
|
||||
return t;
|
||||
}
|
||||
else if (duplicate_decls (x, t))
|
||||
|
@ -3519,10 +3540,7 @@ pushdecl (x)
|
|||
if (TREE_CODE (x) != TYPE_DECL
|
||||
|| t == NULL_TREE
|
||||
|| ! DECL_ARTIFICIAL (x))
|
||||
{
|
||||
b->shadowed = tree_cons (name, oldlocal, b->shadowed);
|
||||
IDENTIFIER_LOCAL_VALUE (name) = x;
|
||||
}
|
||||
set_identifier_local_value_with_scope (name, x, b);
|
||||
|
||||
/* If this is a TYPE_DECL, push it into the type value slot. */
|
||||
if (TREE_CODE (x) == TYPE_DECL)
|
||||
|
@ -3851,12 +3869,11 @@ push_using_decl (scope, name)
|
|||
TREE_LIST otherwise. */
|
||||
|
||||
tree
|
||||
push_using_directive (used, ancestor)
|
||||
push_using_directive (used)
|
||||
tree used;
|
||||
tree ancestor;
|
||||
{
|
||||
tree ud = current_binding_level->using_directives;
|
||||
tree iter;
|
||||
tree iter, ancestor;
|
||||
|
||||
/* Check if we already have this. */
|
||||
if (purpose_member (used, ud) != NULL_TREE)
|
||||
|
@ -3864,8 +3881,9 @@ push_using_directive (used, ancestor)
|
|||
|
||||
/* Recursively add all namespaces used. */
|
||||
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 = perm_tree_cons (used, ancestor, ud);
|
||||
current_binding_level->using_directives = ud;
|
||||
|
@ -4859,7 +4877,10 @@ qualify_lookup (val, flags)
|
|||
return val;
|
||||
if (LOOKUP_NAMESPACES_ONLY (flags) && TREE_CODE (val) != NAMESPACE_DECL)
|
||||
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 val;
|
||||
}
|
||||
|
@ -5133,16 +5154,41 @@ lookup_name_current_level (name)
|
|||
struct binding_level *b = current_binding_level;
|
||||
while (1)
|
||||
{
|
||||
for (t = b->names; t; t = TREE_CHAIN (t))
|
||||
if (DECL_NAME (t) == name || DECL_ASSEMBLER_NAME (t) == name)
|
||||
goto out;
|
||||
if (purpose_member (name, b->shadowed))
|
||||
return IDENTIFIER_LOCAL_VALUE (name);
|
||||
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)
|
||||
b = b->level_chain;
|
||||
else
|
||||
break;
|
||||
}
|
||||
out:
|
||||
;
|
||||
}
|
||||
|
||||
return t;
|
||||
|
|
|
@ -58,7 +58,6 @@ static int finish_vtable_vardecl PROTO((tree, tree));
|
|||
static int prune_vtable_vardecl PROTO((tree, tree));
|
||||
static void finish_sigtable_vardecl 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 tree ambiguous_decl PROTO((tree, tree, tree,int));
|
||||
static tree build_anon_union_vars PROTO((tree, tree*, int, int));
|
||||
|
@ -3839,7 +3838,7 @@ is_namespace_ancestor (root, child)
|
|||
/* Return the namespace that is the common ancestor
|
||||
of two given namespaces. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
namespace_ancestor (ns1, ns2)
|
||||
tree ns1, ns2;
|
||||
{
|
||||
|
@ -4495,10 +4494,16 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
|
|||
if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls)))
|
||||
{
|
||||
tree tmp, tmp1;
|
||||
|
||||
if (oldval && !is_overloaded_fn (oldval))
|
||||
{
|
||||
duplicate_decls (OVL_CURRENT (BINDING_VALUE (decls)), oldval);
|
||||
oldval = NULL_TREE;
|
||||
}
|
||||
|
||||
*newval = oldval;
|
||||
for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
|
||||
{
|
||||
|
||||
/* Compare each new function with each old one.
|
||||
If the old function was also used, there is no conflict. */
|
||||
for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
|
||||
|
@ -4522,8 +4527,8 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
|
|||
else
|
||||
{
|
||||
*newval = BINDING_VALUE (decls);
|
||||
if (oldval && oldval != *newval && !duplicate_decls (*newval, oldval))
|
||||
*newval = oldval;
|
||||
if (oldval)
|
||||
duplicate_decls (*newval, oldval);
|
||||
}
|
||||
|
||||
*newtype = BINDING_TYPE (decls);
|
||||
|
@ -4563,27 +4568,28 @@ do_toplevel_using_decl (decl)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Process a using-declaration at function scope. */
|
||||
|
||||
void
|
||||
do_local_using_decl (decl)
|
||||
tree decl;
|
||||
{
|
||||
tree scope, name;
|
||||
tree oldval, oldtype, newval, newtype;
|
||||
|
||||
decl = validate_nonmember_using_decl (decl, &scope, &name);
|
||||
if (decl == NULL_TREE)
|
||||
return;
|
||||
|
||||
/* XXX nested values */
|
||||
oldval = IDENTIFIER_LOCAL_VALUE (name);
|
||||
/* XXX get local type */
|
||||
oldtype = NULL_TREE;
|
||||
oldval = lookup_name_current_level (name);
|
||||
oldtype = lookup_type_current_level (name);
|
||||
|
||||
do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
|
||||
|
||||
if (newval)
|
||||
/* XXX update bindings */
|
||||
IDENTIFIER_LOCAL_VALUE (name) = newval;
|
||||
/* XXX type */
|
||||
set_identifier_local_value (name, newval);
|
||||
if (newtype)
|
||||
set_identifier_type_value (name, newtype);
|
||||
}
|
||||
|
||||
tree
|
||||
|
@ -4638,9 +4644,7 @@ do_using_directive (namespace)
|
|||
}
|
||||
namespace = ORIGINAL_NAMESPACE (namespace);
|
||||
if (!toplevel_bindings_p ())
|
||||
push_using_directive
|
||||
(namespace, namespace_ancestor (current_decl_namespace(),
|
||||
current_namespace));
|
||||
push_using_directive (namespace);
|
||||
else
|
||||
/* direct usage */
|
||||
add_using_namespace (current_namespace, namespace, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue