From: Jason Merrill Date: Thu, 16 Jul 1998 21:16:06 +0000 (+0000) Subject: decl.c (qualify_lookup): Handle templates. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9ed182dca4ff768a67d63b6070067d5fd6fa4854;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 85e8e05490c..20e6653c630 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,19 @@ 1998-07-16 Jason Merrill + * 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. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3f8840a7609..f6c1e23bdd6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8071386c22a..478d75b0e01 100644 --- a/gcc/cp/decl.c +++ b/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; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5384e98e066..6713c65834b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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);