Commit ed3cf953 by Gabriel Dos Reis Committed by Gabriel Dos Reis

cp-tree.h (binding_for_name): Move to name-lookup.h Adjust prototype.

	* cp-tree.h (binding_for_name: Move to name-lookup.h  Adjust
	prototype.
	(cxx_scope_find_binding_for_name): Likewise.
	* decl.c (find_binding: Move to name-lookup.c.
	(binding_for_name): Likewise.
	(cxx_scope_find_binding_for_name): Likewise.
	(BINDING_LEVEL):  Remove.
	(push_binding): Tidy.
	(push_class_binding): Likewise.
	(pop_binding): Likewise.
	(poplevel): Likewise.
	(poplevel_class): Likewise.
	(set_identifier_type_value_with_scope): Likewise.
	(push_overloaded_decl): Likewise.
	(lookup_tag): Likewise.
	(unqualified_namespace_lookup): Likewise.
	(lookup_name_current_level): Likewise.
	(maybe_inject_for_scope_var): Likewise.
	(namespace_binding): Move to name-lookup.c.
	(set_namespace_binding): Likewise.
	* decl2.c (lookup_using_namespace): Tidy.
	(qualified_lookup_using_namespace): Likewise.
	(do_toplevel_using_decl): Likewise.
	* name-lookup.c: Include "timevar.h"
	* name-lookup.h (cxx_scope):  Declare.
	(struct cxx_binding): Lose member "has_level".  Adjust "scope"
	member declaration.
	(BINDING_SCOPE): Adjust definition.
	(BINDING_HAS_LEVEL_P): Remove.

From-SVN: r65044
parent 9a8075a1
2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
* cp-tree.h (binding_for_name: Move to name-lookup.h Adjust
prototype.
(cxx_scope_find_binding_for_name): Likewise.
* decl.c (find_binding: Move to name-lookup.c.
(binding_for_name): Likewise.
(cxx_scope_find_binding_for_name): Likewise.
(BINDING_LEVEL): Remove.
(push_binding): Tidy.
(push_class_binding): Likewise.
(pop_binding): Likewise.
(poplevel): Likewise.
(poplevel_class): Likewise.
(set_identifier_type_value_with_scope): Likewise.
(push_overloaded_decl): Likewise.
(lookup_tag): Likewise.
(unqualified_namespace_lookup): Likewise.
(lookup_name_current_level): Likewise.
(maybe_inject_for_scope_var): Likewise.
(namespace_binding): Move to name-lookup.c.
(set_namespace_binding): Likewise.
* decl2.c (lookup_using_namespace): Tidy.
(qualified_lookup_using_namespace): Likewise.
(do_toplevel_using_decl): Likewise.
* name-lookup.c: Include "timevar.h"
* name-lookup.h (cxx_scope): Declare.
(struct cxx_binding): Lose member "has_level". Adjust "scope"
member declaration.
(BINDING_SCOPE): Adjust definition.
(BINDING_HAS_LEVEL_P): Remove.
2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
* name-lookup.c: New file.
......
......@@ -380,8 +380,8 @@ struct tree_srcloc GTY(())
BINDING_VALUE is a DECL for the associated declaration. Thus,
name lookup consists simply of pulling off the node at the front
of the list (modulo oddities for looking up the names of types,
and such.) You can use BINDING_SCOPE or BINDING_LEVEL to
determine the scope that bound the name. */
and such.) You can use BINDING_SCOPE to determine the scope
that bound the name. */
#define IDENTIFIER_BINDING(NODE) \
(LANG_IDENTIFIER_CAST (NODE)->bindings)
......@@ -3663,7 +3663,6 @@ extern tree declare_local_label (tree);
extern tree define_label (const char *, int, tree);
extern void check_goto (tree);
extern void define_case_label (void);
extern cxx_binding *binding_for_name (tree, tree);
extern tree namespace_binding (tree, tree);
extern void set_namespace_binding (tree, tree, tree);
extern tree lookup_namespace_name (tree, tree);
......@@ -3753,7 +3752,6 @@ extern int nonstatic_local_decl_p (tree);
extern tree declare_global_var (tree, tree);
extern void register_dtor_fn (tree);
extern tmpl_spec_kind current_tmpl_spec_kind (int);
extern cxx_binding *cxx_scope_find_binding_for_name (tree, tree);
extern tree cp_fname_init (const char *);
extern bool have_extern_spec;
......
......@@ -98,7 +98,6 @@ static void push_binding (tree, tree, struct cp_binding_level*);
static int add_binding (tree, tree);
static void pop_binding (tree, tree);
static tree local_variable_p_walkfn (tree *, int *, void *);
static cxx_binding *find_binding (tree, tree, cxx_binding *);
static tree select_decl (cxx_binding *, int);
static int lookup_flags (int, int);
static tree qualify_lookup (tree, int);
......@@ -885,24 +884,19 @@ finish_scope (void)
poplevel (0, 0, 0);
}
/* For a binding between a name and an entity at a block scope,
this is the `struct cp_binding_level' for the block. */
#define BINDING_LEVEL(NODE) ((NODE)->scope.level)
/* Make DECL the innermost binding for ID. The LEVEL is the binding
level at which this declaration is being bound. */
static void
push_binding (tree id, tree decl, struct cp_binding_level* level)
push_binding (tree id, tree decl, cxx_scope* level)
{
cxx_binding *binding = cxx_binding_make (decl, NULL);
/* Now, fill in the binding information. */
binding->previous = IDENTIFIER_BINDING (id);
BINDING_LEVEL (binding) = level;
BINDING_SCOPE (binding) = level;
INHERITED_VALUE_BINDING_P (binding) = 0;
LOCAL_BINDING_P (binding) = (level != class_binding_level);
BINDING_HAS_LEVEL_P (binding) = 1;
/* And put it on the front of the list of bindings for ID. */
IDENTIFIER_BINDING (id) = binding;
......@@ -1070,7 +1064,7 @@ push_class_binding (tree id, tree decl)
other purpose. */
note_name_declared_in_class (id, decl);
if (binding && BINDING_LEVEL (binding) == class_binding_level)
if (binding && BINDING_SCOPE (binding) == class_binding_level)
/* Supplement the existing binding. */
result = add_binding (id, decl);
else
......@@ -1148,9 +1142,9 @@ pop_binding (tree id, tree decl)
/* Add it to the free list. */
cxx_binding_free (binding);
/* Clear the BINDING_LEVEL so the garbage collector doesn't walk
/* Clear the BINDING_SCOPE so the garbage collector doesn't walk
it. */
BINDING_LEVEL (binding) = NULL;
BINDING_SCOPE (binding) = NULL;
}
}
......@@ -1367,7 +1361,7 @@ poplevel (int keep, int reverse, int functionbody)
ns_binding = NULL_TREE;
if (outer_binding
&& (BINDING_LEVEL (outer_binding)
&& (BINDING_SCOPE (outer_binding)
== current_binding_level->level_chain))
/* We have something like:
......@@ -1414,9 +1408,8 @@ poplevel (int keep, int reverse, int functionbody)
dead_vars_from_for);
/* Although we don't pop the cxx_binding, we do clear
its BINDING_LEVEL since the level is going away now. */
BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link)))
= 0;
its BINDING_SCOPE since the level is going away now. */
BINDING_SCOPE (IDENTIFIER_BINDING (DECL_NAME (link))) = 0;
}
}
else
......@@ -1641,7 +1634,7 @@ poplevel_class (void)
cxx_binding *binding;
binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
while (binding && BINDING_LEVEL (binding) != b)
while (binding && BINDING_SCOPE (binding) != b)
binding = binding->previous;
if (binding)
......@@ -2006,105 +1999,6 @@ print_binding_stack (void)
the identifier is polymorphic, with three possible values:
NULL_TREE, a list of "cxx_binding"s. */
/* Check whether the a binding for the name to scope is known.
Assumes that the bindings of the name are already a list
of bindings. Returns the binding found, or NULL_TREE. */
static inline cxx_binding *
find_binding (tree name, tree scope, cxx_binding *front)
{
cxx_binding *iter;
cxx_binding *prev = NULL;
timevar_push (TV_NAME_LOOKUP);
scope = ORIGINAL_NAMESPACE (scope);
for (iter = front; iter != NULL; iter = iter->previous)
{
if (BINDING_SCOPE (iter) == scope)
{
/* Move binding found to the front of the list, so
subsequent lookups will find it faster. */
if (prev)
{
prev->previous = iter->previous;
iter->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, iter);
}
prev = iter;
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL);
}
/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
cxx_binding *
cxx_scope_find_binding_for_name (tree scope, tree name)
{
cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
if (b)
{
scope = ORIGINAL_NAMESPACE (scope);
/* Fold-in case where NAME is used only once. */
if (scope == BINDING_SCOPE (b) && b->previous == NULL)
return b;
return find_binding (name, scope, b);
}
return b;
}
/* Always returns a binding for name in scope. If the
namespace_bindings is not a list, convert it to one first.
If no binding is found, make a new one. */
cxx_binding *
binding_for_name (tree name, tree scope)
{
cxx_binding *result;
scope = ORIGINAL_NAMESPACE (scope);
result = cxx_scope_find_binding_for_name (scope, name);
if (result)
return result;
/* Not found, make a new one. */
result = cxx_binding_make (NULL, NULL);
result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
BINDING_SCOPE (result) = scope;
result->is_local = false;
result->value_is_inherited = false;
result->has_level = false;
IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
return result;
}
/* Return the binding value for name in scope. */
tree
namespace_binding (tree name, tree scope)
{
cxx_binding *b =
cxx_scope_find_binding_for_name (scope ? scope : global_namespace, name);
return b ? b->value : NULL_TREE;
}
/* Set the binding value for name in scope. If modifying the binding
of global_namespace is attempted, try to optimize it. */
void
set_namespace_binding (tree name, tree scope, tree val)
{
cxx_binding *b;
timevar_push (TV_NAME_LOOKUP);
if (scope == NULL_TREE)
scope = global_namespace;
b = binding_for_name (name, scope);
BINDING_VALUE (b) = val;
timevar_pop (TV_NAME_LOOKUP);
}
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
select a name that is unique to this compilation unit. */
......@@ -2425,7 +2319,8 @@ set_identifier_type_value_with_scope (tree id,
}
else
{
cxx_binding *binding = binding_for_name (id, current_namespace);
cxx_binding *binding =
binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
BINDING_TYPE (binding) = type;
/* Store marker instead of real type. */
type = global_type_node;
......@@ -4532,7 +4427,7 @@ push_overloaded_decl (tree decl, int flags)
{
tree *d;
for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names;
for (d = &BINDING_SCOPE (IDENTIFIER_BINDING (name))->names;
*d;
d = &TREE_CHAIN (*d))
if (*d == old
......@@ -5203,7 +5098,7 @@ follow_tag_typedef (tree type)
/* Given NAME, an IDENTIFIER_NODE,
return the structure (or union or enum) definition for that name.
Searches binding levels from BINDING_LEVEL up to the global level.
Searches binding levels from BINDING_SCOPE up to the global level.
If THISLEVEL_ONLY is nonzero, searches only the specified context
(but skips any tag-transparent contexts to find one that is
meaningful for tags).
......@@ -5238,7 +5133,7 @@ lookup_tag (enum tree_code form, tree name,
for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
{
cxx_binding *binding =
cxx_scope_find_binding_for_name (tail, name);
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
tree old;
/* If we just skipped past a template parameter level,
......@@ -5753,7 +5648,8 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
for (; !val; scope = CP_DECL_CONTEXT (scope))
{
cxx_binding *b = cxx_scope_find_binding_for_name (scope, name);
cxx_binding *b =
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
if (spacesp)
*spacesp = tree_cons (scope, NULL_TREE, *spacesp);
......@@ -6060,7 +5956,7 @@ lookup_name_current_level (tree name)
{
while (1)
{
if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b)
if (BINDING_SCOPE (IDENTIFIER_BINDING (name)) == b)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
if (b->keep == 2)
......@@ -7975,7 +7871,7 @@ maybe_inject_for_scope_var (tree decl)
cxx_binding *outer_binding
= IDENTIFIER_BINDING (DECL_NAME (decl))->previous;
if (outer_binding && BINDING_LEVEL (outer_binding) == outer
if (outer_binding && BINDING_SCOPE (outer_binding) == outer
&& (TREE_CODE (BINDING_VALUE (outer_binding)) == VAR_DECL)
&& DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
{
......
......@@ -3632,10 +3632,11 @@ lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
for (iter = usings; iter; iter = TREE_CHAIN (iter))
if (TREE_VALUE (iter) == scope)
{
tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
cxx_binding *val1 =
cxx_scope_find_binding_for_name (TREE_PURPOSE (iter), name);
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
if (spacesp)
*spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE, *spacesp);
*spacesp = tree_cons (used, NULL_TREE, *spacesp);
/* Resolve ambiguities. */
if (val1)
val = ambiguous_decl (name, val, val1, flags);
......@@ -3663,7 +3664,8 @@ qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
scope = ORIGINAL_NAMESPACE (scope);
while (scope && result->value != error_mark_node)
{
cxx_binding *binding = cxx_scope_find_binding_for_name (scope, name);
cxx_binding *binding =
cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
seen = tree_cons (scope, NULL_TREE, seen);
if (binding)
result = ambiguous_decl (name, result, binding, flags);
......@@ -4355,7 +4357,7 @@ do_toplevel_using_decl (tree decl)
if (decl == NULL_TREE)
return;
binding = binding_for_name (name, current_namespace);
binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
oldval = BINDING_VALUE (binding);
oldtype = BINDING_TYPE (binding);
......
......@@ -2,20 +2,20 @@
Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
......@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h"
#include "cp-tree.h"
#include "name-lookup.h"
#include "timevar.h"
/* A free list of "cxx_binding"s, connected by their PREVIOUS. */
static GTY((deletable (""))) cxx_binding *free_bindings;
......@@ -56,3 +57,86 @@ cxx_binding_free (cxx_binding *binding)
binding->previous = free_bindings;
free_bindings = binding;
}
/* Return (from the stack of) the BINDING, if any, establihsed at SCOPE. */
static inline cxx_binding *
find_binding (cxx_scope *scope, cxx_binding *binding)
{
timevar_push (TV_NAME_LOOKUP);
for (; binding != NULL; binding = binding->previous)
if (BINDING_SCOPE (binding) == scope)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL);
}
/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
cxx_binding *
cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
{
cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
if (b)
{
/* Fold-in case where NAME is used only once. */
if (scope == BINDING_SCOPE (b) && b->previous == NULL)
return b;
return find_binding (scope, b);
}
return NULL;
}
/* Always returns a binding for name in scope. If no binding is
found, make a new one. */
cxx_binding *
binding_for_name (cxx_scope *scope, tree name)
{
cxx_binding *result;
result = cxx_scope_find_binding_for_name (scope, name);
if (result)
return result;
/* Not found, make a new one. */
result = cxx_binding_make (NULL, NULL);
result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
BINDING_SCOPE (result) = scope;
result->is_local = false;
result->value_is_inherited = false;
IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
return result;
}
/* Namespace-scope manipulation routines. */
/* Return the binding value for name in scope. */
tree
namespace_binding (tree name, tree scope)
{
cxx_binding *binding;
if (scope == NULL)
scope = global_namespace;
scope = ORIGINAL_NAMESPACE (scope);
binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
return binding ? binding->value : NULL_TREE;
}
/* Set the binding value for name in scope. */
void
set_namespace_binding (tree name, tree scope, tree val)
{
cxx_binding *b;
timevar_push (TV_NAME_LOOKUP);
if (scope == NULL_TREE)
scope = global_namespace;
b = binding_for_name (NAMESPACE_LEVEL (scope), name);
BINDING_VALUE (b) = val;
timevar_pop (TV_NAME_LOOKUP);
}
......@@ -2,20 +2,20 @@
Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
......@@ -32,6 +32,9 @@ typedef struct cxx_saved_binding cxx_saved_binding;
a name and a C++ entity. */
typedef struct cxx_binding cxx_binding;
/* The datatype used to implement C++ scope. */
typedef struct cp_binding_level cxx_scope;
/* Nonzero if this binding is for a local scope, as opposed to a class
or namespace scope. */
#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
......@@ -42,13 +45,8 @@ typedef struct cxx_binding cxx_binding;
/* For a binding between a name and an entity at a non-local scope,
defines the scope where the binding is declared. (Either a class
_TYPE node, or a NAMESPACE_DECL.) This macro should be used only
for namespace-level bindings; on the IDENTIFIER_BINDING list
BINDING_LEVEL is used instead. */
#define BINDING_SCOPE(NODE) ((NODE)->scope.scope)
/* Nonzero if NODE has BINDING_LEVEL, rather than BINDING_SCOPE. */
#define BINDING_HAS_LEVEL_P(NODE) ((NODE)->has_level)
_TYPE node, or a NAMESPACE_DECL.). */
#define BINDING_SCOPE(NODE) ((NODE)->scope)
/* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */
......@@ -68,11 +66,8 @@ struct cxx_binding GTY(())
tree value;
/* The type entity this name is bound to. */
tree type;
union tree_binding_u {
tree GTY ((tag ("0"))) scope;
struct cp_binding_level * GTY ((tag ("1"))) level;
} GTY ((desc ("%0.has_level"))) scope;
unsigned has_level : 1;
/* The scope at which this binding was made. */
cxx_scope *scope;
unsigned value_is_inherited : 1;
unsigned is_local : 1;
};
......@@ -81,5 +76,10 @@ extern cxx_binding *cxx_binding_make (tree, tree);
extern void cxx_binding_free (cxx_binding *);
extern cxx_binding *cxx_scope_find_binding_for_name (cxx_scope *, tree);
extern cxx_binding *binding_for_name (cxx_scope *, tree);
extern tree namespace_binding (tree, tree);
extern void set_namespace_binding (tree, tree, tree);
#endif /* GCC_CP_NAME_LOOKUP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment