cp-tree.h (saved_scope): Remove x_previous_class_type and x_previous_class_values...
* cp-tree.h (saved_scope): Remove x_previous_class_type and x_previous_class_values; add x_previous_class_level. (previous_class_type): Remove. (previous_class_values): Remove. (previous_class_level): New macro. * class.c (pushclass): Restore the identifier cache more expeditiously. (invalidate_class_lookup_cache): Use vector for class_shadowed and previous_class_values. * decl.c (poplevel): Likewise. * name-lookup.c (cxx_binding_init): New function. (cxx_binding_make): Use it. (push_binding): For a binding in a class level, use a vector of cp_class_binding nodes. (push_binding_level): New function. (begin_scope): Use it. (leave_scope): Do not put class binding levels on the free list. (print_binding_level): Adjust for the fact that class_shadowed is a vector. (poplevel_class): Likewise. (clear_identifier_class_values): Likewise. (push_class_level_binding): Likewise. (set_class_shadows): Remove. (store_binding): New function. (store_class_bindings): New function. (push_to_top_level): Use store_class_bindings as appropriate. (pop_from_top_level): Use previous_class_level, not previous_class_type. * name-lookup.h (cp_class_binding): New type. (cp_binding_level): Use a vector object for class_shadowed. (push_binding_level): Declare. (set_class_shadows): Remove. From-SVN: r84259
This commit is contained in:
parent
beed8fc0bb
commit
89b578be68
@ -1,3 +1,38 @@
|
||||
2004-07-07 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (saved_scope): Remove x_previous_class_type and
|
||||
x_previous_class_values; add x_previous_class_level.
|
||||
(previous_class_type): Remove.
|
||||
(previous_class_values): Remove.
|
||||
(previous_class_level): New macro.
|
||||
* class.c (pushclass): Restore the identifier cache more
|
||||
expeditiously.
|
||||
(invalidate_class_lookup_cache): Use vector for class_shadowed and
|
||||
previous_class_values.
|
||||
* decl.c (poplevel): Likewise.
|
||||
* name-lookup.c (cxx_binding_init): New function.
|
||||
(cxx_binding_make): Use it.
|
||||
(push_binding): For a binding in a class level, use a vector of
|
||||
cp_class_binding nodes.
|
||||
(push_binding_level): New function.
|
||||
(begin_scope): Use it.
|
||||
(leave_scope): Do not put class binding levels on the free list.
|
||||
(print_binding_level): Adjust for the fact that class_shadowed is
|
||||
a vector.
|
||||
(poplevel_class): Likewise.
|
||||
(clear_identifier_class_values): Likewise.
|
||||
(push_class_level_binding): Likewise.
|
||||
(set_class_shadows): Remove.
|
||||
(store_binding): New function.
|
||||
(store_class_bindings): New function.
|
||||
(push_to_top_level): Use store_class_bindings as appropriate.
|
||||
(pop_from_top_level): Use previous_class_level, not
|
||||
previous_class_type.
|
||||
* name-lookup.h (cp_class_binding): New type.
|
||||
(cp_binding_level): Use a vector object for class_shadowed.
|
||||
(push_binding_level): Declare.
|
||||
(set_class_shadows): Remove.
|
||||
|
||||
2004-07-07 Andrew Pinski <apinski@apple.com>
|
||||
|
||||
* class.c (instantiate_type): BUFFER_REF is dead.
|
||||
|
@ -5486,9 +5486,8 @@ pushclass (tree type)
|
||||
? access_private_node
|
||||
: access_public_node);
|
||||
|
||||
if (previous_class_type != NULL_TREE
|
||||
&& (type != previous_class_type
|
||||
|| !COMPLETE_TYPE_P (previous_class_type))
|
||||
if (previous_class_level
|
||||
&& type != previous_class_level->this_entity
|
||||
&& current_class_depth == 1)
|
||||
{
|
||||
/* Forcibly remove any old class remnants. */
|
||||
@ -5500,10 +5499,11 @@ pushclass (tree type)
|
||||
if (current_class_depth > 1)
|
||||
clear_identifier_class_values ();
|
||||
|
||||
pushlevel_class ();
|
||||
|
||||
if (type != previous_class_type || current_class_depth > 1)
|
||||
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))
|
||||
{
|
||||
@ -5520,22 +5520,33 @@ pushclass (tree type)
|
||||
}
|
||||
else
|
||||
{
|
||||
tree item;
|
||||
cp_class_binding *cb;
|
||||
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
|
||||
decls to bind again. Instead, we install the cached
|
||||
class_shadowed list, and walk through it binding names and
|
||||
setting up IDENTIFIER_TYPE_VALUEs. */
|
||||
set_class_shadows (previous_class_values);
|
||||
for (item = previous_class_values; item; item = TREE_CHAIN (item))
|
||||
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 = TREE_PURPOSE (item);
|
||||
tree decl = TREE_TYPE (item);
|
||||
|
||||
push_class_binding (id, decl);
|
||||
if (TREE_CODE (decl) == TYPE_DECL)
|
||||
set_identifier_type_value (id, decl);
|
||||
tree id;
|
||||
tree type_decl;
|
||||
|
||||
id = cb->identifier;
|
||||
cb->base.previous = IDENTIFIER_BINDING (id);
|
||||
IDENTIFIER_BINDING (id) = &cb->base;
|
||||
type_decl = cb->base.value;
|
||||
if (!type_decl || TREE_CODE (type_decl) != TYPE_DECL)
|
||||
type_decl = cb->base.type;
|
||||
if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
|
||||
set_identifier_type_value (id, type_decl);
|
||||
}
|
||||
unuse_fields (type);
|
||||
}
|
||||
@ -5551,14 +5562,17 @@ pushclass (tree type)
|
||||
void
|
||||
invalidate_class_lookup_cache (void)
|
||||
{
|
||||
tree t;
|
||||
size_t i;
|
||||
cp_class_binding *cb;
|
||||
|
||||
/* The IDENTIFIER_CLASS_VALUEs are no longer valid. */
|
||||
for (t = previous_class_values; t; t = TREE_CHAIN (t))
|
||||
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
|
||||
for (i = 0;
|
||||
(cb = VEC_iterate (cp_class_binding,
|
||||
previous_class_level->class_shadowed, i));
|
||||
++i)
|
||||
IDENTIFIER_CLASS_VALUE (cb->identifier) = NULL_TREE;
|
||||
|
||||
previous_class_values = NULL_TREE;
|
||||
previous_class_type = NULL_TREE;
|
||||
previous_class_level = NULL;
|
||||
}
|
||||
|
||||
/* Get out of the current class scope. If we were in a class scope
|
||||
|
@ -640,8 +640,7 @@ struct saved_scope GTY(())
|
||||
varray_type lang_base;
|
||||
tree lang_name;
|
||||
tree template_parms;
|
||||
tree x_previous_class_type;
|
||||
tree x_previous_class_values;
|
||||
struct cp_binding_level *x_previous_class_level;
|
||||
tree x_saved_tree;
|
||||
|
||||
HOST_WIDE_INT x_processing_template_decl;
|
||||
@ -694,16 +693,10 @@ struct saved_scope GTY(())
|
||||
#define processing_specialization scope_chain->x_processing_specialization
|
||||
#define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation
|
||||
|
||||
/* _TYPE: the previous type that was a class */
|
||||
/* The cached class binding level, from the most recently exited
|
||||
class, or NULL if none. */
|
||||
|
||||
#define previous_class_type scope_chain->x_previous_class_type
|
||||
|
||||
/* This is a copy of the class_shadowed list of the previous class
|
||||
binding contour when at global scope. It's used to reset
|
||||
IDENTIFIER_CLASS_VALUEs when entering another class scope (i.e. a
|
||||
cache miss). */
|
||||
|
||||
#define previous_class_values scope_chain->x_previous_class_values
|
||||
#define previous_class_level scope_chain->x_previous_class_level
|
||||
|
||||
/* A list of private types mentioned, for deferred access checking. */
|
||||
|
||||
|
@ -443,7 +443,8 @@ poplevel (int keep, int reverse, int functionbody)
|
||||
? ((functionbody = 0), tmp) : functionbody);
|
||||
subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
|
||||
|
||||
my_friendly_assert (!current_binding_level->class_shadowed,
|
||||
my_friendly_assert (VEC_length(cp_class_binding,
|
||||
current_binding_level->class_shadowed) == 0,
|
||||
19990414);
|
||||
|
||||
/* We used to use KEEP == 2 to indicate that the new block should go
|
||||
|
@ -328,6 +328,17 @@ binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
|
||||
|
||||
static GTY((deletable)) cxx_binding *free_bindings;
|
||||
|
||||
/* Initialize VALUE and TYPE field for BINDING, and set the PREVIOUS
|
||||
field to NULL. */
|
||||
|
||||
static inline void
|
||||
cxx_binding_init (cxx_binding *binding, tree value, tree type)
|
||||
{
|
||||
binding->value = value;
|
||||
binding->type = type;
|
||||
binding->previous = NULL;
|
||||
}
|
||||
|
||||
/* (GC)-allocate a binding object with VALUE and TYPE member initialized. */
|
||||
|
||||
static cxx_binding *
|
||||
@ -342,9 +353,7 @@ cxx_binding_make (tree value, tree type)
|
||||
else
|
||||
binding = ggc_alloc (sizeof (cxx_binding));
|
||||
|
||||
binding->value = value;
|
||||
binding->type = type;
|
||||
binding->previous = NULL;
|
||||
cxx_binding_init (binding, value, type);
|
||||
|
||||
return binding;
|
||||
}
|
||||
@ -365,8 +374,31 @@ cxx_binding_free (cxx_binding *binding)
|
||||
static void
|
||||
push_binding (tree id, tree decl, cxx_scope* level)
|
||||
{
|
||||
cxx_binding *binding = cxx_binding_make (decl, NULL);
|
||||
cxx_binding *binding;
|
||||
|
||||
if (level != class_binding_level)
|
||||
binding = cxx_binding_make (decl, NULL_TREE);
|
||||
else
|
||||
{
|
||||
cp_class_binding *cb;
|
||||
size_t length;
|
||||
size_t i;
|
||||
bool need_fixup;
|
||||
|
||||
length = VEC_length (cp_class_binding, level->class_shadowed);
|
||||
need_fixup = (length && length == level->class_shadowed->alloc);
|
||||
cb = VEC_safe_push (cp_class_binding, level->class_shadowed, NULL);
|
||||
cb->identifier = id;
|
||||
binding = &cb->base;
|
||||
cxx_binding_init (binding, decl, NULL_TREE);
|
||||
if (need_fixup)
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
cb = VEC_index (cp_class_binding, level->class_shadowed, i);
|
||||
IDENTIFIER_BINDING (cb->identifier) = &cb->base;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, fill in the binding information. */
|
||||
binding->previous = IDENTIFIER_BINDING (id);
|
||||
binding->scope = level;
|
||||
@ -1261,6 +1293,26 @@ namespace_scope_ht_size (tree ns)
|
||||
|
||||
static GTY((deletable)) struct cp_binding_level *free_binding_level;
|
||||
|
||||
/* Insert SCOPE as the innermost binding level. */
|
||||
|
||||
void
|
||||
push_binding_level (struct cp_binding_level *scope)
|
||||
{
|
||||
/* Add it to the front of currently active scopes stack. */
|
||||
scope->level_chain = current_binding_level;
|
||||
current_binding_level = scope;
|
||||
keep_next_level_flag = false;
|
||||
|
||||
if (ENABLE_SCOPE_CHECKING)
|
||||
{
|
||||
scope->binding_depth = binding_depth;
|
||||
indent (binding_depth);
|
||||
cxx_scope_debug (scope, input_line, "push");
|
||||
is_class_level = 0;
|
||||
binding_depth++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new KIND scope and make it the top of the active scopes stack.
|
||||
ENTITY is the scope of the associated C++ entity (namespace, class,
|
||||
function); it is NULL otherwise. */
|
||||
@ -1319,19 +1371,7 @@ begin_scope (scope_kind kind, tree entity)
|
||||
}
|
||||
scope->kind = kind;
|
||||
|
||||
/* Add it to the front of currently active scopes stack. */
|
||||
scope->level_chain = current_binding_level;
|
||||
current_binding_level = scope;
|
||||
keep_next_level_flag = false;
|
||||
|
||||
if (ENABLE_SCOPE_CHECKING)
|
||||
{
|
||||
scope->binding_depth = binding_depth;
|
||||
indent (binding_depth);
|
||||
cxx_scope_debug (scope, input_line, "push");
|
||||
is_class_level = 0;
|
||||
binding_depth++;
|
||||
}
|
||||
push_binding_level (scope);
|
||||
|
||||
return scope;
|
||||
}
|
||||
@ -1366,11 +1406,13 @@ leave_scope (void)
|
||||
/* Move one nesting level up. */
|
||||
current_binding_level = scope->level_chain;
|
||||
|
||||
/* Namespace-scopes are left most probably temporarily, not completely;
|
||||
they can be reopen later, e.g. in namespace-extension or any name
|
||||
binding activity that requires us to resume a namespace. For other
|
||||
/* Namespace-scopes are left most probably temporarily, not
|
||||
completely; they can be reopen later, e.g. in namespace-extension
|
||||
or any name binding activity that requires us to resume a
|
||||
namespace. For classes, we cache some binding levels. For other
|
||||
scopes, we just make the structure available for reuse. */
|
||||
if (scope->kind != sk_namespace)
|
||||
if (scope->kind != sk_namespace
|
||||
&& scope->kind != sk_class)
|
||||
{
|
||||
scope->level_chain = free_binding_level;
|
||||
if (scope->kind == sk_class)
|
||||
@ -1628,13 +1670,17 @@ print_binding_level (struct cp_binding_level* lvl)
|
||||
if (i)
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
if (lvl->class_shadowed)
|
||||
if (VEC_length (cp_class_binding, lvl->class_shadowed))
|
||||
{
|
||||
size_t i;
|
||||
cp_class_binding *b;
|
||||
fprintf (stderr, " class-shadowed:");
|
||||
for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
|
||||
{
|
||||
fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
|
||||
}
|
||||
for (i = 0;
|
||||
(b = VEC_iterate(cp_class_binding,
|
||||
lvl->class_shadowed,
|
||||
i));
|
||||
++i)
|
||||
fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
if (lvl->type_shadowed)
|
||||
@ -2576,6 +2622,8 @@ void
|
||||
poplevel_class (void)
|
||||
{
|
||||
struct cp_binding_level *level = class_binding_level;
|
||||
cp_class_binding *cb;
|
||||
size_t i;
|
||||
tree shadowed;
|
||||
|
||||
timevar_push (TV_NAME_LOOKUP);
|
||||
@ -2589,12 +2637,11 @@ poplevel_class (void)
|
||||
if (current_class_depth != 1)
|
||||
{
|
||||
struct cp_binding_level* b;
|
||||
cp_class_binding* cb;
|
||||
size_t i;
|
||||
|
||||
/* Clear out our IDENTIFIER_CLASS_VALUEs. */
|
||||
for (shadowed = level->class_shadowed;
|
||||
shadowed;
|
||||
shadowed = TREE_CHAIN (shadowed))
|
||||
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
|
||||
clear_identifier_class_values ();
|
||||
|
||||
/* Find the next enclosing class, and recreate
|
||||
IDENTIFIER_CLASS_VALUEs appropriate for that class. */
|
||||
@ -2603,38 +2650,36 @@ poplevel_class (void)
|
||||
b = b->level_chain;
|
||||
|
||||
if (b)
|
||||
for (shadowed = b->class_shadowed;
|
||||
shadowed;
|
||||
shadowed = TREE_CHAIN (shadowed))
|
||||
for (i = 0;
|
||||
(cb = VEC_iterate (cp_class_binding,
|
||||
b->class_shadowed,
|
||||
i));
|
||||
++i)
|
||||
{
|
||||
cxx_binding *binding;
|
||||
|
||||
binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
|
||||
binding = IDENTIFIER_BINDING (cb->identifier);
|
||||
while (binding && binding->scope != b)
|
||||
binding = binding->previous;
|
||||
|
||||
if (binding)
|
||||
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
|
||||
= binding->value;
|
||||
IDENTIFIER_CLASS_VALUE (cb->identifier) = binding->value;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Remember to save what IDENTIFIER's were bound in this scope so we
|
||||
can recover from cache misses. */
|
||||
{
|
||||
previous_class_type = current_class_type;
|
||||
previous_class_values = class_binding_level->class_shadowed;
|
||||
}
|
||||
previous_class_level = level;
|
||||
for (shadowed = level->type_shadowed;
|
||||
shadowed;
|
||||
shadowed = TREE_CHAIN (shadowed))
|
||||
SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
|
||||
|
||||
/* Remove the bindings for all of the class-level declarations. */
|
||||
for (shadowed = level->class_shadowed;
|
||||
shadowed;
|
||||
shadowed = TREE_CHAIN (shadowed))
|
||||
pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
|
||||
for (i = 0;
|
||||
(cb = VEC_iterate (cp_class_binding, level->class_shadowed, i));
|
||||
++i)
|
||||
IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
|
||||
|
||||
/* Now, pop out of the binding level which we created up in the
|
||||
`pushlevel_class' routine. */
|
||||
@ -2707,15 +2752,16 @@ push_class_binding (tree id, tree decl)
|
||||
void
|
||||
clear_identifier_class_values (void)
|
||||
{
|
||||
tree t;
|
||||
size_t i;
|
||||
cp_class_binding *cb;
|
||||
|
||||
if (!class_binding_level)
|
||||
return;
|
||||
|
||||
for (t = class_binding_level->class_shadowed;
|
||||
t;
|
||||
t = TREE_CHAIN (t))
|
||||
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
|
||||
if (class_binding_level)
|
||||
for (i = 0;
|
||||
(cb = VEC_iterate (cp_class_binding,
|
||||
class_binding_level->class_shadowed,
|
||||
i));
|
||||
++i)
|
||||
IDENTIFIER_CLASS_VALUE (cb->identifier) = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Make the declaration of X appear in CLASS scope. */
|
||||
@ -2859,22 +2905,25 @@ push_class_level_binding (tree name, tree x)
|
||||
old_decl = bval;
|
||||
else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
|
||||
|
||||
|
||||
if (old_decl)
|
||||
{
|
||||
tree shadow;
|
||||
|
||||
cp_class_binding *cb;
|
||||
size_t i;
|
||||
|
||||
/* Find the previous binding of name on the class-shadowed
|
||||
list, and update it. */
|
||||
for (shadow = class_binding_level->class_shadowed;
|
||||
shadow;
|
||||
shadow = TREE_CHAIN (shadow))
|
||||
if (TREE_PURPOSE (shadow) == name
|
||||
&& TREE_TYPE (shadow) == old_decl)
|
||||
for (i = 0;
|
||||
(cb = VEC_iterate (cp_class_binding,
|
||||
class_binding_level->class_shadowed,
|
||||
i));
|
||||
++i)
|
||||
if (cb->identifier == name
|
||||
&& (cb->base.value == old_decl
|
||||
|| cb->base.type == old_decl))
|
||||
{
|
||||
binding->value = x;
|
||||
INHERITED_VALUE_BINDING_P (binding) = 0;
|
||||
TREE_TYPE (shadow) = x;
|
||||
IDENTIFIER_CLASS_VALUE (name) = x;
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
|
||||
}
|
||||
@ -2884,15 +2933,7 @@ push_class_level_binding (tree name, tree x)
|
||||
/* 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))
|
||||
{
|
||||
class_binding_level->class_shadowed
|
||||
= tree_cons (name, NULL,
|
||||
class_binding_level->class_shadowed);
|
||||
/* Record the value we are binding NAME to so that we can know
|
||||
what to pop later. */
|
||||
TREE_TYPE (class_binding_level->class_shadowed) = x;
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
|
||||
}
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
|
||||
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
|
||||
}
|
||||
@ -2945,11 +2986,6 @@ do_class_using_decl (tree decl)
|
||||
return value;
|
||||
}
|
||||
|
||||
void
|
||||
set_class_shadows (tree shadows)
|
||||
{
|
||||
class_binding_level->class_shadowed = shadows;
|
||||
}
|
||||
|
||||
/* Return the binding value for name in scope. */
|
||||
|
||||
@ -4796,6 +4832,41 @@ struct cxx_saved_binding GTY(())
|
||||
scope isn't enough, because more binding levels may be pushed. */
|
||||
struct saved_scope *scope_chain;
|
||||
|
||||
/* If ID is not already in the SEARCH_BINDINGS, prepend its binding
|
||||
information to OLD_BINDINGS. Returns the new OLD_BINDINGS
|
||||
list. */
|
||||
|
||||
static cxx_saved_binding *
|
||||
store_binding (tree id,
|
||||
cxx_saved_binding *old_bindings,
|
||||
cxx_saved_binding *search_bindings)
|
||||
{
|
||||
cxx_saved_binding *saved;
|
||||
cxx_saved_binding *t1;
|
||||
|
||||
if (!id
|
||||
/* Note that we may have an IDENTIFIER_CLASS_VALUE even when
|
||||
we have no IDENTIFIER_BINDING if we have left the class
|
||||
scope, but cached the class-level declarations. */
|
||||
|| !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
|
||||
return old_bindings;
|
||||
|
||||
for (t1 = search_bindings; t1; t1 = t1->previous)
|
||||
if (t1->identifier == id)
|
||||
return old_bindings;
|
||||
|
||||
my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
|
||||
saved = cxx_saved_binding_make ();
|
||||
saved->previous = old_bindings;
|
||||
saved->identifier = id;
|
||||
saved->binding = IDENTIFIER_BINDING (id);
|
||||
saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
|
||||
saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
|
||||
IDENTIFIER_BINDING (id) = NULL;
|
||||
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
|
||||
return saved;
|
||||
}
|
||||
|
||||
static cxx_saved_binding *
|
||||
store_bindings (tree names, cxx_saved_binding *old_bindings)
|
||||
{
|
||||
@ -4806,41 +4877,38 @@ store_bindings (tree names, cxx_saved_binding *old_bindings)
|
||||
for (t = names; t; t = TREE_CHAIN (t))
|
||||
{
|
||||
tree id;
|
||||
cxx_saved_binding *saved;
|
||||
cxx_saved_binding *t1;
|
||||
|
||||
if (TREE_CODE (t) == TREE_LIST)
|
||||
id = TREE_PURPOSE (t);
|
||||
else
|
||||
id = DECL_NAME (t);
|
||||
|
||||
if (!id
|
||||
/* Note that we may have an IDENTIFIER_CLASS_VALUE even when
|
||||
we have no IDENTIFIER_BINDING if we have left the class
|
||||
scope, but cached the class-level declarations. */
|
||||
|| !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
|
||||
continue;
|
||||
|
||||
for (t1 = search_bindings; t1; t1 = t1->previous)
|
||||
if (t1->identifier == id)
|
||||
goto skip_it;
|
||||
|
||||
my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
|
||||
saved = cxx_saved_binding_make ();
|
||||
saved->previous = old_bindings;
|
||||
saved->identifier = id;
|
||||
saved->binding = IDENTIFIER_BINDING (id);
|
||||
saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
|
||||
saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
|
||||
IDENTIFIER_BINDING (id) = NULL;
|
||||
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
|
||||
old_bindings = saved;
|
||||
skip_it:
|
||||
;
|
||||
old_bindings
|
||||
= store_binding (id, old_bindings, search_bindings);
|
||||
}
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
|
||||
}
|
||||
|
||||
/* Like store_bindings, but NAMES is a vector of cp_class_binding
|
||||
objects, rather than a TREE_LIST. */
|
||||
|
||||
static cxx_saved_binding *
|
||||
store_class_bindings (VEC(cp_class_binding) *names,
|
||||
cxx_saved_binding *old_bindings)
|
||||
{
|
||||
size_t i;
|
||||
cp_class_binding *cb;
|
||||
cxx_saved_binding *search_bindings = old_bindings;
|
||||
|
||||
timevar_push (TV_NAME_LOOKUP);
|
||||
for (i = 0;
|
||||
(cb = VEC_iterate(cp_class_binding, names, i));
|
||||
++i)
|
||||
old_bindings
|
||||
= store_binding (cb->identifier, old_bindings, search_bindings);
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
|
||||
}
|
||||
|
||||
void
|
||||
push_to_top_level (void)
|
||||
{
|
||||
@ -4864,8 +4932,9 @@ push_to_top_level (void)
|
||||
need_pop = 0;
|
||||
|
||||
old_bindings = NULL;
|
||||
if (scope_chain && previous_class_type)
|
||||
old_bindings = store_bindings (previous_class_values, old_bindings);
|
||||
if (scope_chain && previous_class_level)
|
||||
old_bindings = store_class_bindings (previous_class_level->class_shadowed,
|
||||
old_bindings);
|
||||
|
||||
/* Have to include the global scope, because class-scope decls
|
||||
aren't listed anywhere useful. */
|
||||
@ -4884,7 +4953,7 @@ push_to_top_level (void)
|
||||
/* We also need to check class_shadowed to save class-level type
|
||||
bindings, since pushclass doesn't fill in b->names. */
|
||||
if (b->kind == sk_class)
|
||||
old_bindings = store_bindings (b->class_shadowed, old_bindings);
|
||||
old_bindings = store_class_bindings (b->class_shadowed, old_bindings);
|
||||
|
||||
/* Unwind type-value slots back to top level. */
|
||||
for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
|
||||
@ -4912,7 +4981,7 @@ pop_from_top_level (void)
|
||||
|
||||
timevar_push (TV_NAME_LOOKUP);
|
||||
/* Clear out class-level bindings cache. */
|
||||
if (previous_class_type)
|
||||
if (previous_class_level)
|
||||
invalidate_class_lookup_cache ();
|
||||
|
||||
current_lang_base = 0;
|
||||
|
@ -117,6 +117,15 @@ typedef enum scope_kind {
|
||||
"template <>", this scope is always empty. */
|
||||
} scope_kind;
|
||||
|
||||
typedef struct cp_class_binding GTY(())
|
||||
{
|
||||
cxx_binding base;
|
||||
/* The bound name. */
|
||||
tree identifier;
|
||||
} cp_class_binding;
|
||||
|
||||
DEF_VEC_O(cp_class_binding);
|
||||
|
||||
/* For each binding contour we allocate a binding_level structure
|
||||
which records the names defined in that contour.
|
||||
Contours include:
|
||||
@ -175,7 +184,7 @@ struct cp_binding_level GTY(())
|
||||
class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node
|
||||
is the name of an entity bound in the class. The TREE_TYPE is
|
||||
the DECL bound by this name in the class. */
|
||||
tree class_shadowed;
|
||||
VEC(cp_class_binding) *class_shadowed;
|
||||
|
||||
/* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
|
||||
is used for all binding levels. In addition the TREE_VALUE is the
|
||||
@ -273,6 +282,7 @@ extern void keep_next_level (bool);
|
||||
extern bool is_ancestor (tree, tree);
|
||||
extern bool push_scope (tree);
|
||||
extern void pop_scope (tree);
|
||||
extern void push_binding_level (struct cp_binding_level *);
|
||||
|
||||
extern void push_namespace (tree);
|
||||
extern void pop_namespace (void);
|
||||
@ -299,7 +309,6 @@ extern bool push_class_level_binding (tree, tree);
|
||||
extern void storetags (tree);
|
||||
extern tree getdecls (void);
|
||||
extern tree cp_namespace_decls (tree);
|
||||
extern void set_class_shadows (tree);
|
||||
extern void set_decl_namespace (tree, tree, bool);
|
||||
extern tree current_decl_namespace (void);
|
||||
extern void push_decl_namespace (tree);
|
||||
|
Loading…
Reference in New Issue
Block a user