/* Definitions for C++ name lookup routines. Copyright (C) 2003 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. 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. 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 GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" #include "coretypes.h" #include "tm.h" #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; /* (GC)-allocate a binding object with VALUE and TYPE member initialized. */ cxx_binding * cxx_binding_make (tree value, tree type) { cxx_binding *binding; if (free_bindings) { binding = free_bindings; free_bindings = binding->previous; } else binding = ggc_alloc_cleared (sizeof (cxx_binding)); binding->value = value; binding->type = type; return binding; } /* Put BINDING back on the free list. */ void 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, (cxx_binding *)0); } /* 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); } #include "gt-cp-name-lookup.h"