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:
parent
9567481068
commit
90ea9897a0
@ -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
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
14
gcc/cp/pt.c
14
gcc/cp/pt.c
@ -2075,7 +2075,7 @@ check_template_shadow (tree decl)
|
||||
/* Figure out what we're shadowing. */
|
||||
if (TREE_CODE (decl) == OVERLOAD)
|
||||
decl = OVL_CURRENT (decl);
|
||||
olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));
|
||||
olddecl = innermost_non_namespace_value (DECL_NAME (decl));
|
||||
|
||||
/* If there's no previous binding for this name, we're not shadowing
|
||||
anything, let alone a template parameter. */
|
||||
@ -4156,9 +4156,9 @@ lookup_template_class (tree d1,
|
||||
|
||||
if (TREE_CODE (d1) == IDENTIFIER_NODE)
|
||||
{
|
||||
if (IDENTIFIER_VALUE (d1)
|
||||
&& DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
|
||||
template = IDENTIFIER_VALUE (d1);
|
||||
tree value = innermost_non_namespace_value (d1);
|
||||
if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
|
||||
template = value;
|
||||
else
|
||||
{
|
||||
if (context)
|
||||
@ -4200,11 +4200,7 @@ lookup_template_class (tree d1,
|
||||
context = DECL_CONTEXT (template);
|
||||
}
|
||||
|
||||
/* With something like `template <class T> class X class X { ... };'
|
||||
we could end up with D1 having nothing but an IDENTIFIER_VALUE.
|
||||
We don't want to do that, but we have to deal with the situation,
|
||||
so let's give them some syntax errors to chew on instead of a
|
||||
crash. Alternatively D1 might not be a template type at all. */
|
||||
/* Issue an error message if we didn't find a template. */
|
||||
if (! template)
|
||||
{
|
||||
if (complain & tf_error)
|
||||
|
229
gcc/cp/search.c
229
gcc/cp/search.c
@ -49,12 +49,8 @@ static tree dfs_check_overlap (tree, void *);
|
||||
static tree dfs_no_overlap_yet (tree, int, void *);
|
||||
static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
|
||||
static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
|
||||
static tree marked_pushdecls_p (tree, int, void *);
|
||||
static tree unmarked_pushdecls_p (tree, int, void *);
|
||||
static tree dfs_debug_unmarkedp (tree, int, void *);
|
||||
static tree dfs_debug_mark (tree, void *);
|
||||
static tree dfs_push_type_decls (tree, void *);
|
||||
static tree dfs_push_decls (tree, void *);
|
||||
static tree add_conversions (tree, void *);
|
||||
static int look_for_overrides_r (tree, tree);
|
||||
static tree bfs_walk (tree, tree (*) (tree, void *),
|
||||
@ -68,7 +64,6 @@ static tree dfs_access_in_type (tree, void *);
|
||||
static access_kind access_in_type (tree, tree);
|
||||
static int protected_accessible_p (tree, tree, tree);
|
||||
static int friend_accessible_p (tree, tree, tree);
|
||||
static void setup_class_bindings (tree, int);
|
||||
static int template_self_reference_p (tree, tree);
|
||||
static tree dfs_get_pure_virtuals (tree, void *);
|
||||
|
||||
@ -455,12 +450,23 @@ lookup_field_1 (tree type, tree name, bool want_type)
|
||||
return temp;
|
||||
}
|
||||
if (TREE_CODE (field) == USING_DECL)
|
||||
/* For now, we're just treating member using declarations as
|
||||
old ARM-style access declarations. Thus, there's no reason
|
||||
to return a USING_DECL, and the rest of the compiler can't
|
||||
handle it. Once the class is defined, these are purged
|
||||
from TYPE_FIELDS anyhow; see handle_using_decl. */
|
||||
continue;
|
||||
{
|
||||
/* We generally treat class-scope using-declarations as
|
||||
ARM-style access specifications, because support for the
|
||||
ISO semantics has not been implemented. So, in general,
|
||||
there's no reason to return a USING_DECL, and the rest of
|
||||
the compiler cannot handle that. Once the class is
|
||||
defined, USING_DECLs are purged from TYPE_FIELDS; see
|
||||
handle_using_decl. However, we make special efforts to
|
||||
make using-declarations in template classes work
|
||||
correctly. */
|
||||
if (CLASSTYPE_TEMPLATE_INFO (type)
|
||||
&& !CLASSTYPE_USE_TEMPLATE (type)
|
||||
&& !TREE_TYPE (field))
|
||||
;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DECL_NAME (field) == name
|
||||
&& (!want_type
|
||||
@ -1912,24 +1918,6 @@ unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
|
||||
return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
|
||||
}
|
||||
|
||||
static tree
|
||||
marked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree binfo = BINFO_BASE_BINFO (derived, ix);
|
||||
|
||||
return (!BINFO_DEPENDENT_BASE_P (binfo)
|
||||
&& BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE;
|
||||
}
|
||||
|
||||
static tree
|
||||
unmarked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree binfo = BINFO_BASE_BINFO (derived, ix);
|
||||
|
||||
return (!BINFO_DEPENDENT_BASE_P (binfo)
|
||||
&& !BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE;
|
||||
}
|
||||
|
||||
/* The worker functions for `dfs_walk'. These do not need to
|
||||
test anything (vis a vis marking) if they are paired with
|
||||
a predicate function (above). */
|
||||
@ -2032,188 +2020,6 @@ note_debug_info_needed (tree type)
|
||||
dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp, 0);
|
||||
}
|
||||
|
||||
/* A vector of IDENTIFIER_NODEs that have been processed by
|
||||
setup_class_bindings. */
|
||||
|
||||
static GTY(()) VEC(tree) *marked_identifiers;
|
||||
|
||||
/* Subroutines of push_class_decls (). */
|
||||
|
||||
static void
|
||||
setup_class_bindings (tree name, int type_binding_p)
|
||||
{
|
||||
tree type_binding = NULL_TREE;
|
||||
tree value_binding;
|
||||
|
||||
/* If we've already done the lookup for this declaration, we're
|
||||
done. */
|
||||
if (IDENTIFIER_MARKED (name))
|
||||
return;
|
||||
|
||||
IDENTIFIER_MARKED (name) = 1;
|
||||
VEC_safe_push (tree, marked_identifiers, name);
|
||||
|
||||
/* First, deal with the type binding. */
|
||||
if (type_binding_p)
|
||||
{
|
||||
type_binding = lookup_member (current_class_type, name,
|
||||
/*protect=*/2, /*want_type=*/true);
|
||||
if (TREE_CODE (type_binding) == TREE_LIST
|
||||
&& TREE_TYPE (type_binding) == error_mark_node)
|
||||
/* NAME is ambiguous. */
|
||||
push_class_level_binding (name, type_binding);
|
||||
else
|
||||
pushdecl_class_level (type_binding);
|
||||
}
|
||||
|
||||
/* Now, do the value binding. */
|
||||
value_binding = lookup_member (current_class_type, name,
|
||||
/*protect=*/2, /*want_type=*/false);
|
||||
|
||||
if (type_binding_p
|
||||
&& (TREE_CODE (value_binding) == TYPE_DECL
|
||||
|| DECL_CLASS_TEMPLATE_P (value_binding)
|
||||
|| (TREE_CODE (value_binding) == TREE_LIST
|
||||
&& TREE_TYPE (value_binding) == error_mark_node
|
||||
&& (TREE_CODE (TREE_VALUE (value_binding))
|
||||
== TYPE_DECL))))
|
||||
/* We found a type-binding, even when looking for a non-type
|
||||
binding. This means that we already processed this binding
|
||||
above. */;
|
||||
else if (value_binding)
|
||||
{
|
||||
if (TREE_CODE (value_binding) == TREE_LIST
|
||||
&& TREE_TYPE (value_binding) == error_mark_node)
|
||||
/* NAME is ambiguous. */
|
||||
push_class_level_binding (name, value_binding);
|
||||
else
|
||||
{
|
||||
if (BASELINK_P (value_binding))
|
||||
/* NAME is some overloaded functions. */
|
||||
value_binding = BASELINK_FUNCTIONS (value_binding);
|
||||
/* Two conversion operators that convert to the same type
|
||||
may have different names. (See
|
||||
mangle_conv_op_name_for_type.) To avoid recording the
|
||||
same conversion operator declaration more than once we
|
||||
must check to see that the same operator was not already
|
||||
found under another name. */
|
||||
if (IDENTIFIER_TYPENAME_P (name)
|
||||
&& is_overloaded_fn (value_binding))
|
||||
{
|
||||
tree fns;
|
||||
for (fns = value_binding; fns; fns = OVL_NEXT (fns))
|
||||
{
|
||||
tree name = DECL_NAME (OVL_CURRENT (fns));
|
||||
if (IDENTIFIER_MARKED (name))
|
||||
return;
|
||||
IDENTIFIER_MARKED (name) = 1;
|
||||
VEC_safe_push (tree, marked_identifiers, name);
|
||||
}
|
||||
}
|
||||
pushdecl_class_level (value_binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Push class-level declarations for any names appearing in BINFO that
|
||||
are TYPE_DECLS. */
|
||||
|
||||
static tree
|
||||
dfs_push_type_decls (tree binfo, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree type;
|
||||
tree fields;
|
||||
|
||||
type = BINFO_TYPE (binfo);
|
||||
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
|
||||
if (DECL_NAME (fields) && TREE_CODE (fields) == TYPE_DECL
|
||||
&& !(!same_type_p (type, current_class_type)
|
||||
&& template_self_reference_p (type, fields)))
|
||||
setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/1);
|
||||
|
||||
/* We can't just use BINFO_MARKED because envelope_add_decl uses
|
||||
DERIVED_FROM_P, which calls get_base_distance. */
|
||||
BINFO_PUSHDECLS_MARKED (binfo) = 1;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Push class-level declarations for any names appearing in BINFO that
|
||||
are not TYPE_DECLS. */
|
||||
|
||||
static tree
|
||||
dfs_push_decls (tree binfo, void *data)
|
||||
{
|
||||
tree type = BINFO_TYPE (binfo);
|
||||
tree method_vec;
|
||||
tree fields;
|
||||
|
||||
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
|
||||
if (DECL_NAME (fields)
|
||||
&& TREE_CODE (fields) != TYPE_DECL
|
||||
&& TREE_CODE (fields) != USING_DECL
|
||||
&& !DECL_ARTIFICIAL (fields))
|
||||
setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0);
|
||||
else if (TREE_CODE (fields) == FIELD_DECL
|
||||
&& ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
|
||||
dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data);
|
||||
|
||||
method_vec = (CLASS_TYPE_P (type)
|
||||
? CLASSTYPE_METHOD_VEC (type) : NULL_TREE);
|
||||
|
||||
if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3)
|
||||
{
|
||||
tree *methods;
|
||||
tree *end;
|
||||
|
||||
/* Farm out constructors and destructors. */
|
||||
end = TREE_VEC_END (method_vec);
|
||||
|
||||
for (methods = &TREE_VEC_ELT (method_vec, 2);
|
||||
methods < end && *methods;
|
||||
methods++)
|
||||
setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)),
|
||||
/*type_binding_p=*/0);
|
||||
}
|
||||
|
||||
BINFO_PUSHDECLS_MARKED (binfo) = 0;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* When entering the scope of a class, we cache all of the
|
||||
fields that that class provides within its inheritance
|
||||
lattice. Where ambiguities result, we mark them
|
||||
with `error_mark_node' so that if they are encountered
|
||||
without explicit qualification, we can emit an error
|
||||
message. */
|
||||
|
||||
void
|
||||
push_class_decls (tree type)
|
||||
{
|
||||
tree id;
|
||||
size_t i;
|
||||
|
||||
if (!TYPE_BINFO (type))
|
||||
/* This occurs when parsing an invalid declarator id where the
|
||||
scope is incomplete. */
|
||||
return;
|
||||
|
||||
/* Enter type declarations and mark. */
|
||||
dfs_walk (TYPE_BINFO (type), dfs_push_type_decls, unmarked_pushdecls_p, 0);
|
||||
|
||||
/* Enter non-type declarations and unmark. */
|
||||
dfs_walk (TYPE_BINFO (type), dfs_push_decls, marked_pushdecls_p, 0);
|
||||
|
||||
/* Clear the IDENTIFIER_MARKED bits. */
|
||||
for (i = 0;
|
||||
(id = VEC_iterate (tree, marked_identifiers, i));
|
||||
++i)
|
||||
IDENTIFIER_MARKED (id) = 0;
|
||||
if (marked_identifiers)
|
||||
VEC_truncate (tree, marked_identifiers, 0);
|
||||
}
|
||||
|
||||
void
|
||||
print_search_statistics (void)
|
||||
{
|
||||
@ -2533,4 +2339,3 @@ original_binfo (tree binfo, tree here)
|
||||
return result;
|
||||
}
|
||||
|
||||
#include "gt-cp-search.h"
|
||||
|
Loading…
Reference in New Issue
Block a user