From ed3cf9539b38d56097601dd56acd1433931ed603 Mon Sep 17 00:00:00 2001 From: Gabriel Dos Reis Date: Sun, 30 Mar 2003 16:00:39 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 32 ++++++++++ gcc/cp/cp-tree.h | 6 +- gcc/cp/decl.c | 140 ++++++------------------------------------- gcc/cp/decl2.c | 10 ++-- gcc/cp/name-lookup.c | 92 ++++++++++++++++++++++++++-- gcc/cp/name-lookup.h | 32 +++++----- 6 files changed, 162 insertions(+), 150 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac6cc4adae0..159697f7325 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,35 @@ +2003-03-30 Gabriel Dos Reis + + * 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 * name-lookup.c: New file. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 88becd6a23a..a9692fe2842 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 492fc370b1b..602a116e851 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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))) { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 88545d46281..b7b0054b7ee 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 9153823c02f..3eb010a8d1f 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2,20 +2,20 @@ Copyright (C) 2003 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis -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); +} + diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index aaba6e13775..f6a4131fe5b 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -2,20 +2,20 @@ Copyright (C) 2003 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis -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 */ -- 2.30.2