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
This commit is contained in:
Mark Mitchell 2004-07-14 15:34:30 +00:00 committed by Mark Mitchell
parent 9567481068
commit 90ea9897a0
9 changed files with 380 additions and 454 deletions

View File

@ -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

View File

@ -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 ();

View File

@ -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"

View File

@ -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);

View File

@ -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)
{

View File

@ -368,6 +368,47 @@ cxx_binding_free (cxx_binding *binding)
free_bindings = binding;
}
/* Create a new binding for NAME (with the indicated VALUE and TYPE
bindings) in the class scope indicated by SCOPE. */
static cxx_binding *
new_class_binding (tree name, tree value, tree type, cxx_scope *scope)
{
cp_class_binding *cb;
cxx_binding *binding;
if (VEC_length (cp_class_binding, scope->class_shadowed))
{
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, scope->class_shadowed, i));
i++)
{
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. */
@ -377,31 +418,15 @@ push_binding (tree id, tree decl, cxx_scope* level)
cxx_binding *binding;
if (level != class_binding_level)
binding = cxx_binding_make (decl, NULL_TREE);
else
{
cp_class_binding *cb;
if (VEC_reserve (cp_class_binding, level->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));
i++)
IDENTIFIER_BINDING (cb->identifier) = &cb->base;
}
cb = VEC_quick_push (cp_class_binding, level->class_shadowed, NULL);
cb->identifier = id;
binding = &cb->base;
cxx_binding_init (binding, decl, NULL_TREE);
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))
/* 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);
check_template_shadow (decl);
/* [class.mem]
If T is the name of a class, then each of the following shall
have a name different from T:
-- every static data member of class T;
-- every member of class T that is itself a type;
-- every enumerator of every member of class T that is an
enumerated 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 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);
/* [class.mem]
If T is the name of a class, then each of the following shall
have a name different from T:
-- every static data member of class T;
-- every member of class T that is itself a type;
-- every enumerator of every member of class T that is an
enumerated 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)
}
}
/* 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);
/* 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);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
/* 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 (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;
}
/* 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;

View File

@ -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. */

View File

@ -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)

View File

@ -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"