+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.
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)
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);
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;
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);
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;
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
/* 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;
}
}
ns_binding = NULL_TREE;
if (outer_binding
- && (BINDING_LEVEL (outer_binding)
+ && (BINDING_SCOPE (outer_binding)
== current_binding_level->level_chain))
/* We have something like:
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
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)
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. */
}
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;
{
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
/* 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).
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,
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);
{
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)
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)))
{
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);
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);
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);
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. */
#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;
binding->previous = free_bindings;
free_bindings = binding;
}
+\f
+/* 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;
+}
+\f
+/* 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);
+}
+
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. */
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)
/* 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. */
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;
};
extern void cxx_binding_free (cxx_binding *);
\f
+extern cxx_binding *cxx_scope_find_binding_for_name (cxx_scope *, tree);
+extern cxx_binding *binding_for_name (cxx_scope *, tree);
+\f
+extern tree namespace_binding (tree, tree);
+extern void set_namespace_binding (tree, tree, tree);
#endif /* GCC_CP_NAME_LOOKUP_H */