Commit 90ea9897 by Mark Mitchell Committed by Mark Mitchell

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
parent 95674810
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> 2004-07-13 Mark Mitchell <mark@codesourcery.com>
PR c++/16518 PR c++/16518
......
...@@ -807,6 +807,7 @@ add_method (tree type, tree method, int error_p) ...@@ -807,6 +807,7 @@ add_method (tree type, tree method, int error_p)
int len; int len;
int slot; int slot;
tree method_vec; tree method_vec;
tree overload;
int template_conv_p; int template_conv_p;
if (method == error_mark_node) if (method == error_mark_node)
...@@ -1025,15 +1026,14 @@ add_method (tree type, tree method, int error_p) ...@@ -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. */ /* Add the new binding. */
overload = build_overload (method, TREE_VEC_ELT (method_vec, slot));
if (!DECL_CONSTRUCTOR_P (method) if (!DECL_CONSTRUCTOR_P (method)
&& !DECL_DESTRUCTOR_P (method)) && !DECL_DESTRUCTOR_P (method))
push_class_level_binding (DECL_NAME (method), push_class_level_binding (DECL_NAME (method), overload);
TREE_VEC_ELT (method_vec, slot));
/* Actually insert the new method. */
TREE_VEC_ELT (method_vec, slot) = overload;
} }
/* Subroutines of finish_struct. */ /* Subroutines of finish_struct. */
...@@ -5484,9 +5484,7 @@ init_class_processing (void) ...@@ -5484,9 +5484,7 @@ init_class_processing (void)
static void static void
restore_class_cache (void) restore_class_cache (void)
{ {
cp_class_binding *cb;
tree type; tree type;
size_t i;
/* We are re-entering the same class we just left, so we don't /* 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 have to search the whole inheritance matrix to find all the
...@@ -5494,18 +5492,6 @@ restore_class_cache (void) ...@@ -5494,18 +5492,6 @@ restore_class_cache (void)
class_shadowed list and walk through it binding names. */ class_shadowed list and walk through it binding names. */
push_binding_level (previous_class_level); push_binding_level (previous_class_level);
class_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. */ /* Restore IDENTIFIER_TYPE_VALUE. */
for (type = class_binding_level->type_shadowed; for (type = class_binding_level->type_shadowed;
type; type;
...@@ -5567,22 +5553,7 @@ pushclass (tree type) ...@@ -5567,22 +5553,7 @@ pushclass (tree type)
if (!previous_class_level if (!previous_class_level
|| type != previous_class_level->this_entity || type != previous_class_level->this_entity
|| current_class_depth > 1) || current_class_depth > 1)
{ pushlevel_class ();
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);
}
}
else else
restore_class_cache (); restore_class_cache ();
......
...@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" ...@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
target_libs="target-libstdc++-v3 target-gperf" 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"
...@@ -334,11 +334,6 @@ typedef enum cp_id_kind ...@@ -334,11 +334,6 @@ typedef enum cp_id_kind
#define IDENTIFIER_BINDING(NODE) \ #define IDENTIFIER_BINDING(NODE) \
(LANG_IDENTIFIER_CAST (NODE)->bindings) (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 /* TREE_TYPE only indicates on local and class scope the current
type. For namespace scope, the presence of a type in any namespace type. For namespace scope, the presence of a type in any namespace
is indicated with global_type_node, and the real type behind must is indicated with global_type_node, and the real type behind must
...@@ -1388,9 +1383,6 @@ struct lang_type GTY(()) ...@@ -1388,9 +1383,6 @@ struct lang_type GTY(())
my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \ my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \
20000517)) 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. */ /* Nonzero if this BINFO is a primary base class. */
#define BINFO_PRIMARY_P(NODE) \ #define BINFO_PRIMARY_P(NODE) \
...@@ -3708,7 +3700,6 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, ...@@ -3708,7 +3700,6 @@ extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int,
extern void start_decl_1 (tree); extern void start_decl_1 (tree);
extern void cp_finish_decl (tree, tree, tree, int); extern void cp_finish_decl (tree, tree, tree, int);
extern void finish_decl (tree, tree, tree); extern void finish_decl (tree, tree, tree);
extern void maybe_inject_for_scope_var (tree);
extern int complete_array_type (tree, tree, int); extern int complete_array_type (tree, tree, int);
extern tree build_ptrmemfunc_type (tree); extern tree build_ptrmemfunc_type (tree);
extern tree build_ptrmem_type (tree, tree); extern tree build_ptrmem_type (tree, tree);
...@@ -4003,7 +3994,6 @@ extern int look_for_overrides (tree, tree); ...@@ -4003,7 +3994,6 @@ extern int look_for_overrides (tree, tree);
extern void get_pure_virtuals (tree); extern void get_pure_virtuals (tree);
extern void maybe_suppress_debug_info (tree); extern void maybe_suppress_debug_info (tree);
extern void note_debug_info_needed (tree); extern void note_debug_info_needed (tree);
extern void push_class_decls (tree);
extern void print_search_statistics (void); extern void print_search_statistics (void);
extern void reinit_search_statistics (void); extern void reinit_search_statistics (void);
extern tree current_scope (void); extern tree current_scope (void);
......
...@@ -540,17 +540,19 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -540,17 +540,19 @@ poplevel (int keep, int reverse, int functionbody)
if (leaving_for_scope && TREE_CODE (link) == VAR_DECL if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
&& DECL_NAME (link)) && DECL_NAME (link))
{ {
cxx_binding *outer_binding tree name = DECL_NAME (link);
= IDENTIFIER_BINDING (DECL_NAME (link))->previous; cxx_binding *ob;
tree ns_binding; tree ns_binding;
if (!outer_binding) ob = outer_binding (name,
ns_binding = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (link)); IDENTIFIER_BINDING (name),
/*class_p=*/true);
if (!ob)
ns_binding = IDENTIFIER_NAMESPACE_VALUE (name);
else else
ns_binding = NULL_TREE; ns_binding = NULL_TREE;
if (outer_binding if (ob && ob->scope == current_binding_level->level_chain)
&& outer_binding->scope == current_binding_level->level_chain)
/* We have something like: /* We have something like:
int i; int i;
...@@ -558,9 +560,8 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -558,9 +560,8 @@ poplevel (int keep, int reverse, int functionbody)
and we are leaving the `for' scope. There's no reason to and we are leaving the `for' scope. There's no reason to
keep the binding of the inner `i' in this case. */ keep the binding of the inner `i' in this case. */
pop_binding (DECL_NAME (link), link); pop_binding (name, link);
else if ((outer_binding else if ((ob && (TREE_CODE (ob->value) == TYPE_DECL))
&& (TREE_CODE (outer_binding->value) == TYPE_DECL))
|| (ns_binding && TREE_CODE (ns_binding) == TYPE_DECL)) || (ns_binding && TREE_CODE (ns_binding) == TYPE_DECL))
/* Here, we have something like: /* Here, we have something like:
...@@ -572,7 +573,7 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -572,7 +573,7 @@ poplevel (int keep, int reverse, int functionbody)
We must pop the for-scope binding so we know what's a We must pop the for-scope binding so we know what's a
type and what isn't. */ type and what isn't. */
pop_binding (DECL_NAME (link), link); pop_binding (name, link);
else else
{ {
/* Mark this VAR_DECL as dead so that we can tell we left it /* 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) ...@@ -581,8 +582,8 @@ poplevel (int keep, int reverse, int functionbody)
/* Keep track of what should have happened when we /* Keep track of what should have happened when we
popped the binding. */ popped the binding. */
if (outer_binding && outer_binding->value) if (ob && ob->value)
DECL_SHADOWED_FOR_VAR (link) = outer_binding->value; DECL_SHADOWED_FOR_VAR (link) = ob->value;
/* Add it to the list of dead variables in the next /* Add it to the list of dead variables in the next
outermost binding to that we can remove these when we outermost binding to that we can remove these when we
...@@ -594,7 +595,8 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -594,7 +595,8 @@ poplevel (int keep, int reverse, int functionbody)
/* Although we don't pop the cxx_binding, we do clear /* Although we don't pop the cxx_binding, we do clear
its SCOPE since the scope is going away now. */ 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 else
...@@ -4846,8 +4848,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ...@@ -4846,8 +4848,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
/* A variable definition. */ /* A variable definition. */
if (DECL_FUNCTION_SCOPE_P (decl)) if (DECL_FUNCTION_SCOPE_P (decl))
{ {
/* This is a local declaration. */
maybe_inject_for_scope_var (decl);
/* Initialize the local variable. */ /* Initialize the local variable. */
if (processing_template_decl) if (processing_template_decl)
{ {
......
...@@ -310,7 +310,6 @@ extern tree lookup_qualified_name (tree, tree, bool, bool); ...@@ -310,7 +310,6 @@ extern tree lookup_qualified_name (tree, tree, bool, bool);
extern tree lookup_name_nonclass (tree); extern tree lookup_name_nonclass (tree);
extern tree lookup_function_nonclass (tree, tree, bool); extern tree lookup_function_nonclass (tree, tree, bool);
extern void push_local_binding (tree, tree, int); extern void push_local_binding (tree, tree, int);
extern int push_class_binding (tree, tree);
extern bool pushdecl_class_level (tree); extern bool pushdecl_class_level (tree);
extern tree pushdecl_namespace_level (tree); extern tree pushdecl_namespace_level (tree);
extern bool push_class_level_binding (tree, tree); extern bool push_class_level_binding (tree, tree);
...@@ -329,7 +328,8 @@ extern void do_using_directive (tree); ...@@ -329,7 +328,8 @@ extern void do_using_directive (tree);
extern tree lookup_arg_dependent (tree, tree, tree); extern tree lookup_arg_dependent (tree, tree, tree);
extern bool is_associated_namespace (tree, tree); extern bool is_associated_namespace (tree, tree);
extern void parse_using_directive (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, /* Set *DECL to the (non-hidden) declaration for ID at global scope,
if present and return true; otherwise return false. */ if present and return true; otherwise return false. */
......
...@@ -2075,7 +2075,7 @@ check_template_shadow (tree decl) ...@@ -2075,7 +2075,7 @@ check_template_shadow (tree decl)
/* Figure out what we're shadowing. */ /* Figure out what we're shadowing. */
if (TREE_CODE (decl) == OVERLOAD) if (TREE_CODE (decl) == OVERLOAD)
decl = OVL_CURRENT (decl); 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 /* If there's no previous binding for this name, we're not shadowing
anything, let alone a template parameter. */ anything, let alone a template parameter. */
...@@ -4156,9 +4156,9 @@ lookup_template_class (tree d1, ...@@ -4156,9 +4156,9 @@ lookup_template_class (tree d1,
if (TREE_CODE (d1) == IDENTIFIER_NODE) if (TREE_CODE (d1) == IDENTIFIER_NODE)
{ {
if (IDENTIFIER_VALUE (d1) tree value = innermost_non_namespace_value (d1);
&& DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1))) if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
template = IDENTIFIER_VALUE (d1); template = value;
else else
{ {
if (context) if (context)
...@@ -4200,11 +4200,7 @@ lookup_template_class (tree d1, ...@@ -4200,11 +4200,7 @@ lookup_template_class (tree d1,
context = DECL_CONTEXT (template); context = DECL_CONTEXT (template);
} }
/* With something like `template <class T> class X class X { ... };' /* Issue an error message if we didn't find a template. */
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. */
if (! template) if (! template)
{ {
if (complain & tf_error) if (complain & tf_error)
......
...@@ -49,12 +49,8 @@ static tree dfs_check_overlap (tree, void *); ...@@ -49,12 +49,8 @@ static tree dfs_check_overlap (tree, void *);
static tree dfs_no_overlap_yet (tree, int, void *); static tree dfs_no_overlap_yet (tree, int, void *);
static base_kind lookup_base_r (tree, tree, base_access, bool, tree *); static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
static int dynamic_cast_base_recurse (tree, tree, 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_unmarkedp (tree, int, void *);
static tree dfs_debug_mark (tree, 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 tree add_conversions (tree, void *);
static int look_for_overrides_r (tree, tree); static int look_for_overrides_r (tree, tree);
static tree bfs_walk (tree, tree (*) (tree, void *), static tree bfs_walk (tree, tree (*) (tree, void *),
...@@ -68,7 +64,6 @@ static tree dfs_access_in_type (tree, void *); ...@@ -68,7 +64,6 @@ static tree dfs_access_in_type (tree, void *);
static access_kind access_in_type (tree, tree); static access_kind access_in_type (tree, tree);
static int protected_accessible_p (tree, tree, tree); static int protected_accessible_p (tree, tree, tree);
static int friend_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 int template_self_reference_p (tree, tree);
static tree dfs_get_pure_virtuals (tree, void *); static tree dfs_get_pure_virtuals (tree, void *);
...@@ -455,12 +450,23 @@ lookup_field_1 (tree type, tree name, bool want_type) ...@@ -455,12 +450,23 @@ lookup_field_1 (tree type, tree name, bool want_type)
return temp; return temp;
} }
if (TREE_CODE (field) == USING_DECL) 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 /* We generally treat class-scope using-declarations as
to return a USING_DECL, and the rest of the compiler can't ARM-style access specifications, because support for the
handle it. Once the class is defined, these are purged ISO semantics has not been implemented. So, in general,
from TYPE_FIELDS anyhow; see handle_using_decl. */ there's no reason to return a USING_DECL, and the rest of
continue; 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 if (DECL_NAME (field) == name
&& (!want_type && (!want_type
...@@ -1912,24 +1918,6 @@ unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED) ...@@ -1912,24 +1918,6 @@ unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
return !BINFO_MARKED (binfo) ? binfo : NULL_TREE; 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 /* The worker functions for `dfs_walk'. These do not need to
test anything (vis a vis marking) if they are paired with test anything (vis a vis marking) if they are paired with
a predicate function (above). */ a predicate function (above). */
...@@ -2032,188 +2020,6 @@ note_debug_info_needed (tree type) ...@@ -2032,188 +2020,6 @@ note_debug_info_needed (tree type)
dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp, 0); 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 void
print_search_statistics (void) print_search_statistics (void)
{ {
...@@ -2533,4 +2339,3 @@ original_binfo (tree binfo, tree here) ...@@ -2533,4 +2339,3 @@ original_binfo (tree binfo, tree here)
return result; return result;
} }
#include "gt-cp-search.h"
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