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> 2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
* name-lookup.c: New file. * name-lookup.c: New file.
......
...@@ -380,8 +380,8 @@ struct tree_srcloc GTY(()) ...@@ -380,8 +380,8 @@ struct tree_srcloc GTY(())
BINDING_VALUE is a DECL for the associated declaration. Thus, BINDING_VALUE is a DECL for the associated declaration. Thus,
name lookup consists simply of pulling off the node at the front name lookup consists simply of pulling off the node at the front
of the list (modulo oddities for looking up the names of types, of the list (modulo oddities for looking up the names of types,
and such.) You can use BINDING_SCOPE or BINDING_LEVEL to and such.) You can use BINDING_SCOPE to determine the scope
determine the scope that bound the name. */ that bound the name. */
#define IDENTIFIER_BINDING(NODE) \ #define IDENTIFIER_BINDING(NODE) \
(LANG_IDENTIFIER_CAST (NODE)->bindings) (LANG_IDENTIFIER_CAST (NODE)->bindings)
...@@ -3663,7 +3663,6 @@ extern tree declare_local_label (tree); ...@@ -3663,7 +3663,6 @@ extern tree declare_local_label (tree);
extern tree define_label (const char *, int, tree); extern tree define_label (const char *, int, tree);
extern void check_goto (tree); extern void check_goto (tree);
extern void define_case_label (void); extern void define_case_label (void);
extern cxx_binding *binding_for_name (tree, tree);
extern tree namespace_binding (tree, tree); extern tree namespace_binding (tree, tree);
extern void set_namespace_binding (tree, tree, tree); extern void set_namespace_binding (tree, tree, tree);
extern tree lookup_namespace_name (tree, tree); extern tree lookup_namespace_name (tree, tree);
...@@ -3753,7 +3752,6 @@ extern int nonstatic_local_decl_p (tree); ...@@ -3753,7 +3752,6 @@ extern int nonstatic_local_decl_p (tree);
extern tree declare_global_var (tree, tree); extern tree declare_global_var (tree, tree);
extern void register_dtor_fn (tree); extern void register_dtor_fn (tree);
extern tmpl_spec_kind current_tmpl_spec_kind (int); 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 tree cp_fname_init (const char *);
extern bool have_extern_spec; extern bool have_extern_spec;
......
...@@ -98,7 +98,6 @@ static void push_binding (tree, tree, struct cp_binding_level*); ...@@ -98,7 +98,6 @@ static void push_binding (tree, tree, struct cp_binding_level*);
static int add_binding (tree, tree); static int add_binding (tree, tree);
static void pop_binding (tree, tree); static void pop_binding (tree, tree);
static tree local_variable_p_walkfn (tree *, int *, void *); 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 tree select_decl (cxx_binding *, int);
static int lookup_flags (int, int); static int lookup_flags (int, int);
static tree qualify_lookup (tree, int); static tree qualify_lookup (tree, int);
...@@ -885,24 +884,19 @@ finish_scope (void) ...@@ -885,24 +884,19 @@ finish_scope (void)
poplevel (0, 0, 0); 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 /* Make DECL the innermost binding for ID. The LEVEL is the binding
level at which this declaration is being bound. */ level at which this declaration is being bound. */
static void 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); cxx_binding *binding = cxx_binding_make (decl, NULL);
/* Now, fill in the binding information. */ /* Now, fill in the binding information. */
binding->previous = IDENTIFIER_BINDING (id); binding->previous = IDENTIFIER_BINDING (id);
BINDING_LEVEL (binding) = level; BINDING_SCOPE (binding) = level;
INHERITED_VALUE_BINDING_P (binding) = 0; INHERITED_VALUE_BINDING_P (binding) = 0;
LOCAL_BINDING_P (binding) = (level != class_binding_level); 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. */ /* And put it on the front of the list of bindings for ID. */
IDENTIFIER_BINDING (id) = binding; IDENTIFIER_BINDING (id) = binding;
...@@ -1070,7 +1064,7 @@ push_class_binding (tree id, tree decl) ...@@ -1070,7 +1064,7 @@ push_class_binding (tree id, tree decl)
other purpose. */ other purpose. */
note_name_declared_in_class (id, decl); 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. */ /* Supplement the existing binding. */
result = add_binding (id, decl); result = add_binding (id, decl);
else else
...@@ -1148,9 +1142,9 @@ pop_binding (tree id, tree decl) ...@@ -1148,9 +1142,9 @@ pop_binding (tree id, tree decl)
/* Add it to the free list. */ /* Add it to the free list. */
cxx_binding_free (binding); 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. */ it. */
BINDING_LEVEL (binding) = NULL; BINDING_SCOPE (binding) = NULL;
} }
} }
...@@ -1367,7 +1361,7 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -1367,7 +1361,7 @@ poplevel (int keep, int reverse, int functionbody)
ns_binding = NULL_TREE; ns_binding = NULL_TREE;
if (outer_binding if (outer_binding
&& (BINDING_LEVEL (outer_binding) && (BINDING_SCOPE (outer_binding)
== current_binding_level->level_chain)) == current_binding_level->level_chain))
/* We have something like: /* We have something like:
...@@ -1414,9 +1408,8 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -1414,9 +1408,8 @@ poplevel (int keep, int reverse, int functionbody)
dead_vars_from_for); dead_vars_from_for);
/* Although we don't pop the cxx_binding, we do clear /* Although we don't pop the cxx_binding, we do clear
its BINDING_LEVEL since the level is going away now. */ its BINDING_SCOPE since the level is going away now. */
BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link))) BINDING_SCOPE (IDENTIFIER_BINDING (DECL_NAME (link))) = 0;
= 0;
} }
} }
else else
...@@ -1641,7 +1634,7 @@ poplevel_class (void) ...@@ -1641,7 +1634,7 @@ poplevel_class (void)
cxx_binding *binding; cxx_binding *binding;
binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
while (binding && BINDING_LEVEL (binding) != b) while (binding && BINDING_SCOPE (binding) != b)
binding = binding->previous; binding = binding->previous;
if (binding) if (binding)
...@@ -2006,105 +1999,6 @@ print_binding_stack (void) ...@@ -2006,105 +1999,6 @@ print_binding_stack (void)
the identifier is polymorphic, with three possible values: the identifier is polymorphic, with three possible values:
NULL_TREE, a list of "cxx_binding"s. */ 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 /* 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. */ select a name that is unique to this compilation unit. */
...@@ -2425,7 +2319,8 @@ set_identifier_type_value_with_scope (tree id, ...@@ -2425,7 +2319,8 @@ set_identifier_type_value_with_scope (tree id,
} }
else 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; BINDING_TYPE (binding) = type;
/* Store marker instead of real type. */ /* Store marker instead of real type. */
type = global_type_node; type = global_type_node;
...@@ -4532,7 +4427,7 @@ push_overloaded_decl (tree decl, int flags) ...@@ -4532,7 +4427,7 @@ push_overloaded_decl (tree decl, int flags)
{ {
tree *d; tree *d;
for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names; for (d = &BINDING_SCOPE (IDENTIFIER_BINDING (name))->names;
*d; *d;
d = &TREE_CHAIN (*d)) d = &TREE_CHAIN (*d))
if (*d == old if (*d == old
...@@ -5203,7 +5098,7 @@ follow_tag_typedef (tree type) ...@@ -5203,7 +5098,7 @@ follow_tag_typedef (tree type)
/* Given NAME, an IDENTIFIER_NODE, /* Given NAME, an IDENTIFIER_NODE,
return the structure (or union or enum) definition for that name. 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 If THISLEVEL_ONLY is nonzero, searches only the specified context
(but skips any tag-transparent contexts to find one that is (but skips any tag-transparent contexts to find one that is
meaningful for tags). meaningful for tags).
...@@ -5238,7 +5133,7 @@ lookup_tag (enum tree_code form, tree name, ...@@ -5238,7 +5133,7 @@ lookup_tag (enum tree_code form, tree name,
for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
{ {
cxx_binding *binding = cxx_binding *binding =
cxx_scope_find_binding_for_name (tail, name); cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
tree old; tree old;
/* If we just skipped past a template parameter level, /* If we just skipped past a template parameter level,
...@@ -5753,7 +5648,8 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp) ...@@ -5753,7 +5648,8 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
for (; !val; scope = CP_DECL_CONTEXT (scope)) 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) if (spacesp)
*spacesp = tree_cons (scope, NULL_TREE, *spacesp); *spacesp = tree_cons (scope, NULL_TREE, *spacesp);
...@@ -6060,7 +5956,7 @@ lookup_name_current_level (tree name) ...@@ -6060,7 +5956,7 @@ lookup_name_current_level (tree name)
{ {
while (1) 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)); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
if (b->keep == 2) if (b->keep == 2)
...@@ -7975,7 +7871,7 @@ maybe_inject_for_scope_var (tree decl) ...@@ -7975,7 +7871,7 @@ maybe_inject_for_scope_var (tree decl)
cxx_binding *outer_binding cxx_binding *outer_binding
= IDENTIFIER_BINDING (DECL_NAME (decl))->previous; = 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) && (TREE_CODE (BINDING_VALUE (outer_binding)) == VAR_DECL)
&& DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding))) && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
{ {
......
...@@ -3632,10 +3632,11 @@ lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope, ...@@ -3632,10 +3632,11 @@ lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
for (iter = usings; iter; iter = TREE_CHAIN (iter)) for (iter = usings; iter; iter = TREE_CHAIN (iter))
if (TREE_VALUE (iter) == scope) if (TREE_VALUE (iter) == scope)
{ {
tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
cxx_binding *val1 = 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) if (spacesp)
*spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE, *spacesp); *spacesp = tree_cons (used, NULL_TREE, *spacesp);
/* Resolve ambiguities. */ /* Resolve ambiguities. */
if (val1) if (val1)
val = ambiguous_decl (name, val, val1, flags); val = ambiguous_decl (name, val, val1, flags);
...@@ -3663,7 +3664,8 @@ qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result, ...@@ -3663,7 +3664,8 @@ qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
scope = ORIGINAL_NAMESPACE (scope); scope = ORIGINAL_NAMESPACE (scope);
while (scope && result->value != error_mark_node) 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); seen = tree_cons (scope, NULL_TREE, seen);
if (binding) if (binding)
result = ambiguous_decl (name, result, binding, flags); result = ambiguous_decl (name, result, binding, flags);
...@@ -4355,7 +4357,7 @@ do_toplevel_using_decl (tree decl) ...@@ -4355,7 +4357,7 @@ do_toplevel_using_decl (tree decl)
if (decl == NULL_TREE) if (decl == NULL_TREE)
return; return;
binding = binding_for_name (name, current_namespace); binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
oldval = BINDING_VALUE (binding); oldval = BINDING_VALUE (binding);
oldtype = BINDING_TYPE (binding); oldtype = BINDING_TYPE (binding);
......
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
Copyright (C) 2003 Free Software Foundation, Inc. Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. 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 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
...@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h" #include "tree.h"
#include "cp-tree.h" #include "cp-tree.h"
#include "name-lookup.h" #include "name-lookup.h"
#include "timevar.h"
/* A free list of "cxx_binding"s, connected by their PREVIOUS. */ /* A free list of "cxx_binding"s, connected by their PREVIOUS. */
static GTY((deletable (""))) cxx_binding *free_bindings; static GTY((deletable (""))) cxx_binding *free_bindings;
...@@ -56,3 +57,86 @@ cxx_binding_free (cxx_binding *binding) ...@@ -56,3 +57,86 @@ cxx_binding_free (cxx_binding *binding)
binding->previous = free_bindings; binding->previous = free_bindings;
free_bindings = binding; 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 @@ ...@@ -2,20 +2,20 @@
Copyright (C) 2003 Free Software Foundation, Inc. Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. 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 but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
...@@ -32,6 +32,9 @@ typedef struct cxx_saved_binding cxx_saved_binding; ...@@ -32,6 +32,9 @@ typedef struct cxx_saved_binding cxx_saved_binding;
a name and a C++ entity. */ a name and a C++ entity. */
typedef struct cxx_binding cxx_binding; 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 /* Nonzero if this binding is for a local scope, as opposed to a class
or namespace scope. */ or namespace scope. */
#define LOCAL_BINDING_P(NODE) ((NODE)->is_local) #define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
...@@ -42,13 +45,8 @@ typedef struct cxx_binding cxx_binding; ...@@ -42,13 +45,8 @@ typedef struct cxx_binding cxx_binding;
/* For a binding between a name and an entity at a non-local scope, /* 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 defines the scope where the binding is declared. (Either a class
_TYPE node, or a NAMESPACE_DECL.) This macro should be used only _TYPE node, or a NAMESPACE_DECL.). */
for namespace-level bindings; on the IDENTIFIER_BINDING list #define BINDING_SCOPE(NODE) ((NODE)->scope)
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)
/* This is the declaration bound to the name. Possible values: /* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */ variable, overloaded function, namespace, template, enumerator. */
...@@ -68,11 +66,8 @@ struct cxx_binding GTY(()) ...@@ -68,11 +66,8 @@ struct cxx_binding GTY(())
tree value; tree value;
/* The type entity this name is bound to. */ /* The type entity this name is bound to. */
tree type; tree type;
union tree_binding_u { /* The scope at which this binding was made. */
tree GTY ((tag ("0"))) scope; cxx_scope *scope;
struct cp_binding_level * GTY ((tag ("1"))) level;
} GTY ((desc ("%0.has_level"))) scope;
unsigned has_level : 1;
unsigned value_is_inherited : 1; unsigned value_is_inherited : 1;
unsigned is_local : 1; unsigned is_local : 1;
}; };
...@@ -81,5 +76,10 @@ extern cxx_binding *cxx_binding_make (tree, tree); ...@@ -81,5 +76,10 @@ extern cxx_binding *cxx_binding_make (tree, tree);
extern void cxx_binding_free (cxx_binding *); 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 */ #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