diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-07-14 15:34:30 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-07-14 15:34:30 +0000 |
commit | 90ea9897a0940659bc41355d41573fde6c35617a (patch) | |
tree | 5c6490013ea86502c34dbabd84c9be78d2ebd025 /gcc/cp | |
parent | 95674810682ca0c2862094c96cdfa5537113693c (diff) | |
download | gcc-90ea9897a0940659bc41355d41573fde6c35617a.zip gcc-90ea9897a0940659bc41355d41573fde6c35617a.tar.gz gcc-90ea9897a0940659bc41355d41573fde6c35617a.tar.bz2 |
cp-tree.h (IDENTIFIER_VALUE): Remove.
* cp-tree.h (IDENTIFIER_VALUE): Remove.
(BINFO_PUSHDECLS_MARKED): Likewise.
(maybe_inject_for_scope_var): Likewise.
(push_class_decls): Likewise.
* name-lookup.h (push_class_binding): Remove.
(innermost_non_namespace_value): New function.
(outer_binding): Likewise.
* class.c (add_method): Push bindings before adding to
TYPE_METHODS.
(restore_class_cache): Do not restore class_shadowed.
(pushclass): Do not add USING_DECLs. Do not call
push_class_decls.
* config-lang.in (gtfiles): Remove $(srcdir)/cp/search.c.
* decl.c (pushdecl): Use outer_binding.
(poplevel): Set the scope for an out-of-scope for-loop declaration
appropriately.
(cp_finish_decl): Don't call maybe_inject_for_scope_var.
* name-lookup.c (new_class_binding): New function.
(push_binding): Use it.
(pushdecl): Use innermost_non_namespace_value.
(maybe_inject_for_scope_var): Remove.
(push_class_binding): Remove.
(set_inherited_value_binding_p): New function.
(get_class_binding): New function.
(push_class_level_binding): Assert that the current_class_type is
being defined.
(outer_binding): New function.
(innermost_non_namespace_value): Likewise.
(lookup_name_real): Use outer_binding.
(lookup_name_current_level): Ignore out-of-scope variables.
* pt.c (check_template_shadow): Use innermost_non_namespace_value.
(lookup_template_class): Likewise.
* search.c (dfs_push_type_decls): Remove.
(dfs_push_decls): Likewise.
(setup_class_bindings): Likewise.
(lookup_field_1): Handle USING_DECLs from dependent scopes.
(marked_pushdecls_p): Remove.
(unmarked_pushdecls_p): Remove.
(marked_identifiers): Remove.
(setup_class_bindings): Remove.
(dfs_push_type_decls): Remove.
(dfs_push_decls): Remove.
(push_class_decls): Remove.
From-SVN: r84689
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 46 | ||||
-rw-r--r-- | gcc/cp/class.c | 43 | ||||
-rw-r--r-- | gcc/cp/config-lang.in | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 30 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 438 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 14 | ||||
-rw-r--r-- | gcc/cp/search.c | 229 |
9 files changed, 371 insertions, 445 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0cf8261..df264d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,49 @@ +2004-07-14 Mark Mitchell <mark@codesourcery.com> + + * cp-tree.h (IDENTIFIER_VALUE): Remove. + (BINFO_PUSHDECLS_MARKED): Likewise. + (maybe_inject_for_scope_var): Likewise. + (push_class_decls): Likewise. + * name-lookup.h (push_class_binding): Remove. + (innermost_non_namespace_value): New function. + (outer_binding): Likewise. + * class.c (add_method): Push bindings before adding to + TYPE_METHODS. + (restore_class_cache): Do not restore class_shadowed. + (pushclass): Do not add USING_DECLs. Do not call + push_class_decls. + * config-lang.in (gtfiles): Remove $(srcdir)/cp/search.c. + * decl.c (pushdecl): Use outer_binding. + (poplevel): Set the scope for an out-of-scope for-loop declaration + appropriately. + (cp_finish_decl): Don't call maybe_inject_for_scope_var. + * name-lookup.c (new_class_binding): New function. + (push_binding): Use it. + (pushdecl): Use innermost_non_namespace_value. + (maybe_inject_for_scope_var): Remove. + (push_class_binding): Remove. + (set_inherited_value_binding_p): New function. + (get_class_binding): New function. + (push_class_level_binding): Assert that the current_class_type is + being defined. + (outer_binding): New function. + (innermost_non_namespace_value): Likewise. + (lookup_name_real): Use outer_binding. + (lookup_name_current_level): Ignore out-of-scope variables. + * pt.c (check_template_shadow): Use innermost_non_namespace_value. + (lookup_template_class): Likewise. + * search.c (dfs_push_type_decls): Remove. + (dfs_push_decls): Likewise. + (setup_class_bindings): Likewise. + (lookup_field_1): Handle USING_DECLs from dependent scopes. + (marked_pushdecls_p): Remove. + (unmarked_pushdecls_p): Remove. + (marked_identifiers): Remove. + (setup_class_bindings): Remove. + (dfs_push_type_decls): Remove. + (dfs_push_decls): Remove. + (push_class_decls): Remove. + 2004-07-13 Mark Mitchell <mark@codesourcery.com> PR c++/16518 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 907503d..b292255f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -807,6 +807,7 @@ add_method (tree type, tree method, int error_p) int len; int slot; tree method_vec; + tree overload; int template_conv_p; if (method == error_mark_node) @@ -1025,15 +1026,14 @@ add_method (tree type, tree method, int error_p) } } - /* Actually insert the new method. */ - TREE_VEC_ELT (method_vec, slot) - = build_overload (method, TREE_VEC_ELT (method_vec, slot)); - /* Add the new binding. */ + overload = build_overload (method, TREE_VEC_ELT (method_vec, slot)); if (!DECL_CONSTRUCTOR_P (method) && !DECL_DESTRUCTOR_P (method)) - push_class_level_binding (DECL_NAME (method), - TREE_VEC_ELT (method_vec, slot)); + push_class_level_binding (DECL_NAME (method), overload); + + /* Actually insert the new method. */ + TREE_VEC_ELT (method_vec, slot) = overload; } /* Subroutines of finish_struct. */ @@ -5484,9 +5484,7 @@ init_class_processing (void) static void restore_class_cache (void) { - cp_class_binding *cb; tree type; - size_t i; /* We are re-entering the same class we just left, so we don't have to search the whole inheritance matrix to find all the @@ -5494,18 +5492,6 @@ restore_class_cache (void) class_shadowed list and walk through it binding names. */ push_binding_level (previous_class_level); class_binding_level = previous_class_level; - for (i = 0; - (cb = VEC_iterate (cp_class_binding, - previous_class_level->class_shadowed, - i)); - ++i) - { - tree id; - - id = cb->identifier; - cb->base.previous = IDENTIFIER_BINDING (id); - IDENTIFIER_BINDING (id) = &cb->base; - } /* Restore IDENTIFIER_TYPE_VALUE. */ for (type = class_binding_level->type_shadowed; type; @@ -5567,22 +5553,7 @@ pushclass (tree type) if (!previous_class_level || type != previous_class_level->this_entity || current_class_depth > 1) - { - pushlevel_class (); - push_class_decls (type); - if (CLASSTYPE_TEMPLATE_INFO (type) && !CLASSTYPE_USE_TEMPLATE (type)) - { - /* If we are entering the scope of a template declaration (not a - specialization), we need to push all the using decls with - dependent scope too. */ - tree fields; - - for (fields = TYPE_FIELDS (type); - fields; fields = TREE_CHAIN (fields)) - if (TREE_CODE (fields) == USING_DECL && !TREE_TYPE (fields)) - pushdecl_class_level (fields); - } - } + pushlevel_class (); else restore_class_cache (); diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index 48b88d7..563cfb4 100644 --- a/gcc/cp/config-lang.in +++ b/gcc/cp/config-lang.in @@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" target_libs="target-libstdc++-v3 target-gperf" -gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/search.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-lex.c \$(srcdir)/c-pragma.c" +gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-lex.c \$(srcdir)/c-pragma.c" diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6e5dfdf..95c633a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -334,11 +334,6 @@ typedef enum cp_id_kind #define IDENTIFIER_BINDING(NODE) \ (LANG_IDENTIFIER_CAST (NODE)->bindings) -/* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or - NULL_TREE if there is no binding. */ -#define IDENTIFIER_VALUE(NODE) \ - (IDENTIFIER_BINDING (NODE) ? IDENTIFIER_BINDING (NODE)->value : NULL) - /* TREE_TYPE only indicates on local and class scope the current type. For namespace scope, the presence of a type in any namespace is indicated with global_type_node, and the real type behind must @@ -1388,9 +1383,6 @@ struct lang_type GTY(()) my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \ 20000517)) -/* Nonzero means this class has done dfs_pushdecls. */ -#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE) - /* Nonzero if this BINFO is a primary base class. */ #define BINFO_PRIMARY_P(NODE) \ @@ -3708,7 +3700,6 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, extern void start_decl_1 (tree); extern void cp_finish_decl (tree, tree, tree, int); extern void finish_decl (tree, tree, tree); -extern void maybe_inject_for_scope_var (tree); extern int complete_array_type (tree, tree, int); extern tree build_ptrmemfunc_type (tree); extern tree build_ptrmem_type (tree, tree); @@ -4003,7 +3994,6 @@ extern int look_for_overrides (tree, tree); extern void get_pure_virtuals (tree); extern void maybe_suppress_debug_info (tree); extern void note_debug_info_needed (tree); -extern void push_class_decls (tree); extern void print_search_statistics (void); extern void reinit_search_statistics (void); extern tree current_scope (void); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 39e4d55..7277343 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -540,17 +540,19 @@ poplevel (int keep, int reverse, int functionbody) if (leaving_for_scope && TREE_CODE (link) == VAR_DECL && DECL_NAME (link)) { - cxx_binding *outer_binding - = IDENTIFIER_BINDING (DECL_NAME (link))->previous; + tree name = DECL_NAME (link); + cxx_binding *ob; tree ns_binding; - if (!outer_binding) - ns_binding = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (link)); + ob = outer_binding (name, + IDENTIFIER_BINDING (name), + /*class_p=*/true); + if (!ob) + ns_binding = IDENTIFIER_NAMESPACE_VALUE (name); else ns_binding = NULL_TREE; - if (outer_binding - && outer_binding->scope == current_binding_level->level_chain) + if (ob && ob->scope == current_binding_level->level_chain) /* We have something like: int i; @@ -558,9 +560,8 @@ poplevel (int keep, int reverse, int functionbody) and we are leaving the `for' scope. There's no reason to keep the binding of the inner `i' in this case. */ - pop_binding (DECL_NAME (link), link); - else if ((outer_binding - && (TREE_CODE (outer_binding->value) == TYPE_DECL)) + pop_binding (name, link); + else if ((ob && (TREE_CODE (ob->value) == TYPE_DECL)) || (ns_binding && TREE_CODE (ns_binding) == TYPE_DECL)) /* Here, we have something like: @@ -572,7 +573,7 @@ poplevel (int keep, int reverse, int functionbody) We must pop the for-scope binding so we know what's a type and what isn't. */ - pop_binding (DECL_NAME (link), link); + pop_binding (name, link); else { /* Mark this VAR_DECL as dead so that we can tell we left it @@ -581,8 +582,8 @@ poplevel (int keep, int reverse, int functionbody) /* Keep track of what should have happened when we popped the binding. */ - if (outer_binding && outer_binding->value) - DECL_SHADOWED_FOR_VAR (link) = outer_binding->value; + if (ob && ob->value) + DECL_SHADOWED_FOR_VAR (link) = ob->value; /* Add it to the list of dead variables in the next outermost binding to that we can remove these when we @@ -594,7 +595,8 @@ poplevel (int keep, int reverse, int functionbody) /* Although we don't pop the cxx_binding, we do clear its SCOPE since the scope is going away now. */ - IDENTIFIER_BINDING (DECL_NAME (link))->scope = NULL; + IDENTIFIER_BINDING (name)->scope + = current_binding_level->level_chain; } } else @@ -4846,8 +4848,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) /* A variable definition. */ if (DECL_FUNCTION_SCOPE_P (decl)) { - /* This is a local declaration. */ - maybe_inject_for_scope_var (decl); /* Initialize the local variable. */ if (processing_template_decl) { diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 1511ff9..0aff14b 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -368,40 +368,65 @@ cxx_binding_free (cxx_binding *binding) free_bindings = binding; } -/* Make DECL the innermost binding for ID. The LEVEL is the binding - level at which this declaration is being bound. */ +/* Create a new binding for NAME (with the indicated VALUE and TYPE + bindings) in the class scope indicated by SCOPE. */ -static void -push_binding (tree id, tree decl, cxx_scope* level) +static cxx_binding * +new_class_binding (tree name, tree value, tree type, cxx_scope *scope) { + cp_class_binding *cb; cxx_binding *binding; - - if (level != class_binding_level) - binding = cxx_binding_make (decl, NULL_TREE); - else + + if (VEC_length (cp_class_binding, scope->class_shadowed)) { - cp_class_binding *cb; - - if (VEC_reserve (cp_class_binding, level->class_shadowed, -1)) + cp_class_binding *old_base; + old_base = VEC_index (cp_class_binding, scope->class_shadowed, 0); + if (VEC_reserve (cp_class_binding, scope->class_shadowed, -1)) { /* Fixup the current bindings, as they might have moved. */ size_t i; for (i = 0; - (cb = VEC_iterate (cp_class_binding, level->class_shadowed, i)); + (cb = VEC_iterate (cp_class_binding, scope->class_shadowed, i)); i++) - IDENTIFIER_BINDING (cb->identifier) = &cb->base; + { + cxx_binding **b; + b = &IDENTIFIER_BINDING (cb->identifier); + while (*b != &old_base[i].base) + b = &((*b)->previous); + *b = &cb->base; + } } + cb = VEC_quick_push (cp_class_binding, scope->class_shadowed, NULL); + } + else + cb = VEC_safe_push (cp_class_binding, scope->class_shadowed, NULL); + + cb->identifier = name; + binding = &cb->base; + binding->scope = scope; + cxx_binding_init (binding, value, type); + return binding; +} + +/* Make DECL the innermost binding for ID. The LEVEL is the binding + level at which this declaration is being bound. */ + +static void +push_binding (tree id, tree decl, cxx_scope* level) +{ + cxx_binding *binding; - cb = VEC_quick_push (cp_class_binding, level->class_shadowed, NULL); - cb->identifier = id; - binding = &cb->base; - cxx_binding_init (binding, decl, NULL_TREE); + if (level != class_binding_level) + { + binding = cxx_binding_make (decl, NULL_TREE); + binding->scope = level; } + else + binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level); /* Now, fill in the binding information. */ binding->previous = IDENTIFIER_BINDING (id); - binding->scope = level; INHERITED_VALUE_BINDING_P (binding) = 0; LOCAL_BINDING_P (binding) = (level != class_binding_level); @@ -665,7 +690,7 @@ pushdecl (tree x) && DECL_EXTERNAL (x)) { /* Look in block scope. */ - t = IDENTIFIER_VALUE (name); + t = innermost_non_namespace_value (name); /* Or in the innermost namespace. */ if (! t) t = namespace_binding (name, DECL_CONTEXT (x)); @@ -893,7 +918,7 @@ pushdecl (tree x) else { /* Here to install a non-global value. */ - tree oldlocal = IDENTIFIER_VALUE (name); + tree oldlocal = innermost_non_namespace_value (name); tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name); if (need_new_binding) @@ -1113,59 +1138,6 @@ push_local_binding (tree id, tree decl, int flags) add_decl_to_level (decl, b); } -/* The old ARM scoping rules injected variables declared in the - initialization statement of a for-statement into the surrounding - scope. We support this usage, in order to be backward-compatible. - DECL is a just-declared VAR_DECL; if necessary inject its - declaration into the surrounding scope. */ - -void -maybe_inject_for_scope_var (tree decl) -{ - timevar_push (TV_NAME_LOOKUP); - if (!DECL_NAME (decl)) - { - timevar_pop (TV_NAME_LOOKUP); - return; - } - - /* Declarations of __FUNCTION__ and its ilk appear magically when - the variable is first used. If that happens to be inside a - for-loop, we don't want to do anything special. */ - if (DECL_PRETTY_FUNCTION_P (decl)) - { - timevar_pop (TV_NAME_LOOKUP); - return; - } - - if (current_binding_level->kind == sk_for) - { - struct cp_binding_level *outer - = current_binding_level->level_chain; - - /* Check to see if the same name is already bound at the outer - level, either because it was directly declared, or because a - dead for-decl got preserved. In either case, the code would - not have been valid under the ARM scope rules, so clear - is_for_scope for the current_binding_level. - - Otherwise, we need to preserve the temp slot for decl to last - into the outer binding level. */ - - cxx_binding *outer_binding - = IDENTIFIER_BINDING (DECL_NAME (decl))->previous; - - if (outer_binding && outer_binding->scope == outer - && (TREE_CODE (outer_binding->value) == VAR_DECL) - && DECL_DEAD_FOR_LOCAL (outer_binding->value)) - { - outer_binding->value = DECL_SHADOWED_FOR_VAR (outer_binding->value); - current_binding_level->kind = sk_block; - } - } - timevar_pop (TV_NAME_LOOKUP); -} - /* Check to see whether or not DECL is a variable that would have been in scope under the ARM, but is not in scope under the ANSI/ISO standard. If so, issue an error message. If name lookup would @@ -2647,10 +2619,15 @@ poplevel_class (void) SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed)); /* Remove the bindings for all of the class-level declarations. */ - for (i = 0; - (cb = VEC_iterate (cp_class_binding, level->class_shadowed, i)); - ++i) - IDENTIFIER_BINDING (cb->identifier) = cb->base.previous; + if (level->class_shadowed) + { + for (i = 0; + (cb = VEC_iterate (cp_class_binding, level->class_shadowed, i)); + ++i) + IDENTIFIER_BINDING (cb->identifier) = cb->base.previous; + ggc_free (level->class_shadowed); + level->class_shadowed = NULL; + } /* Now, pop out of the binding level which we created up in the `pushlevel_class' routine. */ @@ -2661,33 +2638,17 @@ poplevel_class (void) timevar_pop (TV_NAME_LOOKUP); } -/* Bind DECL to ID in the class_binding_level. Returns nonzero if the - binding was successful. */ +/* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as + appropriate. DECL is the value to which a name has just been + bound. */ -int -push_class_binding (tree id, tree decl) +static void +set_inherited_value_binding_p (cxx_binding *binding, tree decl) { - int result = 1; - cxx_binding *binding = IDENTIFIER_BINDING (id); - tree context; - - timevar_push (TV_NAME_LOOKUP); - /* Note that we declared this value so that we can issue an error if - this is an invalid redeclaration of a name already used for some - other purpose. */ - note_name_declared_in_class (id, decl); - - if (binding && binding->scope == class_binding_level) - /* Supplement the existing binding. */ - result = supplement_binding (IDENTIFIER_BINDING (id), decl); - else - /* Create a new binding. */ - push_binding (id, decl, class_binding_level); - - /* If this is a binding from a base class, mark it as such. */ - binding = IDENTIFIER_BINDING (id); if (binding->value == decl && TREE_CODE (decl) != TREE_LIST) { + tree context; + if (TREE_CODE (decl) == OVERLOAD) context = CP_DECL_CONTEXT (OVL_CURRENT (decl)); else @@ -2702,12 +2663,12 @@ push_class_binding (tree id, tree decl) INHERITED_VALUE_BINDING_P (binding) = 0; } else if (binding->value == decl) - /* We only encounter a TREE_LIST when push_class_decls detects an - ambiguity. Such an ambiguity can be overridden by a definition - in this class. */ + /* We only encounter a TREE_LIST when there is an ambiguity in the + base classes. Such an ambiguity can be overridden by a + definition in this class. */ INHERITED_VALUE_BINDING_P (binding) = 1; - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result); + else + INHERITED_VALUE_BINDING_P (binding) = 0; } /* Make the declaration of X appear in CLASS scope. */ @@ -2752,6 +2713,67 @@ pushdecl_class_level (tree x) return is_valid; } +/* Return the BINDING (if any) for NAME in SCOPE, which is a class + scope. If the value returned is non-NULL, and the PREVIOUS field + is not set, callers must set the PREVIOUS field explicitly. */ + +static cxx_binding * +get_class_binding (tree name, cxx_scope *scope) +{ + tree class_type; + tree type_binding; + tree value_binding; + cxx_binding *binding; + + class_type = scope->this_entity; + + /* Get the type binding. */ + type_binding = lookup_member (class_type, name, + /*protect=*/2, /*want_type=*/true); + /* Get the value binding. */ + value_binding = lookup_member (class_type, name, + /*protect=*/2, /*want_type=*/false); + + if (value_binding + && (TREE_CODE (value_binding) == TYPE_DECL + || DECL_CLASS_TEMPLATE_P (value_binding) + || (TREE_CODE (value_binding) == TREE_LIST + && TREE_TYPE (value_binding) == error_mark_node + && (TREE_CODE (TREE_VALUE (value_binding)) + == TYPE_DECL)))) + /* We found a type binding, even when looking for a non-type + binding. This means that we already processed this binding + above. */ + ; + else if (value_binding) + { + if (TREE_CODE (value_binding) == TREE_LIST + && TREE_TYPE (value_binding) == error_mark_node) + /* NAME is ambiguous. */ + ; + else if (BASELINK_P (value_binding)) + /* NAME is some overloaded functions. */ + value_binding = BASELINK_FUNCTIONS (value_binding); + } + + /* If we found either a type binding or a value binding, create a + new binding object. */ + if (type_binding || value_binding) + { + binding = new_class_binding (name, + value_binding, + type_binding, + scope); + /* This is a class-scope binding, not a block-scope binding. */ + LOCAL_BINDING_P (binding) = 0; + set_inherited_value_binding_p (binding, value_binding); + } + else + binding = NULL; + + return binding; +} + /* Make the declaration(s) of X appear in CLASS scope under the name NAME. Returns true if the binding is valid. */ @@ -2759,6 +2781,8 @@ bool push_class_level_binding (tree name, tree x) { cxx_binding *binding; + tree decl = x; + bool ok; timevar_push (TV_NAME_LOOKUP); /* The class_binding_level will be NULL if x is a template @@ -2766,64 +2790,69 @@ push_class_level_binding (tree name, tree x) if (!class_binding_level) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); - /* Check for invalid member names, if the class is being defined. - This function is also used to restore bindings when reentering - the class scope, and there is no point in checking again at that - time. */ - if (TYPE_BEING_DEFINED (current_class_type)) - { - tree decl = x; - - /* We could have been passed a tree list if this is an ambiguous - declaration. If so, pull the declaration out because - check_template_shadow will not handle a TREE_LIST. */ - if (TREE_CODE (decl) == TREE_LIST - && TREE_TYPE (decl) == error_mark_node) - decl = TREE_VALUE (decl); - - check_template_shadow (decl); + /* Check for invalid member names. */ + my_friendly_assert (TYPE_BEING_DEFINED (current_class_type), 20040713); + /* We could have been passed a tree list if this is an ambiguous + declaration. If so, pull the declaration out because + check_template_shadow will not handle a TREE_LIST. */ + if (TREE_CODE (decl) == TREE_LIST + && TREE_TYPE (decl) == error_mark_node) + decl = TREE_VALUE (decl); - /* [class.mem] + check_template_shadow (decl); - If T is the name of a class, then each of the following shall - have a name different from T: + /* [class.mem] - -- every static data member of class T; + If T is the name of a class, then each of the following shall + have a name different from T: - -- every member of class T that is itself a type; + -- every static data member of class T; - -- every enumerator of every member of class T that is an - enumerated type; + -- every member of class T that is itself a type; - -- every member of every anonymous union that is a member of - class T. + -- every enumerator of every member of class T that is an + enumerated type; - (Non-static data members were also forbidden to have the same - name as T until TC1.) */ - if ((TREE_CODE (x) == VAR_DECL - || TREE_CODE (x) == CONST_DECL - || (TREE_CODE (x) == TYPE_DECL - && !DECL_SELF_REFERENCE_P (x)) - /* A data member of an anonymous union. */ - || (TREE_CODE (x) == FIELD_DECL - && DECL_CONTEXT (x) != current_class_type)) - && DECL_NAME (x) == constructor_name (current_class_type)) + -- every member of every anonymous union that is a member of + class T. + + (Non-static data members were also forbidden to have the same + name as T until TC1.) */ + if ((TREE_CODE (x) == VAR_DECL + || TREE_CODE (x) == CONST_DECL + || (TREE_CODE (x) == TYPE_DECL + && !DECL_SELF_REFERENCE_P (x)) + /* A data member of an anonymous union. */ + || (TREE_CODE (x) == FIELD_DECL + && DECL_CONTEXT (x) != current_class_type)) + && DECL_NAME (x) == constructor_name (current_class_type)) + { + tree scope = context_for_name_lookup (x); + if (TYPE_P (scope) && same_type_p (scope, current_class_type)) { - tree scope = context_for_name_lookup (x); - if (TYPE_P (scope) && same_type_p (scope, current_class_type)) - { - error ("`%D' has the same name as the class in which it is " - "declared", - x); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); - } + error ("`%D' has the same name as the class in which it is " + "declared", + x); + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); } } - /* If this declaration shadows a declaration from an enclosing - class, then we will need to restore bindings when we leave this - class. Record the shadowed declaration here. */ + /* Get the current binding for NAME in this class, if any. */ binding = IDENTIFIER_BINDING (name); + if (!binding || binding->scope != class_binding_level) + { + binding = get_class_binding (name, class_binding_level); + /* If a new binding was created, put it at the front of the + IDENTIFIER_BINDING list. */ + if (binding) + { + binding->previous = IDENTIFIER_BINDING (name); + IDENTIFIER_BINDING (name) = binding; + } + } + + /* If there is already a binding, then we may need to update the + current value. */ if (binding && binding->value) { tree bval = binding->value; @@ -2855,8 +2884,7 @@ push_class_level_binding (tree name, tree x) else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x)) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); - if (old_decl - && binding->scope == class_binding_level) + if (old_decl && binding->scope == class_binding_level) { binding->value = x; /* It is always safe to clear INHERITED_VALUE_BINDING_P @@ -2872,12 +2900,29 @@ push_class_level_binding (tree name, tree x) } } + /* Note that we declared this value so that we can issue an error if + this is an invalid redeclaration of a name already used for some + other purpose. */ + note_name_declared_in_class (name, decl); + /* If we didn't replace an existing binding, put the binding on the - stack of bindings for the identifier, and update the shadowed list. */ - if (push_class_binding (name, x)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + stack of bindings for the identifier, and update the shadowed + list. */ + if (binding && binding->scope == class_binding_level) + /* Supplement the existing binding. */ + ok = supplement_binding (binding, decl); + else + { + /* Create a new binding. */ + push_binding (name, decl, class_binding_level); + ok = true; + } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + /* Determine whether or not this binding is from a base class. */ + binding = IDENTIFIER_BINDING (name); + set_inherited_value_binding_p (binding, decl); + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); } tree @@ -3929,6 +3974,73 @@ qualified_lookup_using_namespace (tree name, tree scope, POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node); } +/* 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. */ + +cxx_binding * +outer_binding (tree name, + cxx_binding *binding, + bool class_p) +{ + cxx_binding *outer; + cxx_scope *scope; + cxx_scope *outer_scope; + + if (binding) + { + scope = binding->scope->level_chain; + outer = binding->previous; + } + else + { + scope = current_binding_level; + outer = IDENTIFIER_BINDING (name); + } + outer_scope = outer ? outer->scope : NULL; + + /* Because we create class bindings lazily, we might be missing a + class binding for NAME. If there are any class binding levels + between the LAST_BINDING_LEVEL and the scope in which OUTER was + declared, we must lookup NAME in those class scopes. */ + if (class_p) + while (scope && scope != outer_scope && scope->kind != sk_namespace) + { + if (scope->kind == sk_class) + { + cxx_binding *class_binding; + + class_binding = get_class_binding (name, scope); + if (class_binding) + { + /* Thread this new class-scope binding onto the + IDENTIFIER_BINDING list so that future lookups + find it quickly. */ + class_binding->previous = outer; + if (binding) + binding->previous = class_binding; + else + IDENTIFIER_BINDING (name) = class_binding; + return class_binding; + } + } + scope = scope->level_chain; + } + + return outer; +} + +/* Return the innermost block-scope or class-scope value binding for + NAME, or NULL_TREE if there is no such binding. */ + +tree +innermost_non_namespace_value (tree name) +{ + cxx_binding *binding; + binding = outer_binding (name, /*binding=*/NULL, /*class_p=*/true); + return binding ? binding->value : NULL_TREE; +} + /* Look up NAME in the current binding level and its superiors in the namespace of variables, functions and typedefs. Return a ..._DECL node of some kind representing its definition if there is only one @@ -3987,7 +4099,9 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, nonclass = 1; if (block_p || !nonclass) - for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous) + for (iter = outer_binding (name, NULL, !nonclass); + iter; + iter = outer_binding (name, iter, !nonclass)) { tree binding; @@ -4075,10 +4189,14 @@ lookup_name_current_level (tree name) else if (IDENTIFIER_BINDING (name) && LOCAL_BINDING_P (IDENTIFIER_BINDING (name))) { + cxx_binding *binding; + binding = IDENTIFIER_BINDING (name); while (1) { - if (IDENTIFIER_BINDING (name)->scope == b) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name)); + if (binding->scope == b + && !(TREE_CODE (binding->value) == VAR_DECL + && DECL_DEAD_FOR_LOCAL (binding->value))) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding->value); if (b->kind == sk_cleanup) b = b->level_chain; diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 8d60f39..892303b 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -310,7 +310,6 @@ extern tree lookup_qualified_name (tree, tree, bool, bool); extern tree lookup_name_nonclass (tree); extern tree lookup_function_nonclass (tree, tree, bool); extern void push_local_binding (tree, tree, int); -extern int push_class_binding (tree, tree); extern bool pushdecl_class_level (tree); extern tree pushdecl_namespace_level (tree); extern bool push_class_level_binding (tree, tree); @@ -329,7 +328,8 @@ extern void do_using_directive (tree); extern tree lookup_arg_dependent (tree, tree, tree); extern bool is_associated_namespace (tree, tree); extern void parse_using_directive (tree, tree); - +extern tree innermost_non_namespace_value (tree); +extern cxx_binding *outer_binding (tree, cxx_binding *, bool); /* Set *DECL to the (non-hidden) declaration for ID at global scope, if present and return true; otherwise return false. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3d46883..6dd3c64 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2075,7 +2075,7 @@ check_template_shadow (tree decl) /* Figure out what we're shadowing. */ if (TREE_CODE (decl) == OVERLOAD) decl = OVL_CURRENT (decl); - olddecl = IDENTIFIER_VALUE (DECL_NAME (decl)); + olddecl = innermost_non_namespace_value (DECL_NAME (decl)); /* If there's no previous binding for this name, we're not shadowing anything, let alone a template parameter. */ @@ -4156,9 +4156,9 @@ lookup_template_class (tree d1, if (TREE_CODE (d1) == IDENTIFIER_NODE) { - if (IDENTIFIER_VALUE (d1) - && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1))) - template = IDENTIFIER_VALUE (d1); + tree value = innermost_non_namespace_value (d1); + if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value)) + template = value; else { if (context) @@ -4200,11 +4200,7 @@ lookup_template_class (tree d1, context = DECL_CONTEXT (template); } - /* With something like `template <class T> class X class X { ... };' - we could end up with D1 having nothing but an IDENTIFIER_VALUE. - We don't want to do that, but we have to deal with the situation, - so let's give them some syntax errors to chew on instead of a - crash. Alternatively D1 might not be a template type at all. */ + /* Issue an error message if we didn't find a template. */ if (! template) { if (complain & tf_error) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 460b2408..506c581 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -49,12 +49,8 @@ static tree dfs_check_overlap (tree, void *); static tree dfs_no_overlap_yet (tree, int, void *); static base_kind lookup_base_r (tree, tree, base_access, bool, tree *); static int dynamic_cast_base_recurse (tree, tree, bool, tree *); -static tree marked_pushdecls_p (tree, int, void *); -static tree unmarked_pushdecls_p (tree, int, void *); static tree dfs_debug_unmarkedp (tree, int, void *); static tree dfs_debug_mark (tree, void *); -static tree dfs_push_type_decls (tree, void *); -static tree dfs_push_decls (tree, void *); static tree add_conversions (tree, void *); static int look_for_overrides_r (tree, tree); static tree bfs_walk (tree, tree (*) (tree, void *), @@ -68,7 +64,6 @@ static tree dfs_access_in_type (tree, void *); static access_kind access_in_type (tree, tree); static int protected_accessible_p (tree, tree, tree); static int friend_accessible_p (tree, tree, tree); -static void setup_class_bindings (tree, int); static int template_self_reference_p (tree, tree); static tree dfs_get_pure_virtuals (tree, void *); @@ -455,12 +450,23 @@ lookup_field_1 (tree type, tree name, bool want_type) return temp; } if (TREE_CODE (field) == USING_DECL) - /* For now, we're just treating member using declarations as - old ARM-style access declarations. Thus, there's no reason - to return a USING_DECL, and the rest of the compiler can't - handle it. Once the class is defined, these are purged - from TYPE_FIELDS anyhow; see handle_using_decl. */ - continue; + { + /* We generally treat class-scope using-declarations as + ARM-style access specifications, because support for the + ISO semantics has not been implemented. So, in general, + there's no reason to return a USING_DECL, and the rest of + the compiler cannot handle that. Once the class is + defined, USING_DECLs are purged from TYPE_FIELDS; see + handle_using_decl. However, we make special efforts to + make using-declarations in template classes work + correctly. */ + if (CLASSTYPE_TEMPLATE_INFO (type) + && !CLASSTYPE_USE_TEMPLATE (type) + && !TREE_TYPE (field)) + ; + else + continue; + } if (DECL_NAME (field) == name && (!want_type @@ -1912,24 +1918,6 @@ unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED) return !BINFO_MARKED (binfo) ? binfo : NULL_TREE; } -static tree -marked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) -{ - tree binfo = BINFO_BASE_BINFO (derived, ix); - - return (!BINFO_DEPENDENT_BASE_P (binfo) - && BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE; -} - -static tree -unmarked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) -{ - tree binfo = BINFO_BASE_BINFO (derived, ix); - - return (!BINFO_DEPENDENT_BASE_P (binfo) - && !BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE; -} - /* The worker functions for `dfs_walk'. These do not need to test anything (vis a vis marking) if they are paired with a predicate function (above). */ @@ -2032,188 +2020,6 @@ note_debug_info_needed (tree type) dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp, 0); } -/* A vector of IDENTIFIER_NODEs that have been processed by - setup_class_bindings. */ - -static GTY(()) VEC(tree) *marked_identifiers; - -/* Subroutines of push_class_decls (). */ - -static void -setup_class_bindings (tree name, int type_binding_p) -{ - tree type_binding = NULL_TREE; - tree value_binding; - - /* If we've already done the lookup for this declaration, we're - done. */ - if (IDENTIFIER_MARKED (name)) - return; - - IDENTIFIER_MARKED (name) = 1; - VEC_safe_push (tree, marked_identifiers, name); - - /* First, deal with the type binding. */ - if (type_binding_p) - { - type_binding = lookup_member (current_class_type, name, - /*protect=*/2, /*want_type=*/true); - if (TREE_CODE (type_binding) == TREE_LIST - && TREE_TYPE (type_binding) == error_mark_node) - /* NAME is ambiguous. */ - push_class_level_binding (name, type_binding); - else - pushdecl_class_level (type_binding); - } - - /* Now, do the value binding. */ - value_binding = lookup_member (current_class_type, name, - /*protect=*/2, /*want_type=*/false); - - if (type_binding_p - && (TREE_CODE (value_binding) == TYPE_DECL - || DECL_CLASS_TEMPLATE_P (value_binding) - || (TREE_CODE (value_binding) == TREE_LIST - && TREE_TYPE (value_binding) == error_mark_node - && (TREE_CODE (TREE_VALUE (value_binding)) - == TYPE_DECL)))) - /* We found a type-binding, even when looking for a non-type - binding. This means that we already processed this binding - above. */; - else if (value_binding) - { - if (TREE_CODE (value_binding) == TREE_LIST - && TREE_TYPE (value_binding) == error_mark_node) - /* NAME is ambiguous. */ - push_class_level_binding (name, value_binding); - else - { - if (BASELINK_P (value_binding)) - /* NAME is some overloaded functions. */ - value_binding = BASELINK_FUNCTIONS (value_binding); - /* Two conversion operators that convert to the same type - may have different names. (See - mangle_conv_op_name_for_type.) To avoid recording the - same conversion operator declaration more than once we - must check to see that the same operator was not already - found under another name. */ - if (IDENTIFIER_TYPENAME_P (name) - && is_overloaded_fn (value_binding)) - { - tree fns; - for (fns = value_binding; fns; fns = OVL_NEXT (fns)) - { - tree name = DECL_NAME (OVL_CURRENT (fns)); - if (IDENTIFIER_MARKED (name)) - return; - IDENTIFIER_MARKED (name) = 1; - VEC_safe_push (tree, marked_identifiers, name); - } - } - pushdecl_class_level (value_binding); - } - } -} - -/* Push class-level declarations for any names appearing in BINFO that - are TYPE_DECLS. */ - -static tree -dfs_push_type_decls (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - tree type; - tree fields; - - type = BINFO_TYPE (binfo); - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - if (DECL_NAME (fields) && TREE_CODE (fields) == TYPE_DECL - && !(!same_type_p (type, current_class_type) - && template_self_reference_p (type, fields))) - setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/1); - - /* We can't just use BINFO_MARKED because envelope_add_decl uses - DERIVED_FROM_P, which calls get_base_distance. */ - BINFO_PUSHDECLS_MARKED (binfo) = 1; - - return NULL_TREE; -} - -/* Push class-level declarations for any names appearing in BINFO that - are not TYPE_DECLS. */ - -static tree -dfs_push_decls (tree binfo, void *data) -{ - tree type = BINFO_TYPE (binfo); - tree method_vec; - tree fields; - - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - if (DECL_NAME (fields) - && TREE_CODE (fields) != TYPE_DECL - && TREE_CODE (fields) != USING_DECL - && !DECL_ARTIFICIAL (fields)) - setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0); - else if (TREE_CODE (fields) == FIELD_DECL - && ANON_AGGR_TYPE_P (TREE_TYPE (fields))) - dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data); - - method_vec = (CLASS_TYPE_P (type) - ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE); - - if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3) - { - tree *methods; - tree *end; - - /* Farm out constructors and destructors. */ - end = TREE_VEC_END (method_vec); - - for (methods = &TREE_VEC_ELT (method_vec, 2); - methods < end && *methods; - methods++) - setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)), - /*type_binding_p=*/0); - } - - BINFO_PUSHDECLS_MARKED (binfo) = 0; - - return NULL_TREE; -} - -/* When entering the scope of a class, we cache all of the - fields that that class provides within its inheritance - lattice. Where ambiguities result, we mark them - with `error_mark_node' so that if they are encountered - without explicit qualification, we can emit an error - message. */ - -void -push_class_decls (tree type) -{ - tree id; - size_t i; - - if (!TYPE_BINFO (type)) - /* This occurs when parsing an invalid declarator id where the - scope is incomplete. */ - return; - - /* Enter type declarations and mark. */ - dfs_walk (TYPE_BINFO (type), dfs_push_type_decls, unmarked_pushdecls_p, 0); - - /* Enter non-type declarations and unmark. */ - dfs_walk (TYPE_BINFO (type), dfs_push_decls, marked_pushdecls_p, 0); - - /* Clear the IDENTIFIER_MARKED bits. */ - for (i = 0; - (id = VEC_iterate (tree, marked_identifiers, i)); - ++i) - IDENTIFIER_MARKED (id) = 0; - if (marked_identifiers) - VEC_truncate (tree, marked_identifiers, 0); -} - void print_search_statistics (void) { @@ -2533,4 +2339,3 @@ original_binfo (tree binfo, tree here) return result; } -#include "gt-cp-search.h" |