OSDN Git Service

Break out decl.c (2/n)
authorgdr <gdr@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Oct 2003 10:26:36 +0000 (10:26 +0000)
committergdr <gdr@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Oct 2003 10:26:36 +0000 (10:26 +0000)
* name-lookup.c: Include diagnostic.h
(cxx_binding_free): Make static.
(cxx_binding_make): Likewise.
(binding_table_new): Likewise
(binding_table_free): Likewise.
(binding_table_insert): Likewise.
(binding_table_find_anon_type): Likewise.
(binding_table_reverse_maybe_remap): Likewise.
(supplement_binding): Likewise.
* name-lookup.h (global_scope_name): Declare extern.
(global_type_node): Likewise.
(cxx_binding_free): Don't export.
(cxx_binding_make): Likewise.
(binding_table_new): Likewise.
(binding_table_free): Likewise.
(binding_table_insert): Likewise.
(binding_table_find_anon_type): Likewise.
(binding_table_reverse_maybe_remap): Likewise.
* Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H)
* decl.c (lookup_namespace_name): Move to name-lookup.c
(select_decl): Likewise.
(unqualified_namespace_lookup): Likewise.
(lookup_qualified_name): Likewise.
(lookup_name_real): Likewise.
(lookup_name_nonclass): Likewise.
(lookup_function_nonclass): Likewise.
(lookup_name): Likewise.
(lookup_name_current_level): Likewise.
(lookup_type_current_level): Likewise.
(lookup_flags): Likewise.
(qualify_lookup): Likewise.
(lookup_tag): Likewise.
(lookup_tag_reverse): Likewise.
(getdecls): Likewise.
(storedecls): Remove.
(cxx_remember_type_decls): Likewise.
(global_bindings_p): Likewise.
(innermost_nonclass_level): Likewise.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(kept_level_p): Likewise.
(innermost_scope_kind): Likewise.
(template_parm_scope_p): Likewise.
(push_binding): Likewise.
(push_local_binding): Likewise.
(add_decl_to_level): Likewise.  Make extern.
(push_class_binding): Move to name-lookup.c.
(resume_level): Likewise.  Rename to resume_scope.
(begin_scope): Likewise.
(indent): Likewise.
(binding_depth): Likewise.
(is_class_level): Likewise.
(cxx_scope_descriptor): Likewise.
(cxx_scope_debug): Likewise.
(namespace_scope_ht_size): Likewise.
(leave_scope): Likewise.
(pushlevel_class): Likewise.
(poplevel_class): Likewise.
(clear_identifier_class_values): Likewise.
(pushdecl_with_scope): Likewise.
(pushdecl_namespace_level): Likewise.
(pushdecl_class_level): Likewise.
(push_class_level_binding): Likewise.
(push_using_directive): Likewise.
(identifier_global_value): Likewise.
(keep_next_level_flag): Likewise.
(keep_next_level): Likewise.
(free_binding_level): Likewise.
(set_class_shadows): Likewise.
(maybe_push_cleanup_level): Likewise.
(cp_namespace_decls): Likewise.
(bt_print_entry): Likewise.
(print_binding_level): Likewise.
(print_other_binding_stack): Likewise.
(print_binding_stack): Likewise.
(push_namespace): Likewise.
(pop_namespace): Likewise.
(push_nested_namespace): Likewise.
(pop_nested_namespace): Likewise.
(cxx_saved_binding_make): Likewise.
(struct cxx_saved_binding_make): Likewise.
(store_bindings): Likewise.
(maybe_push_to_top_level): Likewise.
(push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
(identifier_type_value): Likewise.
(set_identifier_type_value): Likewise.
(set_identifier_type_value_with_scope): Likewise.
(pop_everything): Likewise.
(pushtag): Likewise.
(follow_tag_typedef): Likewise.
(maybe_process_template_type_declaration): Likewise.
(pop_binding): Likewise.
* cp-tree.h: Move corresponding declarations to name-lookup.h

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72426 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h

index 9a0735b..be4eba0 100644 (file)
@@ -1,3 +1,101 @@
+2003-10-13  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+       Break out decl.c (2/n) 
+       * name-lookup.c: Include diagnostic.h
+       (cxx_binding_free): Make static.
+       (cxx_binding_make): Likewise.
+       (binding_table_new): Likewise
+       (binding_table_free): Likewise.
+       (binding_table_insert): Likewise.
+       (binding_table_find_anon_type): Likewise.
+       (binding_table_reverse_maybe_remap): Likewise.
+       (supplement_binding): Likewise.
+       * name-lookup.h (global_scope_name): Declare extern.
+       (global_type_node): Likewise.
+       (cxx_binding_free): Don't export.
+       (cxx_binding_make): Likewise.
+       (binding_table_new): Likewise.
+       (binding_table_free): Likewise.
+       (binding_table_insert): Likewise.
+       (binding_table_find_anon_type): Likewise.
+       (binding_table_reverse_maybe_remap): Likewise.
+       * Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H)
+       * decl.c (lookup_namespace_name): Move to name-lookup.c
+       (select_decl): Likewise.
+       (unqualified_namespace_lookup): Likewise.
+       (lookup_qualified_name): Likewise.
+       (lookup_name_real): Likewise.
+       (lookup_name_nonclass): Likewise.
+       (lookup_function_nonclass): Likewise.
+       (lookup_name): Likewise.
+       (lookup_name_current_level): Likewise.
+       (lookup_type_current_level): Likewise.
+       (lookup_flags): Likewise.
+       (qualify_lookup): Likewise.
+       (lookup_tag): Likewise.
+       (lookup_tag_reverse): Likewise.
+       (getdecls): Likewise.
+       (storedecls): Remove.
+       (cxx_remember_type_decls): Likewise.
+       (global_bindings_p): Likewise.
+       (innermost_nonclass_level): Likewise.
+       (toplevel_bindings_p): Likewise.
+       (namespace_bindings_p): Likewise.
+       (kept_level_p): Likewise.
+       (innermost_scope_kind): Likewise.
+       (template_parm_scope_p): Likewise.
+       (push_binding): Likewise.
+       (push_local_binding): Likewise.
+       (add_decl_to_level): Likewise.  Make extern.
+       (push_class_binding): Move to name-lookup.c.
+       (resume_level): Likewise.  Rename to resume_scope.
+       (begin_scope): Likewise.
+       (indent): Likewise.
+       (binding_depth): Likewise.
+       (is_class_level): Likewise.
+       (cxx_scope_descriptor): Likewise.
+       (cxx_scope_debug): Likewise.
+       (namespace_scope_ht_size): Likewise.
+       (leave_scope): Likewise.
+       (pushlevel_class): Likewise.
+       (poplevel_class): Likewise.
+       (clear_identifier_class_values): Likewise.
+       (pushdecl_with_scope): Likewise.
+       (pushdecl_namespace_level): Likewise.
+       (pushdecl_class_level): Likewise.
+       (push_class_level_binding): Likewise.
+       (push_using_directive): Likewise.
+       (identifier_global_value): Likewise.
+       (keep_next_level_flag): Likewise.
+       (keep_next_level): Likewise.
+       (free_binding_level): Likewise.
+       (set_class_shadows): Likewise.
+       (maybe_push_cleanup_level): Likewise.
+       (cp_namespace_decls): Likewise.
+       (bt_print_entry): Likewise.
+       (print_binding_level): Likewise.
+       (print_other_binding_stack): Likewise.
+       (print_binding_stack): Likewise.
+       (push_namespace): Likewise.
+       (pop_namespace): Likewise.
+       (push_nested_namespace): Likewise.
+       (pop_nested_namespace): Likewise.
+       (cxx_saved_binding_make): Likewise.
+       (struct cxx_saved_binding_make): Likewise.
+       (store_bindings): Likewise.
+       (maybe_push_to_top_level): Likewise.
+       (push_to_top_level): Likewise.
+       (pop_from_top_level): Likewise.
+       (identifier_type_value): Likewise.
+       (set_identifier_type_value): Likewise.
+       (set_identifier_type_value_with_scope): Likewise.
+       (pop_everything): Likewise.
+       (pushtag): Likewise.
+       (follow_tag_typedef): Likewise.
+       (maybe_process_template_type_declaration): Likewise.
+       (pop_binding): Likewise.
+       * cp-tree.h: Move corresponding declarations to name-lookup.h
+       
 2003-10-12  Steven Bosscher  <steven@gcc.gnu.org>
 
        * cvt.c (ocp_convert): Move warning to C common code.
index a975273..52a5a0c 100644 (file)
@@ -279,7 +279,8 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $(
 cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h
 
 cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-       $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h
+       $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h \
+       $(DIAGNOSTIC_H)
 
 cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \
   $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H)
index f4582c3..f3286d6 100644 (file)
@@ -3584,9 +3584,6 @@ extern void clone_function_decl                 (tree, int);
 extern void adjust_clone_args                  (tree);
 
 /* decl.c */
-extern int global_bindings_p                   (void);
-extern int kept_level_p                                (void);
-extern tree getdecls                           (void);
 extern void insert_block                       (tree);
 extern void set_block                          (tree);
 extern tree pushdecl                           (tree);
@@ -3597,34 +3594,12 @@ extern bool cxx_mark_addressable                (tree);
 extern void cxx_push_function_context          (struct function *);
 extern void cxx_pop_function_context           (struct function *);
 extern void cxx_mark_function_context          (struct function *);
-extern int toplevel_bindings_p                 (void);
-extern int namespace_bindings_p                        (void);
-extern void keep_next_level (bool);
-extern scope_kind innermost_scope_kind          (void);
-extern int template_parm_scope_p               (void);
-extern void set_class_shadows                  (tree);
-extern void maybe_push_cleanup_level           (tree);
-extern cxx_scope *begin_scope (scope_kind, tree);
+extern void maybe_push_cleanup_level (tree);
 extern void finish_scope                        (void);
-extern void resume_level                       (struct cp_binding_level *);
 extern void delete_block                       (tree);
 extern void add_block_current_level            (tree);
-extern void pushlevel_class                    (void);
-extern void poplevel_class                      (void);
-extern void print_binding_stack                        (void);
-extern void print_binding_level                        (struct cp_binding_level *);
-extern void push_namespace                     (tree);
-extern void pop_namespace                      (void);
-extern void push_nested_namespace              (tree);
-extern void pop_nested_namespace               (tree);
-extern void maybe_push_to_top_level            (int);
-extern void push_to_top_level                  (void);
-extern void pop_from_top_level                 (void);
 extern void push_switch                                (tree);
 extern void pop_switch                         (void);
-extern tree identifier_type_value              (tree);
-extern void set_identifier_type_value          (tree, tree);
-extern void pop_everything                     (void);
 extern void pushtag                            (tree, tree, int);
 extern tree make_anon_name                     (void);
 extern void clear_anon_tags                    (void);
@@ -3632,31 +3607,16 @@ extern int decls_match                          (tree, tree);
 extern int duplicate_decls                     (tree, tree);
 extern tree pushdecl_top_level                 (tree);
 extern tree pushdecl_top_level_and_finish       (tree, tree);
-extern bool pushdecl_class_level               (tree);
-extern tree pushdecl_namespace_level            (tree);
 extern tree push_using_decl                     (tree, tree);
-extern tree push_using_directive                (tree);
-extern bool push_class_level_binding           (tree, tree);
 extern tree implicitly_declare                 (tree);
 extern tree declare_local_label                 (tree);
 extern tree define_label                       (location_t, tree);
 extern void check_goto                         (tree);
 extern void define_case_label                  (void);
-extern tree namespace_binding                   (tree, tree);
-extern void set_namespace_binding               (tree, tree, tree);
-extern tree lookup_namespace_name              (tree, tree);
 extern tree make_typename_type                 (tree, tree, tsubst_flags_t);
 extern tree make_unbound_class_template                (tree, tree, tsubst_flags_t);
-extern tree lookup_name_nonclass               (tree);
-extern tree lookup_function_nonclass            (tree, tree);
-extern tree lookup_qualified_name               (tree, tree, bool, bool);
-extern tree lookup_name                                (tree, int);
-extern tree lookup_name_current_level          (tree);
-extern tree lookup_type_current_level          (tree);
-extern tree lookup_name_real                    (tree, int, int, int, int);
 extern tree namespace_ancestor                 (tree, tree);
 extern bool is_ancestor                         (tree, tree);
-extern tree unqualified_namespace_lookup       (tree, int, tree *);
 extern tree check_for_out_of_scope_variable     (tree);
 extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *);
 extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
@@ -3705,12 +3665,8 @@ extern void revert_static_member_fn             (tree);
 extern void fixup_anonymous_aggr                (tree);
 extern int check_static_variable_definition     (tree, tree);
 extern tree compute_array_index_type           (tree, tree);
-extern void push_local_binding                  (tree, tree, int);
-extern int push_class_binding                   (tree, tree);
 extern tree check_default_argument              (tree, tree);
 extern tree push_overloaded_decl               (tree, int);
-extern void clear_identifier_class_values       (void);
-extern void storetags                           (tree);
 extern int vtable_decl_p                        (tree, void *);
 extern int vtype_decl_p                         (tree, void *);
 extern int sigtable_decl_p                      (tree, void *);
@@ -3722,7 +3678,6 @@ typedef int (*walk_namespaces_fn)               (tree, void *);
 extern int walk_namespaces                      (walk_namespaces_fn,
                                                       void *);
 extern int wrapup_globals_for_namespace         (tree, void *);
-extern tree cp_namespace_decls                  (tree);
 extern tree create_implicit_typedef             (tree, tree);
 extern tree maybe_push_decl                     (tree);
 extern tree build_target_expr_with_type         (tree, tree);
@@ -3736,6 +3691,7 @@ extern tree check_elaborated_type_specifier     (enum tag_types, tree, bool);
 extern tree cxx_builtin_type_decls              (void);
 
 extern bool have_extern_spec;
+extern GTY(()) tree last_function_parms;
 
 /* in decl2.c */
 extern bool check_java_method (tree);
index 872fed0..bcd0a5f 100644 (file)
@@ -55,14 +55,10 @@ Boston, MA 02111-1307, USA.  */
 static tree grokparms (tree);
 static const char *redeclaration_error_message (tree, tree);
 
-static void resume_binding_level (struct cp_binding_level *);
 static int decl_jump_unsafe (tree);
-static void storedecls (tree);
 static void require_complete_types_for_parms (tree);
 static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
-static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *);
-static tree lookup_tag_reverse (tree, tree);
 static void push_local_name (tree);
 static void warn_extern_redeclared_static (tree, tree);
 static tree grok_reference_init (tree, tree, tree, tree *);
@@ -70,11 +66,6 @@ static tree grokfndecl (tree, tree, tree, tree, int,
                        enum overload_flags, tree,
                        tree, int, int, int, int, int, int, tree);
 static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree);
-static tree follow_tag_typedef (tree);
-static tree lookup_tag (enum tree_code, tree,
-                       struct cp_binding_level *, int);
-static void set_identifier_type_value_with_scope
-       (tree, tree, struct cp_binding_level *);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (const char *, tree, tree, int,
                                 enum built_in_class, const char *,
@@ -83,24 +74,15 @@ static tree build_library_fn_1 (tree, enum tree_code, tree);
 static int member_function_or_else (tree, tree, enum overload_flags);
 static void bad_specifiers (tree, const char *, int, int, int, int,
                            int);
-static tree maybe_process_template_type_declaration 
-       (tree, int, struct cp_binding_level*);
 static void check_for_uninitialized_const_var (tree);
 static hashval_t typename_hash (const void *);
 static int typename_compare (const void *, const void *);
-static void push_binding (tree, tree, struct cp_binding_level*);
-static void pop_binding (tree, tree);
 static tree local_variable_p_walkfn (tree *, int *, void *);
-static tree select_decl (cxx_binding *, int);
-static int lookup_flags (int, int);
-static tree qualify_lookup (tree, int);
 static tree record_builtin_java_type (const char *, int);
 static const char *tag_name (enum tag_types code);
-static struct cp_binding_level *innermost_nonclass_level (void);
 static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
 static int walk_globals_r (tree, void*);
 static int walk_vtables_r (tree, void*);
-static void add_decl_to_level (tree, struct cp_binding_level *);
 static tree make_label_decl (tree, int);
 static void use_label (tree);
 static void check_previous_goto_1 (tree, struct cp_binding_level *, tree,
@@ -193,10 +175,10 @@ tree cp_global_trees[CPTI_MAX];
 /* Indicates that there is a type value in some namespace, although
    that is not necessarily in scope at the moment.  */
 
-static GTY(()) tree global_type_node;
+tree global_type_node;
 
 /* The node that holds the "name" of the global scope.  */
-static GTY(()) tree global_scope_name;
+tree global_scope_name;
 
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
@@ -278,331 +260,12 @@ int adding_implicit_members = 0;
 bool have_extern_spec;
 
 \f
-/* A chain of binding_level structures awaiting reuse.  */
-
-static GTY((deletable (""))) struct cp_binding_level *free_binding_level;
-
-/* true means unconditionally make a BLOCK for the next level pushed.  */
-
-static bool keep_next_level_flag;
-
 /* A TREE_LIST of VAR_DECLs.  The TREE_PURPOSE is a RECORD_TYPE or
    UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type.  At the
    time the VAR_DECL was declared, the type was incomplete.  */
 
 static GTY(()) tree incomplete_vars;
-
-#ifndef ENABLE_SCOPE_CHECKING
-#  define ENABLE_SCOPE_CHECKING 0
-#else
-#  define ENABLE_SCOPE_CHECKING 1
-#endif
-
-static int binding_depth = 0;
-static int is_class_level = 0;
-
-static void
-indent (int depth)
-{
-  int i;
-
-  for (i = 0; i < depth * 2; i++)
-    putc (' ', stderr);
-}
-
-static tree pushdecl_with_scope        (tree, struct cp_binding_level *);
-
-/* Return a string describing the kind of SCOPE we have.  */
-static const char *
-cxx_scope_descriptor (cxx_scope *scope)
-{
-  /* The order of this table must match the "scope_kind"
-     enumerators.  */
-  static const char* scope_kind_names[] = {
-    "block-scope",
-    "cleanup-scope",
-    "try-scope",
-    "catch-scope",
-    "for-scope",
-    "function-parameter-scope",
-    "class-scope",
-    "namespace-scope",
-    "template-parameter-scope",
-    "template-explicit-spec-scope"
-  };
-  const scope_kind kind = scope->explicit_spec_p
-    ? sk_template_spec : scope->kind;
-
-  return scope_kind_names[kind];
-}
-
-/* Output a debugging information about SCOPE when performning
-   ACTION at LINE.  */
-static void
-cxx_scope_debug (cxx_scope *scope, int line, const char *action)
-{
-  const char *desc = cxx_scope_descriptor (scope);
-  if (scope->this_entity)
-    verbatim ("%s %s(%E) %p %d\n", action, desc,
-              scope->this_entity, (void *) scope, line);
-  else
-    verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
-}
-
-/* Return the estimated initial size of the hashtable of a NAMESPACE
-   scope.  */
-
-static inline size_t
-namespace_scope_ht_size (tree ns)
-{
-  tree name = DECL_NAME (ns);
-
-  return name == std_identifier
-    ? NAMESPACE_STD_HT_SIZE
-    : (name == global_scope_name
-       ? GLOBAL_SCOPE_HT_SIZE
-       : NAMESPACE_ORDINARY_HT_SIZE);
-}
-
-/* Create a new KIND scope and make it the top of the active scopes stack.
-   ENTITY is the scope of the associated C++ entity (namespace, class,
-   function); it is NULL otherwise.  */
-
-cxx_scope *
-begin_scope (scope_kind kind, tree entity)
-{
-  cxx_scope *scope;
-  
-  /* Reuse or create a struct for this binding level.  */
-  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
-    {
-      scope = free_binding_level;
-      free_binding_level = scope->level_chain;
-    }
-  else
-    scope = ggc_alloc (sizeof (cxx_scope));
-  memset (scope, 0, sizeof (cxx_scope));
-
-  scope->this_entity = entity;
-  scope->more_cleanups_ok = true;
-  switch (kind)
-    {
-    case sk_cleanup:
-      scope->keep = true;
-      break;
-      
-    case sk_template_spec:
-      scope->explicit_spec_p = true;
-      kind = sk_template_parms;
-      /* fall through */
-    case sk_template_parms:
-    case sk_block:
-    case sk_try:
-    case sk_catch:
-    case sk_for:
-    case sk_class:
-    case sk_function_parms:
-      scope->keep = keep_next_level_flag;
-      break;
-
-    case sk_namespace:
-      scope->type_decls = binding_table_new (namespace_scope_ht_size (entity));
-      NAMESPACE_LEVEL (entity) = scope;
-      VARRAY_TREE_INIT (scope->static_decls,
-                        DECL_NAME (entity) == std_identifier
-                        || DECL_NAME (entity) == global_scope_name
-                        ? 200 : 10,
-                        "Static declarations");
-      break;
-
-    default:
-      /* Should not happen.  */
-      my_friendly_assert (false, 20030922);
-      break;
-    }
-  scope->kind = kind;
-
-  /* Add it to the front of currently active scopes stack.  */
-  scope->level_chain = current_binding_level;
-  current_binding_level = scope;
-  keep_next_level_flag = false;
-
-  if (ENABLE_SCOPE_CHECKING)
-    {
-      scope->binding_depth = binding_depth;
-      indent (binding_depth);
-      cxx_scope_debug (scope, input_location.line, "push");
-      is_class_level = 0;
-      binding_depth++;
-    }
-
-  return scope;
-}
-
-/* We're about to leave current scope.  Pop the top of the stack of
-   currently active scopes.  Return the enclosing scope, now active.  */
-
-static cxx_scope *
-leave_scope (void)
-{
-  cxx_scope *scope = current_binding_level;
-
-  if (scope->kind == sk_namespace && class_binding_level)
-    current_binding_level = class_binding_level;
-
-  /* We cannot leave a scope, if there are none left.  */
-  if (NAMESPACE_LEVEL (global_namespace))
-    my_friendly_assert (!global_scope_p (scope), 20030527);
-  
-  if (ENABLE_SCOPE_CHECKING)
-    {
-      indent (--binding_depth);
-      cxx_scope_debug (scope, input_location.line, "leave");
-      if (is_class_level != (scope == class_binding_level))
-        {
-          indent (binding_depth);
-          verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
-        }
-      is_class_level = 0;
-    }
-
-  /* Move one nesting level up.  */
-  current_binding_level = scope->level_chain;
-
-  /* Namespace-scopes are left most probably temporarily, not completely;
-     they can be reopen later, e.g. in namespace-extension or any name
-     binding acttivity that requires us to resume a namespace.  For other
-     scopes, we just make the structure available for reuse.  */
-  if (scope->kind != sk_namespace)
-    {
-      scope->level_chain = free_binding_level;
-      if (scope->kind == sk_class)
-        scope->type_decls = NULL;
-      else
-        binding_table_free (scope->type_decls);
-      my_friendly_assert (!ENABLE_SCOPE_CHECKING
-                          || scope->binding_depth == binding_depth,
-                          20030529);
-      free_binding_level = scope;
-    }
-
-  /* Find the innermost enclosing class scope, and reset
-     CLASS_BINDING_LEVEL appropriately.  */
-  for (scope = current_binding_level;
-       scope && scope->kind != sk_class;
-       scope = scope->level_chain)
-    ;
-  class_binding_level = scope && scope->kind == sk_class ? scope : NULL;
-
-  return current_binding_level;
-}
-
-static void
-resume_binding_level (struct cp_binding_level* b)
-{
-  /* Resuming binding levels is meant only for namespaces,
-     and those cannot nest into classes.  */
-  my_friendly_assert(!class_binding_level, 386);
-  /* Also, resuming a non-directly nested namespace is a no-no.  */
-  my_friendly_assert(b->level_chain == current_binding_level, 386);
-  current_binding_level = b;
-  if (ENABLE_SCOPE_CHECKING)
-    {
-      b->binding_depth = binding_depth;
-      indent (binding_depth);
-      cxx_scope_debug (b, input_location.line, "resume");
-      is_class_level = 0;
-      binding_depth++;
-    }
-}
 \f
-/* Nonzero if we are currently in the global binding level.  */
-
-int
-global_bindings_p (void)
-{
-  return global_scope_p (current_binding_level);
-}
-
-/* Return the innermost binding level that is not for a class scope.  */
-
-static struct cp_binding_level *
-innermost_nonclass_level (void)
-{
-  struct cp_binding_level *b;
-
-  b = current_binding_level;
-  while (b->kind == sk_class)
-    b = b->level_chain;
-
-  return b;
-}
-
-/* Nonzero if we are currently in a toplevel binding level.  This
-   means either the global binding level or a namespace in a toplevel
-   binding level.  Since there are no non-toplevel namespace levels,
-   this really means any namespace or template parameter level.  We
-   also include a class whose context is toplevel.  */
-
-int
-toplevel_bindings_p (void)
-{
-  struct cp_binding_level *b = innermost_nonclass_level ();
-
-  return b->kind == sk_namespace || b->kind == sk_template_parms;
-}
-
-/* Nonzero if this is a namespace scope, or if we are defining a class
-   which is itself at namespace scope, or whose enclosing class is
-   such a class, etc.  */
-
-int
-namespace_bindings_p (void)
-{
-  struct cp_binding_level *b = innermost_nonclass_level ();
-
-  return b->kind == sk_namespace;
-}
-
-/* If KEEP is true, make a BLOCK node for the next binding level,
-   unconditionally.  Otherwise, use the normal logic to decide whether
-   or not to create a BLOCK.  */
-
-void
-keep_next_level (bool keep)
-{
-  keep_next_level_flag = keep;
-}
-
-/* Nonzero if the current level needs to have a BLOCK made.  */
-
-int
-kept_level_p (void)
-{
-  return (current_binding_level->blocks != NULL_TREE
-         || current_binding_level->keep
-          || current_binding_level->kind == sk_cleanup
-         || current_binding_level->names != NULL_TREE
-         || current_binding_level->type_decls != NULL);
-}
-
-/* Returns the kind of the innermost scope.  */
-
-scope_kind
-innermost_scope_kind (void)
-{
-  return current_binding_level->kind;
-}
-
-/* Returns nonzero if this scope was created to store template
-   parameters.  */
-
-int
-template_parm_scope_p (void)
-{
-  return innermost_scope_kind () == sk_template_parms;
-}
-
 /* Returns the kind of template specialization we are currently
    processing, given that it's declaration contained N_CLASS_SCOPES
    explicit scope qualifications.  */
@@ -693,28 +356,6 @@ current_tmpl_spec_kind (int n_class_scopes)
     return innermost_specialization_p ? tsk_expl_spec : tsk_template;
 }
 
-void
-set_class_shadows (tree shadows)
-{
-  class_binding_level->class_shadowed = shadows;
-}
-
-/* We're defining an object of type TYPE.  If it needs a cleanup, but
-   we're not allowed to add any more objects with cleanups to the current
-   scope, create a new binding level.  */
-
-void
-maybe_push_cleanup_level (tree type)
-{
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
-      && current_binding_level->more_cleanups_ok == 0)
-    {
-      begin_scope (sk_cleanup, NULL);
-      clear_last_expr ();
-      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
-    }
-}
-
 /* Exit the current scope.  */
 
 void
@@ -723,192 +364,6 @@ finish_scope (void)
   poplevel (0, 0, 0);
 }
 
-/* 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, cxx_scope* level)
-{
-   cxx_binding *binding = cxx_binding_make (decl, NULL);
-
-  /* Now, fill in the binding information.  */
-  binding->previous = IDENTIFIER_BINDING (id);
-  binding->scope = level;
-  INHERITED_VALUE_BINDING_P (binding) = 0;
-  LOCAL_BINDING_P (binding) = (level != class_binding_level);
-
-  /* And put it on the front of the list of bindings for ID.  */
-  IDENTIFIER_BINDING (id) = binding;
-}
-
-/* Add DECL to the list of things declared in B.  */
-
-static void
-add_decl_to_level (tree decl, 
-                   struct cp_binding_level* b)
-{
-  if (TREE_CODE (decl) == NAMESPACE_DECL 
-      && !DECL_NAMESPACE_ALIAS (decl))
-    {
-      TREE_CHAIN (decl) = b->namespaces;
-      b->namespaces = decl;
-    }
-  else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
-    {
-      TREE_CHAIN (decl) = b->vtables;
-      b->vtables = decl;
-    }
-  else       
-    {
-      /* We build up the list in reverse order, and reverse it later if
-         necessary.  */
-      TREE_CHAIN (decl) = b->names;
-      b->names = decl;
-      b->names_size++;
-
-      /* If appropriate, add decl to separate list of statics */
-      if (b->kind == sk_namespace)
-       if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
-           || (TREE_CODE (decl) == FUNCTION_DECL
-               && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
-         VARRAY_PUSH_TREE (b->static_decls, decl);
-    }
-}
-
-/* Bind DECL to ID in the current_binding_level, assumed to be a local
-   binding level.  If PUSH_USING is set in FLAGS, we know that DECL
-   doesn't really belong to this binding level, that it got here
-   through a using-declaration.  */
-
-void
-push_local_binding (tree id, tree decl, int flags)
-{
-  struct cp_binding_level *b;
-
-  /* Skip over any local classes.  This makes sense if we call
-     push_local_binding with a friend decl of a local class.  */
-  b = innermost_nonclass_level ();
-
-  if (lookup_name_current_level (id))
-    {
-      /* Supplement the existing binding.  */
-      if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
-       /* It didn't work.  Something else must be bound at this
-          level.  Do not add DECL to the list of things to pop
-          later.  */
-       return;
-    }
-  else
-    /* Create a new binding.  */
-    push_binding (id, decl, b);
-
-  if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
-    /* We must put the OVERLOAD into a TREE_LIST since the
-       TREE_CHAIN of an OVERLOAD is already used.  Similarly for
-       decls that got here through a using-declaration.  */
-    decl = build_tree_list (NULL_TREE, decl);
-
-  /* And put DECL on the list of things declared by the current
-     binding level.  */
-  add_decl_to_level (decl, b);
-}
-
-/* Bind DECL to ID in the class_binding_level.  Returns nonzero if the
-   binding was successful.  */
-
-int
-push_class_binding (tree id, tree decl)
-{
-  int result = 1;
-  cxx_binding *binding = IDENTIFIER_BINDING (id);
-  tree context;
-
-  timevar_push (TV_NAME_LOOKUP);
-  /* Note that we declared this value so that we can issue an error if
-     this is an invalid redeclaration of a name already used for some
-     other purpose.  */
-  note_name_declared_in_class (id, decl);
-
-  if (binding && binding->scope == class_binding_level)
-    /* Supplement the existing binding.  */
-    result = supplement_binding (IDENTIFIER_BINDING (id), decl);
-  else
-    /* Create a new binding.  */
-    push_binding (id, decl, class_binding_level);
-
-  /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the
-     class-level declaration.  Note that we do not use DECL here
-     because of the possibility of the `struct stat' hack; if DECL is
-     a class-name or enum-name we might prefer a field-name, or some
-     such.  */
-  IDENTIFIER_CLASS_VALUE (id) = IDENTIFIER_BINDING (id)->value;
-
-  /* If this is a binding from a base class, mark it as such.  */
-  binding = IDENTIFIER_BINDING (id);
-  if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)
-    {
-      if (TREE_CODE (decl) == OVERLOAD)
-       context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
-      else
-       {
-         my_friendly_assert (DECL_P (decl), 0);
-         context = context_for_name_lookup (decl);
-       }
-
-      if (is_properly_derived_from (current_class_type, context))
-       INHERITED_VALUE_BINDING_P (binding) = 1;
-      else
-       INHERITED_VALUE_BINDING_P (binding) = 0;
-    }
-  else if (binding->value == decl)
-    /* We only encounter a TREE_LIST when push_class_decls detects an
-       ambiguity.  Such an ambiguity can be overridden by a definition
-       in this class.  */
-    INHERITED_VALUE_BINDING_P (binding) = 1;
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result);
-}
-
-/* Remove the binding for DECL which should be the innermost binding
-   for ID.  */
-
-static void
-pop_binding (tree id, tree decl)
-{
-  cxx_binding *binding;
-
-  if (id == NULL_TREE)
-    /* It's easiest to write the loops that call this function without
-       checking whether or not the entities involved have names.  We
-       get here for such an entity.  */
-    return;
-
-  /* Get the innermost binding for ID.  */
-  binding = IDENTIFIER_BINDING (id);
-
-  /* The name should be bound.  */
-  my_friendly_assert (binding != NULL, 0);
-
-  /* The DECL will be either the ordinary binding or the type
-     binding for this identifier.  Remove that binding.  */
-  if (binding->value == decl)
-    binding->value = NULL_TREE;
-  else if (binding->type == decl)
-    binding->type = NULL_TREE;
-  else
-    abort ();
-
-  if (!binding->value && !binding->type)
-    {
-      /* We're completely done with the innermost binding for this
-        identifier.  Unhook it from the list of bindings.  */
-      IDENTIFIER_BINDING (id) = binding->previous;
-
-      /* Add it to the free list.  */
-      cxx_binding_free (binding);
-    }
-}
-
 /* When a label goes out of scope, check to see if that label was used
    in a valid manner, and issue any appropriate warnings or errors.  */
 
@@ -1319,109 +774,6 @@ set_block (tree block ATTRIBUTE_UNUSED )
      but it is not applicable in function-at-a-time mode.  */
 }
 
-/* Do a pushlevel for class declarations.  */
-
-void
-pushlevel_class (void)
-{
-  if (ENABLE_SCOPE_CHECKING)
-    is_class_level = 1;
-
-  class_binding_level = begin_scope (sk_class, current_class_type);
-}
-
-/* ...and a poplevel for class declarations.  */
-
-void
-poplevel_class (void)
-{
-  register struct cp_binding_level *level = class_binding_level;
-  tree shadowed;
-
-  timevar_push (TV_NAME_LOOKUP);
-  my_friendly_assert (level != 0, 354);
-
-  /* If we're leaving a toplevel class, don't bother to do the setting
-     of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
-     shouldn't even be used when current_class_type isn't set, and second,
-     if we don't touch it here, we're able to use the cache effect if the
-     next time we're entering a class scope, it is the same class.  */
-  if (current_class_depth != 1)
-    {
-      struct cp_binding_level* b;
-
-      /* Clear out our IDENTIFIER_CLASS_VALUEs.  */
-      for (shadowed = level->class_shadowed;
-          shadowed;
-          shadowed = TREE_CHAIN (shadowed))
-       IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
-
-      /* Find the next enclosing class, and recreate
-        IDENTIFIER_CLASS_VALUEs appropriate for that class.  */
-      b = level->level_chain;
-      while (b && b->kind != sk_class)
-       b = b->level_chain;
-
-      if (b)
-       for (shadowed = b->class_shadowed;
-            shadowed;
-            shadowed = TREE_CHAIN (shadowed))
-         {
-           cxx_binding *binding;
-            
-           binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
-           while (binding && binding->scope != b)
-             binding = binding->previous;
-
-           if (binding)
-             IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
-               = binding->value;
-         }
-    }
-  else
-    /* Remember to save what IDENTIFIER's were bound in this scope so we
-       can recover from cache misses.  */
-    {
-      previous_class_type = current_class_type;
-      previous_class_values = class_binding_level->class_shadowed;
-    }
-  for (shadowed = level->type_shadowed;
-       shadowed;
-       shadowed = TREE_CHAIN (shadowed))
-    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
-
-  /* Remove the bindings for all of the class-level declarations.  */
-  for (shadowed = level->class_shadowed;
-       shadowed;
-       shadowed = TREE_CHAIN (shadowed))
-    pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
-
-  /* Now, pop out of the binding level which we created up in the
-     `pushlevel_class' routine.  */
-  if (ENABLE_SCOPE_CHECKING)
-    is_class_level = 1;
-
-  leave_scope ();
-  timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* We are entering the scope of a class.  Clear IDENTIFIER_CLASS_VALUE
-   for any names in enclosing classes.  */
-
-void
-clear_identifier_class_values (void)
-{
-  tree t;
-
-  if (!class_binding_level)
-    return;
-
-  for (t = class_binding_level->class_shadowed;
-       t;
-       t = TREE_CHAIN (t))
-    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
-}
-
 /* Returns nonzero if T is a virtual function table.  */
 
 int
@@ -1441,14 +793,6 @@ vtype_decl_p (tree t, void *data ATTRIBUTE_UNUSED )
          && TYPE_POLYMORPHIC_P (TREE_TYPE (t)));
 }
 
-/* Return the declarations that are members of the namespace NS.  */
-
-tree
-cp_namespace_decls (tree ns)
-{
-  return NAMESPACE_LEVEL (ns)->names;
-}
-
 struct walk_globals_data {
   walk_globals_pred p;
   walk_globals_fn f;
@@ -1491,693 +835,100 @@ walk_vtables (walk_globals_pred p, walk_globals_fn f, void *data)
 /* Walk all the namespaces contained NAMESPACE, including NAMESPACE
    itself, calling F for each.  The DATA is passed to F as well.  */
 
-static int
-walk_namespaces_r (tree namespace, walk_namespaces_fn f, void* data)
-{
-  int result = 0;
-  tree current = NAMESPACE_LEVEL (namespace)->namespaces;     
-
-  result |= (*f) (namespace, data);
-
-  for (; current; current = TREE_CHAIN (current))
-    result |= walk_namespaces_r (current, f, data);
-
-  return result;
-}
-
-/* Walk all the namespaces, calling F for each.  The DATA is passed to
-   F as well.  */
-
-int
-walk_namespaces (walk_namespaces_fn f, void* data)
-{
-  return walk_namespaces_r (global_namespace, f, data);
-}
-
-/* Walk the global declarations in NAMESPACE.  Whenever one is found
-   for which P returns nonzero, call F with its address.  If any call
-   to F returns a nonzero value, return a nonzero value.  */
-
-static int
-walk_globals_r (tree namespace, void* data)
-{
-  struct walk_globals_data* wgd = (struct walk_globals_data *) data;
-  walk_globals_pred p = wgd->p;
-  walk_globals_fn f = wgd->f;
-  void *d = wgd->data;
-  tree *t;
-  int result = 0;
-
-  t = &NAMESPACE_LEVEL (namespace)->names;
-
-  while (*t)
-    {
-      tree glbl = *t;
-
-      if ((*p) (glbl, d))
-       result |= (*f) (t, d);
-
-      /* If F changed *T, then *T still points at the next item to
-        examine.  */
-      if (*t == glbl)
-       t = &TREE_CHAIN (*t);
-    }
-
-  return result;
-}
-
-/* Walk the global declarations.  Whenever one is found for which P
-   returns true, call F with its address.  If any call to F
-   returns true, return true.  */
-
-bool
-walk_globals (walk_globals_pred p, walk_globals_fn f, void *data)
-{
-  struct walk_globals_data wgd;
-  wgd.p = p;
-  wgd.f = f;
-  wgd.data = data;
-
-  return walk_namespaces (walk_globals_r, &wgd);
-}
-
-/* Call wrapup_globals_declarations for the globals in NAMESPACE.  If
-   DATA is non-NULL, this is the last time we will call
-   wrapup_global_declarations for this NAMESPACE.  */
-
-int
-wrapup_globals_for_namespace (tree namespace, void* data)
-{
-  struct cp_binding_level *level = NAMESPACE_LEVEL (namespace);
-  varray_type statics = level->static_decls;
-  tree *vec = &VARRAY_TREE (statics, 0);
-  int len = VARRAY_ACTIVE_SIZE (statics);
-  int last_time = (data != 0);
-
-  if (last_time)
-    {
-      check_global_declarations (vec, len);
-      return 0;
-    }
-
-  /* Write out any globals that need to be output.  */
-  return wrapup_global_declarations (vec, len);
-}
-
-\f
-/* For debugging.  */
-static int no_print_functions = 0;
-static int no_print_builtins = 0;
-
-/* Called from print_binding_level through binding_table_foreach to
-   print the content of binding ENTRY.  DATA is a pointer to line offset
-   marker.  */
-static void
-bt_print_entry (binding_entry entry, void *data)
-{
-  int *p = (int *) data;
-  int len;
-
-  if (entry->name == NULL)
-    len = 3;
-  else if (entry->name == TYPE_IDENTIFIER (entry->type))
-    len = 2;
-  else
-    len = 4;
-    len = 4;
-
-  *p += len;
-
-  if (*p > 5)
-    {
-      fprintf (stderr, "\n\t");
-      *p = len;
-    }
-  if (entry->name == NULL)
-    {
-      print_node_brief (stderr, "<unnamed-typedef", entry->type, 0);
-      fprintf (stderr, ">");
-    }
-  else if (entry->name == TYPE_IDENTIFIER (entry->type))
-    print_node_brief (stderr, "", entry->type, 0);
-  else
-    {
-      print_node_brief (stderr, "<typedef", entry->name, 0);
-      print_node_brief (stderr, "", entry->type, 0);
-      fprintf (stderr, ">");
-    }
-}
-
-void
-print_binding_level (struct cp_binding_level* lvl)
-{
-  tree t;
-  int i = 0, len;
-  fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
-  if (lvl->more_cleanups_ok)
-    fprintf (stderr, " more-cleanups-ok");
-  if (lvl->have_cleanups)
-    fprintf (stderr, " have-cleanups");
-  fprintf (stderr, "\n");
-  if (lvl->names)
-    {
-      fprintf (stderr, " names:\t");
-      /* We can probably fit 3 names to a line?  */
-      for (t = lvl->names; t; t = TREE_CHAIN (t))
-       {
-         if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
-           continue;
-         if (no_print_builtins
-             && (TREE_CODE (t) == TYPE_DECL)
-             && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))
-           continue;
-
-         /* Function decls tend to have longer names.  */
-         if (TREE_CODE (t) == FUNCTION_DECL)
-           len = 3;
-         else
-           len = 2;
-         i += len;
-         if (i > 6)
-           {
-             fprintf (stderr, "\n\t");
-             i = len;
-           }
-         print_node_brief (stderr, "", t, 0);
-         if (t == error_mark_node)
-           break;
-       }
-      if (i)
-        fprintf (stderr, "\n");
-    }
-  if (lvl->type_decls)
-    {
-      fprintf (stderr, " tags:\t");
-      i = 0;
-      binding_table_foreach (lvl->type_decls, bt_print_entry, &i);
-      if (i)
-       fprintf (stderr, "\n");
-    }
-  if (lvl->class_shadowed)
-    {
-      fprintf (stderr, " class-shadowed:");
-      for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
-       {
-         fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
-       }
-      fprintf (stderr, "\n");
-    }
-  if (lvl->type_shadowed)
-    {
-      fprintf (stderr, " type-shadowed:");
-      for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
-        {
-         fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
-        }
-      fprintf (stderr, "\n");
-    }
-}
-
-void
-print_other_binding_stack (struct cp_binding_level *stack)
-{
-  struct cp_binding_level *level;
-  for (level = stack; !global_scope_p (level); level = level->level_chain)
-    {
-      fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level);
-      print_binding_level (level);
-    }
-}
-
-void
-print_binding_stack (void)
-{
-  struct cp_binding_level *b;
-  fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF
-          "\nclass_binding_level=" HOST_PTR_PRINTF
-          "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n",
-          (void *) current_binding_level, (void *) class_binding_level,
-           (void *) NAMESPACE_LEVEL (global_namespace));
-  if (class_binding_level)
-    {
-      for (b = class_binding_level; b; b = b->level_chain)
-       if (b == current_binding_level)
-         break;
-      if (b)
-       b = class_binding_level;
-      else
-       b = current_binding_level;
-    }
-  else
-    b = current_binding_level;
-  print_other_binding_stack (b);
-  fprintf (stderr, "global:\n");
-  print_binding_level (NAMESPACE_LEVEL (global_namespace));
-}
-
-/* Namespace binding access routines: The namespace_bindings field of
-   the identifier is polymorphic, with three possible values:
-   NULL_TREE, a list of "cxx_binding"s.  */
-
-/* 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.  */
-
-void
-push_namespace (tree name)
-{
-  tree d = NULL_TREE;
-  int need_new = 1;
-  int implicit_use = 0;
-
-  timevar_push (TV_NAME_LOOKUP);
-  
-  /* We should not get here if the global_namespace is not yet constructed
-     nor if NAME designates the global namespace:  The global scope is
-     constructed elsewhere.  */
-  my_friendly_assert (global_namespace != NULL && name != global_scope_name,
-                      20030531);
-
-  if (!name)
-    {
-      /* The name of anonymous namespace is unique for the translation
-         unit.  */
-      if (!anonymous_namespace_name)
-        anonymous_namespace_name = get_file_function_name ('N');
-      name = anonymous_namespace_name;
-      d = IDENTIFIER_NAMESPACE_VALUE (name);
-      if (d)
-        /* Reopening anonymous namespace.  */
-        need_new = 0;
-      implicit_use = 1;
-    }
-  else
-    {
-      /* Check whether this is an extended namespace definition.  */
-      d = IDENTIFIER_NAMESPACE_VALUE (name);
-      if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
-        {
-          need_new = 0;
-          if (DECL_NAMESPACE_ALIAS (d))
-            {
-              error ("namespace alias `%D' not allowed here, assuming `%D'",
-                        d, DECL_NAMESPACE_ALIAS (d));
-              d = DECL_NAMESPACE_ALIAS (d);
-            }
-        }
-    }
-
-  if (need_new)
-    {
-      /* Make a new namespace, binding the name to it.  */
-      d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
-      DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
-      d = pushdecl (d);
-      begin_scope (sk_namespace, d);
-    }
-  else
-    resume_binding_level (NAMESPACE_LEVEL (d));
-
-  if (implicit_use)
-    do_using_directive (d);
-  /* Enter the name space.  */
-  current_namespace = d;
-
-  timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* Pop from the scope of the current namespace.  */
-
-void
-pop_namespace (void)
-{
-  my_friendly_assert (current_namespace != global_namespace, 20010801);
-  current_namespace = CP_DECL_CONTEXT (current_namespace);
-  /* The binding level is not popped, as it might be re-opened later.  */
-  leave_scope ();
-}
-
-/* Push into the scope of the namespace NS, even if it is deeply
-   nested within another namespace.  */
-
-void
-push_nested_namespace (tree ns)
-{
-  if (ns == global_namespace)
-    push_to_top_level ();
-  else
-    {
-      push_nested_namespace (CP_DECL_CONTEXT (ns));
-      push_namespace (DECL_NAME (ns));
-    }
-}
-
-/* Pop back from the scope of the namespace NS, which was previously
-   entered with push_nested_namespace.  */
-
-void
-pop_nested_namespace (tree ns)
-{
-  timevar_push (TV_NAME_LOOKUP);
-  while (ns != global_namespace)
-    {
-      pop_namespace ();
-      ns = CP_DECL_CONTEXT (ns);
-    }
-
-  pop_from_top_level ();
-  timevar_pop (TV_NAME_LOOKUP);
-}
-
-\f
-/* Allocate storage for saving a C++ binding.  */
-#define cxx_saved_binding_make() \
-  (ggc_alloc (sizeof (cxx_saved_binding)))
-
-struct cxx_saved_binding GTY(())
-{
-  /* Link that chains saved C++ bindings for a given name into a stack.  */
-  cxx_saved_binding *previous;
-  /* The name of the current binding.  */
-  tree identifier;
-  /* The binding we're saving.  */
-  cxx_binding *binding;
-  tree class_value;
-  tree real_type_value;
-};
-
-/* Subroutines for reverting temporarily to top-level for instantiation
-   of templates and such.  We actually need to clear out the class- and
-   local-value slots of all identifiers, so that only the global values
-   are at all visible.  Simply setting current_binding_level to the global
-   scope isn't enough, because more binding levels may be pushed.  */
-struct saved_scope *scope_chain;
-
-static cxx_saved_binding *
-store_bindings (tree names, cxx_saved_binding *old_bindings)
-{
-  tree t;
-  cxx_saved_binding *search_bindings = old_bindings;
-
-  timevar_push (TV_NAME_LOOKUP);
-  for (t = names; t; t = TREE_CHAIN (t))
-    {
-      tree id;
-      cxx_saved_binding *saved;
-      cxx_saved_binding *t1;
-
-      if (TREE_CODE (t) == TREE_LIST)
-       id = TREE_PURPOSE (t);
-      else
-       id = DECL_NAME (t);
-
-      if (!id
-         /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
-            we have no IDENTIFIER_BINDING if we have left the class
-            scope, but cached the class-level declarations.  */
-         || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
-       continue;
-
-      for (t1 = search_bindings; t1; t1 = t1->previous)
-       if (t1->identifier == id)
-         goto skip_it;
-
-      my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
-      saved = cxx_saved_binding_make ();
-      saved->previous = old_bindings;
-      saved->identifier = id;
-      saved->binding = IDENTIFIER_BINDING (id);
-      saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
-      saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
-      IDENTIFIER_BINDING (id) = NULL;
-      IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
-      old_bindings = saved;
-    skip_it:
-      ;
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
-}
-
-void
-maybe_push_to_top_level (int pseudo)
-{
-  struct saved_scope *s;
-  struct cp_binding_level *b;
-  cxx_saved_binding *old_bindings;
-  int need_pop;
-
-  timevar_push (TV_NAME_LOOKUP);
-  s = ggc_alloc_cleared (sizeof (struct saved_scope));
-
-  b = scope_chain ? current_binding_level : 0;
-
-  /* If we're in the middle of some function, save our state.  */
-  if (cfun)
-    {
-      need_pop = 1;
-      push_function_context_to (NULL_TREE);
-    }
-  else
-    need_pop = 0;
-
-  old_bindings = NULL;
-  if (scope_chain && previous_class_type)
-    old_bindings = store_bindings (previous_class_values, old_bindings);
-
-  /* Have to include the global scope, because class-scope decls
-     aren't listed anywhere useful.  */
-  for (; b; b = b->level_chain)
-    {
-      tree t;
-
-      /* Template IDs are inserted into the global level. If they were
-        inserted into namespace level, finish_file wouldn't find them
-        when doing pending instantiations. Therefore, don't stop at
-        namespace level, but continue until :: .  */
-      if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms))
-       break;
+static int
+walk_namespaces_r (tree namespace, walk_namespaces_fn f, void* data)
+{
+  int result = 0;
+  tree current = NAMESPACE_LEVEL (namespace)->namespaces;     
 
-      old_bindings = store_bindings (b->names, old_bindings);
-      /* We also need to check class_shadowed to save class-level type
-        bindings, since pushclass doesn't fill in b->names.  */
-      if (b->kind == sk_class)
-       old_bindings = store_bindings (b->class_shadowed, old_bindings);
+  result |= (*f) (namespace, data);
 
-      /* Unwind type-value slots back to top level.  */
-      for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
-       SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
-    }
-  s->prev = scope_chain;
-  s->old_bindings = old_bindings;
-  s->bindings = b;
-  s->need_pop_function_context = need_pop;
-  s->function_decl = current_function_decl;
-  s->last_parms = last_function_parms;
+  for (; current; current = TREE_CHAIN (current))
+    result |= walk_namespaces_r (current, f, data);
 
-  scope_chain = s;
-  current_function_decl = NULL_TREE;
-  VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
-  current_lang_name = lang_name_cplusplus;
-  current_namespace = global_namespace;
-  timevar_pop (TV_NAME_LOOKUP);
+  return result;
 }
 
-void
-push_to_top_level (void)
+/* Walk all the namespaces, calling F for each.  The DATA is passed to
+   F as well.  */
+
+int
+walk_namespaces (walk_namespaces_fn f, void* data)
 {
-  maybe_push_to_top_level (0);
+  return walk_namespaces_r (global_namespace, f, data);
 }
 
-void
-pop_from_top_level (void)
-{
-  struct saved_scope *s = scope_chain;
-  cxx_saved_binding *saved;
+/* Walk the global declarations in NAMESPACE.  Whenever one is found
+   for which P returns nonzero, call F with its address.  If any call
+   to F returns a nonzero value, return a nonzero value.  */
 
-  timevar_push (TV_NAME_LOOKUP); 
-  /* Clear out class-level bindings cache.  */
-  if (previous_class_type)
-    invalidate_class_lookup_cache ();
+static int
+walk_globals_r (tree namespace, void* data)
+{
+  struct walk_globals_data* wgd = (struct walk_globals_data *) data;
+  walk_globals_pred p = wgd->p;
+  walk_globals_fn f = wgd->f;
+  void *d = wgd->data;
+  tree *t;
+  int result = 0;
 
-  current_lang_base = 0;
+  t = &NAMESPACE_LEVEL (namespace)->names;
 
-  scope_chain = s->prev;
-  for (saved = s->old_bindings; saved; saved = saved->previous)
+  while (*t)
     {
-      tree id = saved->identifier;
-
-      IDENTIFIER_BINDING (id) = saved->binding;
-      IDENTIFIER_CLASS_VALUE (id) = saved->class_value;
-      SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
-    }
-
-  /* If we were in the middle of compiling a function, restore our
-     state.  */
-  if (s->need_pop_function_context)
-    pop_function_context_from (NULL_TREE);
-  current_function_decl = s->function_decl;
-  last_function_parms = s->last_parms;
-  timevar_pop (TV_NAME_LOOKUP);
-}
-\f
-/* Push a definition of struct, union or enum tag named ID.  into
-   binding_level B.  DECL is a TYPE_DECL for the type.  We assume that
-   the tag ID is not already defined.  */
+      tree glbl = *t;
 
-static void
-set_identifier_type_value_with_scope (tree id, 
-                                      tree decl,
-                                      struct cp_binding_level* b)
-{
-  tree type;
+      if ((*p) (glbl, d))
+       result |= (*f) (t, d);
 
-  if (b->kind != sk_namespace)
-    {
-      /* Shadow the marker, not the real thing, so that the marker
-        gets restored later.  */
-      tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
-      b->type_shadowed
-       = tree_cons (id, old_type_value, b->type_shadowed);
-      type = decl ? TREE_TYPE (decl) : NULL_TREE;
-    }
-  else
-    {
-      cxx_binding *binding =
-       binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
-      if (decl)
-       {
-         if (binding->value)
-           supplement_binding (binding, decl);
-         else
-           binding->value = decl;
-       }
-      else
-       abort ();
-      /* Store marker instead of real type.  */
-      type = global_type_node;
+      /* If F changed *T, then *T still points at the next item to
+        examine.  */
+      if (*t == glbl)
+       t = &TREE_CHAIN (*t);
     }
-  SET_IDENTIFIER_TYPE_VALUE (id, type);
-}
 
-/* As set_identifier_type_value_with_scope, but using current_binding_level.  */
-
-void
-set_identifier_type_value (tree id, tree decl)
-{
-  set_identifier_type_value_with_scope (id, decl, current_binding_level);
+  return result;
 }
 
-/* Return the type associated with id.  */
+/* Walk the global declarations.  Whenever one is found for which P
+   returns true, call F with its address.  If any call to F
+   returns true, return true.  */
 
-tree
-identifier_type_value (tree id)
+bool
+walk_globals (walk_globals_pred p, walk_globals_fn f, void *data)
 {
-  timevar_push (TV_NAME_LOOKUP);
-  /* There is no type with that name, anywhere.  */
-  if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-  /* This is not the type marker, but the real thing.  */
-  if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
-  /* Have to search for it. It must be on the global level, now.
-     Ask lookup_name not to return non-types.  */
-  id = lookup_name_real (id, 2, 1, 0, LOOKUP_COMPLAIN);
-  if (id)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
-/* Pop off extraneous binding levels left over due to syntax errors.
-
-   We don't pop past namespaces, as they might be valid.  */
+  struct walk_globals_data wgd;
+  wgd.p = p;
+  wgd.f = f;
+  wgd.data = data;
 
-void
-pop_everything (void)
-{
-  if (ENABLE_SCOPE_CHECKING)
-    verbatim ("XXX entering pop_everything ()\n");
-  while (!toplevel_bindings_p ())
-    {
-      if (current_binding_level->kind == sk_class)
-       pop_nested_class ();
-      else
-       poplevel (0, 0, 0);
-    }
-  if (ENABLE_SCOPE_CHECKING)
-    verbatim ("XXX leaving pop_everything ()\n");
+  return walk_namespaces (walk_globals_r, &wgd);
 }
 
-/* The type TYPE is being declared.  If it is a class template, or a
-   specialization of a class template, do any processing required and
-   perform error-checking.  If IS_FRIEND is nonzero, this TYPE is
-   being declared a friend.  B is the binding level at which this TYPE
-   should be bound.
-
-   Returns the TYPE_DECL for TYPE, which may have been altered by this
-   processing.  */
+/* Call wrapup_globals_declarations for the globals in NAMESPACE.  If
+   DATA is non-NULL, this is the last time we will call
+   wrapup_global_declarations for this NAMESPACE.  */
 
-static tree
-maybe_process_template_type_declaration (tree type, 
-                                         int globalize, 
-                                         struct cp_binding_level* b)
+int
+wrapup_globals_for_namespace (tree namespace, void* data)
 {
-  tree decl = TYPE_NAME (type);
-
-  if (processing_template_parmlist)
-    /* You can't declare a new template type in a template parameter
-       list.  But, you can declare a non-template type:
-
-         template <class A*> struct S;
+  struct cp_binding_level *level = NAMESPACE_LEVEL (namespace);
+  varray_type statics = level->static_decls;
+  tree *vec = &VARRAY_TREE (statics, 0);
+  int len = VARRAY_ACTIVE_SIZE (statics);
+  int last_time = (data != 0);
 
-       is a forward-declaration of `A'.  */
-    ;
-  else
+  if (last_time)
     {
-      maybe_check_template_type (type);
-
-      my_friendly_assert (IS_AGGR_TYPE (type)
-                         || TREE_CODE (type) == ENUMERAL_TYPE, 0);
-
-
-      if (processing_template_decl)
-       {
-         /* This may change after the call to
-            push_template_decl_real, but we want the original value.  */
-         tree name = DECL_NAME (decl);
-
-         decl = push_template_decl_real (decl, globalize);
-         /* If the current binding level is the binding level for the
-            template parameters (see the comment in
-            begin_template_parm_list) and the enclosing level is a class
-            scope, and we're not looking at a friend, push the
-            declaration of the member class into the class scope.  In the
-            friend case, push_template_decl will already have put the
-            friend into global scope, if appropriate.  */
-         if (TREE_CODE (type) != ENUMERAL_TYPE
-             && !globalize && b->kind == sk_template_parms
-             && b->level_chain->kind == sk_class)
-           {
-             finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
-             /* Put this UDT in the table of UDTs for the class, since
-                that won't happen below because B is not the class
-                binding level, but is instead the pseudo-global level.  */
-              if (b->level_chain->type_decls == NULL)
-                b->level_chain->type_decls =
-                  binding_table_new (SCOPE_DEFAULT_HT_SIZE);
-              binding_table_insert (b->level_chain->type_decls, name, type);
-             if (!COMPLETE_TYPE_P (current_class_type))
-               {
-                 maybe_add_class_template_decl_list (current_class_type,
-                                                     type, /*friend_p=*/0);
-                 CLASSTYPE_NESTED_UTDS (current_class_type) =
-                    b->level_chain->type_decls;
-               }
-           }
-       }
+      check_global_declarations (vec, len);
+      return 0;
     }
 
-  return decl;
+  /* Write out any globals that need to be output.  */
+  return wrapup_global_declarations (vec, len);
 }
 
+\f
 /* In C++, you don't have to write `struct S' to refer to `S'; you
    can just use `S'.  We accomplish this by creating a TYPE_DECL as
    if the user had written `typedef struct S S'.  Create and return
@@ -2237,130 +988,6 @@ push_local_name (tree decl)
   timevar_pop (TV_NAME_LOOKUP);
 }
 
-/* Push a tag name NAME for struct/class/union/enum type TYPE.
-   Normally put it into the inner-most non-sk_cleanup scope,
-   but if GLOBALIZE is true, put it in the inner-most non-class scope.
-   The latter is needed for implicit declarations.  */
-
-void
-pushtag (tree name, tree type, int globalize)
-{
-  register struct cp_binding_level *b;
-
-  timevar_push (TV_NAME_LOOKUP);
-  b = current_binding_level;
-  while (b->kind == sk_cleanup
-        || (b->kind == sk_class
-            && (globalize
-                /* We may be defining a new type in the initializer
-                   of a static member variable. We allow this when
-                   not pedantic, and it is particularly useful for
-                   type punning via an anonymous union.  */
-                || COMPLETE_TYPE_P (b->this_entity))))
-    b = b->level_chain;
-
-  if (b->type_decls == NULL)
-    b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
-  binding_table_insert (b->type_decls, name, type);
-
-  if (name)
-    {
-      /* Do C++ gratuitous typedefing.  */
-      if (IDENTIFIER_TYPE_VALUE (name) != type)
-        {
-          register tree d = NULL_TREE;
-         int in_class = 0;
-         tree context = TYPE_CONTEXT (type);
-
-         if (! context)
-           {
-             tree cs = current_scope ();
-
-             if (! globalize)
-               context = cs;
-             else if (cs != NULL_TREE && TYPE_P (cs))
-               /* When declaring a friend class of a local class, we want
-                  to inject the newly named class into the scope
-                  containing the local class, not the namespace scope.  */
-               context = decl_function_context (get_type_decl (cs));
-           }
-         if (!context)
-           context = current_namespace;
-
-         if (b->kind == sk_class
-             || (b->kind == sk_template_parms 
-                 && b->level_chain->kind == sk_class))
-           in_class = 1;
-
-         if (current_lang_name == lang_name_java)
-           TYPE_FOR_JAVA (type) = 1;
-
-         d = create_implicit_typedef (name, type);
-         DECL_CONTEXT (d) = FROB_CONTEXT (context);
-         if (! in_class)
-           set_identifier_type_value_with_scope (name, d, b);
-
-         d = maybe_process_template_type_declaration (type,
-                                                      globalize, b);
-
-         if (b->kind == sk_class)
-           {
-             if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
-               /* Put this TYPE_DECL on the TYPE_FIELDS list for the
-                  class.  But if it's a member template class, we
-                  want the TEMPLATE_DECL, not the TYPE_DECL, so this
-                  is done later.  */
-               finish_member_declaration (d);
-             else
-               pushdecl_class_level (d);
-           }
-         else
-           d = pushdecl_with_scope (d, b);
-
-         /* FIXME what if it gets a name from typedef?  */
-         if (ANON_AGGRNAME_P (name))
-           DECL_IGNORED_P (d) = 1;
-
-         TYPE_CONTEXT (type) = DECL_CONTEXT (d);
-
-         /* If this is a local class, keep track of it.  We need this
-            information for name-mangling, and so that it is possible to find
-            all function definitions in a translation unit in a convenient
-            way.  (It's otherwise tricky to find a member function definition
-            it's only pointed to from within a local class.)  */
-         if (TYPE_CONTEXT (type)
-             && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
-             && !processing_template_decl)
-           VARRAY_PUSH_TREE (local_classes, type);
-        }
-      if (b->kind == sk_class
-         && !COMPLETE_TYPE_P (current_class_type))
-       {
-         maybe_add_class_template_decl_list (current_class_type,
-                                             type, /*friend_p=*/0);
-         CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
-       }
-    }
-
-  if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
-    /* Use the canonical TYPE_DECL for this node.  */
-    TYPE_STUB_DECL (type) = TYPE_NAME (type);
-  else
-    {
-      /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
-        will be the tagged type we just added to the current
-        binding level.  This fake NULL-named TYPE_DECL node helps
-        dwarfout.c to know when it needs to output a
-        representation of a tagged type, and it also gives us a
-        convenient place to record the "scope start" address for
-        the tagged type.  */
-
-      tree d = build_decl (TYPE_DECL, NULL_TREE, type);
-      TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
-    }
-  timevar_pop (TV_NAME_LOOKUP);
-}
-
 /* Counter used to create anonymous type names.  */
 
 static GTY(()) int anon_cnt;
@@ -3776,81 +2403,6 @@ pushdecl (tree x)
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
 
-/* Same as pushdecl, but define X in binding-level LEVEL.  We rely on the
-   caller to set DECL_CONTEXT properly.  */
-
-static tree
-pushdecl_with_scope (tree x, struct cp_binding_level* level)
-{
-  register struct cp_binding_level *b;
-  tree function_decl = current_function_decl;
-
-  timevar_push (TV_NAME_LOOKUP);
-  current_function_decl = NULL_TREE;
-  if (level->kind == sk_class)
-    {
-      b = class_binding_level;
-      class_binding_level = level;
-      pushdecl_class_level (x);
-      class_binding_level = b;
-    }
-  else
-    {
-      b = current_binding_level;
-      current_binding_level = level;
-      x = pushdecl (x);
-      current_binding_level = b;
-    }
-  current_function_decl = function_decl;
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
-}
-
-/* Like pushdecl, only it places X in the current namespace,
-   if appropriate.  */
-
-tree
-pushdecl_namespace_level (tree x)
-{
-  register struct cp_binding_level *b = current_binding_level;
-  register tree t;
-
-  timevar_push (TV_NAME_LOOKUP);
-  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
-
-  /* Now, the type_shadowed stack may screw us.  Munge it so it does
-     what we want.  */
-  if (TREE_CODE (x) == TYPE_DECL)
-    {
-      tree name = DECL_NAME (x);
-      tree newval;
-      tree *ptr = (tree *)0;
-      for (; !global_scope_p (b); b = b->level_chain)
-        {
-          tree shadowed = b->type_shadowed;
-          for (; shadowed; shadowed = TREE_CHAIN (shadowed))
-            if (TREE_PURPOSE (shadowed) == name)
-              {
-               ptr = &TREE_VALUE (shadowed);
-               /* Can't break out of the loop here because sometimes
-                  a binding level will have duplicate bindings for
-                  PT names.  It's gross, but I haven't time to fix it.  */
-              }
-        }
-      newval = TREE_TYPE (x);
-      if (ptr == (tree *)0)
-        {
-          /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
-             up here if this is changed to an assertion.  --KR  */
-         SET_IDENTIFIER_TYPE_VALUE (name, x);
-       }
-      else
-        {
-         *ptr = newval;
-        }
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
-}
-
 /* Like pushdecl, only it places X in the global scope if appropriate.
    Calls cp_finish_decl to register the variable, initializing it with
    *INIT, if INIT is non-NULL.  */
@@ -3885,48 +2437,6 @@ pushdecl_top_level_and_finish (tree x, tree init)
   return pushdecl_top_level_1 (x, &init);
 }
 
-/* Make the declaration of X appear in CLASS scope.  */
-
-bool
-pushdecl_class_level (tree x)
-{
-  tree name;
-  bool is_valid = true;
-
-  timevar_push (TV_NAME_LOOKUP);
-  /* Get the name of X.  */
-  if (TREE_CODE (x) == OVERLOAD)
-    name = DECL_NAME (get_first_fn (x));
-  else
-    name = DECL_NAME (x);
-
-  if (name)
-    {
-      is_valid = push_class_level_binding (name, x);
-      if (TREE_CODE (x) == TYPE_DECL)
-       set_identifier_type_value (name, x);
-    }
-  else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
-    {
-      /* If X is an anonymous aggregate, all of its members are
-        treated as if they were members of the class containing the
-        aggregate, for naming purposes.  */
-      tree f;
-
-      for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
-       {
-         location_t save_location = input_location;
-         input_location = DECL_SOURCE_LOCATION (f);
-         if (!pushdecl_class_level (f))
-           is_valid = false;
-         input_location = save_location;
-       }
-    }
-  timevar_pop (TV_NAME_LOOKUP);
-
-  return is_valid;
-}
-
 /* Enter DECL into the symbol table, if that's appropriate.  Returns
    DECL, or a modified version thereof.  */
 
@@ -3956,97 +2466,6 @@ maybe_push_decl (tree decl)
     return pushdecl (decl);
 }
 
-/* Make the declaration(s) of X appear in CLASS scope under the name
-   NAME.  Returns true if the binding is valid.  */
-
-bool
-push_class_level_binding (tree name, tree x)
-{
-  cxx_binding *binding;
-
-  timevar_push (TV_NAME_LOOKUP);
-  /* The class_binding_level will be NULL if x is a template
-     parameter name in a member template.  */
-  if (!class_binding_level)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-
-  /* Make sure that this new member does not have the same name
-     as a template parameter.  */
-  if (TYPE_BEING_DEFINED (current_class_type))
-    check_template_shadow (x);
-
-  /* If this declaration shadows a declaration from an enclosing
-     class, then we will need to restore IDENTIFIER_CLASS_VALUE when
-     we leave this class.  Record the shadowed declaration here.  */
-  binding = IDENTIFIER_BINDING (name);
-  if (binding && binding->value)
-    {
-      tree bval = binding->value;
-      tree old_decl = NULL_TREE;
-
-      if (INHERITED_VALUE_BINDING_P (binding))
-       {
-         /* If the old binding was from a base class, and was for a
-            tag name, slide it over to make room for the new binding.
-            The old binding is still visible if explicitly qualified
-            with a class-key.  */
-         if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
-             && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
-           {
-             old_decl = binding->type;
-             binding->type = bval;
-             binding->value = NULL_TREE;
-             INHERITED_VALUE_BINDING_P (binding) = 0;
-           }
-         else
-           old_decl = bval;
-       }
-      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
-       old_decl = bval;
-      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
-       old_decl = bval;
-      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-      
-      if (old_decl)
-       {
-         tree shadow;
-         
-         /* Find the previous binding of name on the class-shadowed
-             list, and update it.  */
-         for (shadow = class_binding_level->class_shadowed;
-              shadow;
-              shadow = TREE_CHAIN (shadow))
-           if (TREE_PURPOSE (shadow) == name
-               && TREE_TYPE (shadow) == old_decl)
-             {
-               binding->value = x;
-               INHERITED_VALUE_BINDING_P (binding) = 0;
-               TREE_TYPE (shadow) = x;
-               IDENTIFIER_CLASS_VALUE (name) = x;
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-             }
-       }
-    }
-
-  /* If we didn't replace an existing binding, put the binding on the
-     stack of bindings for the identifier, and update the shadowed list.  */
-  if (push_class_binding (name, x))
-    {
-      class_binding_level->class_shadowed
-       = tree_cons (name, NULL,
-                    class_binding_level->class_shadowed);
-      /* Record the value we are binding NAME to so that we can know
-        what to pop later.  */
-      TREE_TYPE (class_binding_level->class_shadowed) = x;
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-    }
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
-}
-
 /* Insert another USING_DECL into the current binding level, returning
    this declaration. If this is a redeclaration, do nothing, and
    return NULL_TREE if this not in namespace scope (in namespace
@@ -4063,41 +2482,14 @@ push_using_decl (tree scope, tree name)
   for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
     if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
       break;
-  if (decl)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                            namespace_bindings_p () ? decl : NULL_TREE);
-  decl = build_lang_decl (USING_DECL, name, void_type_node);
-  DECL_INITIAL (decl) = scope;
-  TREE_CHAIN (decl) = current_binding_level->usings;
-  current_binding_level->usings = decl;
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
-}
-
-/* Add namespace to using_directives. Return NULL_TREE if nothing was
-   changed (i.e. there was already a directive), or the fresh
-   TREE_LIST otherwise.  */
-
-tree
-push_using_directive (tree used)
-{
-  tree ud = current_binding_level->using_directives;
-  tree iter, ancestor;
-
-  timevar_push (TV_NAME_LOOKUP);
-  /* Check if we already have this.  */
-  if (purpose_member (used, ud) != NULL_TREE)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-
-  ancestor = namespace_ancestor (current_decl_namespace (), used);
-  ud = current_binding_level->using_directives;
-  ud = tree_cons (used, ancestor, ud);
-  current_binding_level->using_directives = ud;
-
-  /* Recursively add all namespaces used.  */
-  for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
-    push_using_directive (TREE_PURPOSE (iter));
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud);
+  if (decl)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+                            namespace_bindings_p () ? decl : NULL_TREE);
+  decl = build_lang_decl (USING_DECL, name, void_type_node);
+  DECL_INITIAL (decl) = scope;
+  TREE_CHAIN (decl) = current_binding_level->usings;
+  current_binding_level->usings = decl;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
 }
 
 /* DECL is a FUNCTION_DECL for a non-member function, which may have
@@ -4781,298 +3173,6 @@ finish_case_label (tree low_value, tree high_value)
   return r;
 }
 \f
-/* Return the list of declarations of the current level.
-   Note that this list is in reverse order unless/until
-   you nreverse it; and when you do nreverse it, you must
-   store the result back using `storedecls' or you will lose.  */
-
-tree
-getdecls (void)
-{
-  return current_binding_level->names;
-}
-
-/* Store the list of declarations of the current level.
-   This is done for the parameter declarations of a function being defined,
-   after they are modified in the light of any missing parameters.  */
-
-static void
-storedecls (tree decls)
-{
-  current_binding_level->names = decls;
-}
-
-/* Set the current binding TABLE for type declarations..  This is a
-   temporary workaround of the fact that the data structure classtypes
-   does not currently carry its allocated cxx_scope structure.  */
-void
-cxx_remember_type_decls (binding_table table)
-{
-  current_binding_level->type_decls = table;
-}
-\f
-/* Return the type that should be used when TYPE's name is preceded
-   by a tag such as 'struct' or 'union', or null if the name cannot
-   be used in this way.
-
-   For example, when processing the third line of:
-
-       struct A;
-       typedef struct A A;
-       struct A;
-
-   lookup of A will find the typedef.  Given A's typedef, this function
-   will return the type associated with "struct A".  For the tag to be
-   anything other than TYPE, TYPE must be a typedef whose original type
-   has the same name and context as TYPE itself.
-
-   It is not valid for a typedef of an anonymous type to be used with
-   an explicit tag:
-
-       typedef struct { ... } B;
-       struct B;
-
-   Return null for this case.  */
-
-static tree
-follow_tag_typedef (tree type)
-{
-  tree original;
-
-  original = original_type (type);
-  if (! TYPE_NAME (original))
-    return NULL_TREE;
-  if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type)
-      && (CP_DECL_CONTEXT (TYPE_NAME (original))
-         == CP_DECL_CONTEXT (TYPE_NAME (type)))
-      && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original)))
-    return original;
-  else
-    return NULL_TREE;
-}
-
-/* Given NAME, an IDENTIFIER_NODE,
-   return the structure (or union or enum) definition for that name.
-   Searches binding levels from its SCOPE up to the global level.
-   If THISLEVEL_ONLY is nonzero, searches only the specified context
-   (but skips any sk_cleanup contexts to find one that is
-   meaningful for tags).
-   FORM says which kind of type the caller wants;
-   it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
-   If the wrong kind of type is found, and it's not a template, an error is
-   reported.  */
-
-static tree
-lookup_tag (enum tree_code form, tree name,
-            struct cp_binding_level* binding_level, int thislevel_only)
-{
-  register struct cp_binding_level *level;
-  /* Nonzero if, we should look past a template parameter level, even
-     if THISLEVEL_ONLY.  */
-  int allow_template_parms_p = 1;
-  bool type_is_anonymous = ANON_AGGRNAME_P (name);
-
-  timevar_push (TV_NAME_LOOKUP);
-  for (level = binding_level; level; level = level->level_chain)
-    {
-      register tree tail;
-      if (type_is_anonymous && level->type_decls != NULL)
-        {
-          tree type = binding_table_find_anon_type (level->type_decls, name);
-          /* There is no need for error checking here, because
-           anon names are unique throughout the compilation.  */
-          if (type != NULL)
-            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
-        }
-      else if (level->kind == sk_namespace)
-       /* Do namespace lookup.  */
-       for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
-         {
-            cxx_binding *binding =
-              cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
-           tree old;
-
-           /* If we just skipped past a template parameter level,
-              even though THISLEVEL_ONLY, and we find a template
-              class declaration, then we use the _TYPE node for the
-              template.  See the example below.  */
-           if (thislevel_only && !allow_template_parms_p
-               && binding && binding->value
-               && DECL_CLASS_TEMPLATE_P (binding->value))
-             old = binding->value;
-           else if (binding)
-             old = select_decl (binding, LOOKUP_PREFER_TYPES);
-            else
-              old = NULL_TREE;
-
-           if (old)
-             {
-               /* We've found something at this binding level.  If it is
-                  a typedef, extract the tag it refers to.  Lookup fails
-                  if the typedef doesn't refer to a taggable type.  */
-               old = TREE_TYPE (old);
-               old = follow_tag_typedef (old);
-               if (!old)
-                 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-               if (TREE_CODE (old) != form
-                   && (form == ENUMERAL_TYPE
-                       || TREE_CODE (old) == ENUMERAL_TYPE))
-                 {
-                   error ("`%#D' redeclared as %C", old, form);
-                   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-                 }
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
-             }
-           if (thislevel_only || tail == global_namespace)
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-         }
-      else if (level->type_decls != NULL)
-        {
-          binding_entry entry = binding_table_find (level->type_decls, name);
-          if (entry != NULL)
-            {
-              enum tree_code code = TREE_CODE (entry->type);
-               
-              if (code != form
-                  && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
-                {
-                  /* Definition isn't the kind we were looking for.  */
-                  error ("`%#D' redeclared as %C", entry->type, form);
-                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-                }
-              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
-            }
-         }
-      if (thislevel_only && level->kind != sk_cleanup)
-       {
-         if (level->kind == sk_template_parms && allow_template_parms_p)
-           {
-             /* We must deal with cases like this:
-
-                  template <class T> struct S;
-                  template <class T> struct S {};
-
-                When looking up `S', for the second declaration, we
-                would like to find the first declaration.  But, we
-                are in the pseudo-global level created for the
-                template parameters, rather than the (surrounding)
-                namespace level.  Thus, we keep going one more level,
-                even though THISLEVEL_ONLY is nonzero.  */
-             allow_template_parms_p = 0;
-             continue;
-           }
-         else
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-       }
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
-/* Given a type, find the tag that was defined for it and return the tag name.
-   Otherwise return 0.  However, the value can never be 0
-   in the cases in which this is used.
-
-   C++: If NAME is nonzero, this is the new name to install.  This is
-   done when replacing anonymous tags with real tag names.  */
-
-static tree
-lookup_tag_reverse (tree type, tree name)
-{
-  register struct cp_binding_level *level;
-
-  timevar_push (TV_NAME_LOOKUP);
-  for (level = current_binding_level; level; level = level->level_chain)
-    {
-      binding_entry entry = level->type_decls == NULL
-        ? NULL
-        : binding_table_reverse_maybe_remap (level->type_decls, type, name);
-      if (entry)
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name);
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-\f
-/* Look up NAME in the NAMESPACE.  */
-
-tree
-lookup_namespace_name (tree namespace, tree name)
-{
-  tree val;
-  tree template_id = NULL_TREE;
-  cxx_binding binding;
-
-  timevar_push (TV_NAME_LOOKUP);
-  my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
-
-  if (TREE_CODE (name) == NAMESPACE_DECL)
-    /* This happens for A::B<int> when B is a namespace.  */
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
-  else if (TREE_CODE (name) == TEMPLATE_DECL)
-    {
-      /* This happens for A::B where B is a template, and there are no
-        template arguments.  */
-      error ("invalid use of `%D'", name);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-    }
-
-  namespace = ORIGINAL_NAMESPACE (namespace);
-
-  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-    {
-      template_id = name;
-      name = TREE_OPERAND (name, 0);
-      if (TREE_CODE (name) == OVERLOAD)
-       name = DECL_NAME (OVL_CURRENT (name));
-      else if (DECL_P (name))
-       name = DECL_NAME (name);
-    }
-
-  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
-
-  cxx_binding_clear (&binding);
-  if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-
-  if (binding.value)
-    {
-      val = binding.value;
-
-      if (template_id)
-       {
-         if (DECL_CLASS_TEMPLATE_P (val))
-           val = lookup_template_class (val,
-                                        TREE_OPERAND (template_id, 1),
-                                        /*in_decl=*/NULL_TREE,
-                                        /*context=*/NULL_TREE,
-                                        /*entering_scope=*/0,
-                                        tf_error | tf_warning);
-         else if (DECL_FUNCTION_TEMPLATE_P (val)
-                  || TREE_CODE (val) == OVERLOAD)
-           val = lookup_template_function (val,
-                                           TREE_OPERAND (template_id, 1));
-         else
-           {
-             error ("`%D::%D' is not a template",
-                       namespace, name);
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-           }
-       }
-
-      /* If we have a single function from a using decl, pull it out.  */
-      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
-       val = OVL_FUNCTION (val);
-
-      /* Ignore built-in functions that haven't been prototyped yet.  */
-      if (!val || !DECL_P(val)
-          || !DECL_LANG_SPECIFIC(val)
-          || !DECL_ANTICIPATED (val))
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-    }
-
-  error ("`%D' undeclared in namespace `%D'", name, namespace);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-}
-
 /* Hash a TYPENAME_TYPE.  K is really of type `tree'.  */
 
 static hashval_t
@@ -5336,172 +3436,6 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
   return t;
 }
 
-/* Select the right _DECL from multiple choices.  */
-
-static tree
-select_decl (cxx_binding *binding, int flags)
-{
-  tree val;
-  val = binding->value;
-
-  timevar_push (TV_NAME_LOOKUP);
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    {
-      /* We are not interested in types.  */
-      if (val && TREE_CODE (val) == NAMESPACE_DECL)
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-    }
-
-  /* If looking for a type, or if there is no non-type binding, select
-     the value binding.  */
-  if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
-    val = binding->type;
-  /* Don't return non-types if we really prefer types.  */
-  else if (val && LOOKUP_TYPES_ONLY (flags)  && TREE_CODE (val) != TYPE_DECL
-          && (TREE_CODE (val) != TEMPLATE_DECL
-              || !DECL_CLASS_TEMPLATE_P (val)))
-    val = NULL_TREE;
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
-/* Unscoped lookup of a global: iterate over current namespaces,
-   considering using-directives.  If SPACESP is non-NULL, store a list
-   of the namespaces we've considered in it.  */
-
-tree
-unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
-{
-  tree initial = current_decl_namespace ();
-  tree scope = initial;
-  tree siter;
-  struct cp_binding_level *level;
-  tree val = NULL_TREE;
-  cxx_binding binding;
-
-  timevar_push (TV_NAME_LOOKUP);
-  cxx_binding_clear (&binding);
-  if (spacesp)
-    *spacesp = NULL_TREE;
-
-  for (; !val; scope = CP_DECL_CONTEXT (scope))
-    {
-      cxx_binding *b =
-         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
-      if (spacesp)
-       *spacesp = tree_cons (scope, NULL_TREE, *spacesp);
-
-      /* Ignore anticipated built-in functions.  */
-      if (b && b->value && DECL_P (b->value)
-          && DECL_LANG_SPECIFIC (b->value) && DECL_ANTICIPATED (b->value))
-        /* Keep binding cleared.  */;
-      else if (b)
-        {
-          /* Initialize binding for this context.  */
-          binding.value = b->value;
-          binding.type = b->type;
-        }
-
-      /* Add all _DECLs seen through local using-directives.  */
-      for (level = current_binding_level;
-          level->kind != sk_namespace;
-          level = level->level_chain)
-       if (!lookup_using_namespace (name, &binding, level->using_directives,
-                                     scope, flags, spacesp))
-         /* Give up because of error.  */
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-
-      /* Add all _DECLs seen through global using-directives.  */
-      /* XXX local and global using lists should work equally.  */
-      siter = initial;
-      while (1)
-       {
-         if (!lookup_using_namespace (name, &binding,
-                                       DECL_NAMESPACE_USING (siter),
-                                      scope, flags, spacesp))
-           /* Give up because of error.  */
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-         if (siter == scope) break;
-         siter = CP_DECL_CONTEXT (siter);
-       }
-
-      val = select_decl (&binding, flags);
-      if (scope == global_namespace)
-       break;
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
-/* Combine prefer_type and namespaces_only into flags.  */
-
-static int
-lookup_flags (int prefer_type, int namespaces_only)
-{
-  if (namespaces_only)
-    return LOOKUP_PREFER_NAMESPACES;
-  if (prefer_type > 1)
-    return LOOKUP_PREFER_TYPES;
-  if (prefer_type > 0)
-    return LOOKUP_PREFER_BOTH;
-  return 0;
-}
-
-/* Given a lookup that returned VAL, use FLAGS to decide if we want to
-   ignore it or not.  Subroutine of lookup_name_real.  */
-
-static tree
-qualify_lookup (tree val, int flags)
-{
-  if (val == NULL_TREE)
-    return val;
-  if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
-    return val;
-  if ((flags & LOOKUP_PREFER_TYPES)
-      && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
-    return val;
-  if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
-    return NULL_TREE;
-  return val;
-}
-
-/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
-   or a class TYPE).  If IS_TYPE_P is TRUE, then ignore non-type
-   bindings.  
-
-   Returns a DECL (or OVERLOAD, or BASELINK) representing the
-   declaration found.  If no suitable declaration can be found,
-   ERROR_MARK_NODE is returned.  Iif COMPLAIN is true and SCOPE is
-   neither a class-type nor a namespace a diagnostic is issued.  */
-
-tree
-lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
-{
-  int flags = 0;
-
-  if (TREE_CODE (scope) == NAMESPACE_DECL)
-    {
-      cxx_binding binding;
-
-      cxx_binding_clear (&binding);
-      flags |= LOOKUP_COMPLAIN;
-      if (is_type_p)
-       flags |= LOOKUP_PREFER_TYPES;
-      if (qualified_lookup_using_namespace (name, scope, &binding, 
-                                           flags))
-       return select_decl (&binding, flags);
-    }
-  else if (is_aggr_type (scope, complain))
-    {
-      tree t;
-      t = lookup_member (scope, name, 0, is_type_p);
-      if (t)
-       return t;
-    }
-
-  return error_mark_node;
-}
-
 /* Check to see whether or not DECL is a variable that would have been
    in scope under the ARM, but is not in scope under the ANSI/ISO
    standard.  If so, issue an error message.  If name lookup would
@@ -5561,191 +3495,6 @@ check_for_out_of_scope_variable (tree decl)
   return decl;
 }
 
-/* Look up NAME in the current binding level and its superiors in the
-   namespace of variables, functions and typedefs.  Return a ..._DECL
-   node of some kind representing its definition if there is only one
-   such declaration, or return a TREE_LIST with all the overloaded
-   definitions if there are many, or return 0 if it is undefined.
-
-   If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
-   If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
-   Otherwise we prefer non-TYPE_DECLs.
-
-   If NONCLASS is nonzero, we don't look for the NAME in class scope,
-   using IDENTIFIER_CLASS_VALUE.  */
-
-tree
-lookup_name_real (tree name, int prefer_type, int nonclass, 
-                 int namespaces_only, int flags)
-{
-  cxx_binding *iter;
-  tree val = NULL_TREE;
-
-  timevar_push (TV_NAME_LOOKUP);
-  /* Conversion operators are handled specially because ordinary
-     unqualified name lookup will not find template conversion
-     operators.  */
-  if (IDENTIFIER_TYPENAME_P (name)) 
-    {
-      struct cp_binding_level *level;
-
-      for (level = current_binding_level; 
-          level && level->kind != sk_namespace;
-          level = level->level_chain)
-       {
-         tree class_type;
-         tree operators;
-         
-         /* A conversion operator can only be declared in a class 
-            scope.  */
-         if (level->kind != sk_class)
-           continue;
-         
-         /* Lookup the conversion operator in the class.  */
-         class_type = level->this_entity;
-         operators = lookup_fnfields (class_type, name, /*protect=*/0);
-         if (operators)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
-       }
-
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-    }
-
-  flags |= lookup_flags (prefer_type, namespaces_only);
-
-  /* First, look in non-namespace scopes.  */
-
-  if (current_class_type == NULL_TREE)
-    nonclass = 1;
-
-  for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
-    {
-      tree binding;
-
-      if (!LOCAL_BINDING_P (iter) && nonclass)
-       /* We're not looking for class-scoped bindings, so keep going.  */
-       continue;
-
-      /* If this is the kind of thing we're looking for, we're done.  */
-      if (qualify_lookup (iter->value, flags))
-       binding = iter->value;
-      else if ((flags & LOOKUP_PREFER_TYPES)
-              && qualify_lookup (iter->type, flags))
-       binding = iter->type;
-      else
-       binding = NULL_TREE;
-
-      if (binding)
-       {
-         val = binding;
-         break;
-       }
-    }
-
-  /* Now lookup in namespace scopes.  */
-  if (!val)
-    {
-      tree t = unqualified_namespace_lookup (name, flags, 0);
-      if (t)
-       val = t;
-    }
-
-  if (val)
-    {
-      /* If we have a single function from a using decl, pull it out.  */
-      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
-       val = OVL_FUNCTION (val);
-    }
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
-tree
-lookup_name_nonclass (tree name)
-{
-  return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN);
-}
-
-tree
-lookup_function_nonclass (tree name, tree args)
-{
-  return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
-}
-
-tree
-lookup_name (tree name, int prefer_type)
-{
-  return lookup_name_real (name, prefer_type, 0, 0, LOOKUP_COMPLAIN);
-}
-
-/* Similar to `lookup_name' but look only in the innermost non-class
-   binding level.  */
-
-tree
-lookup_name_current_level (tree name)
-{
-  struct cp_binding_level *b;
-  tree t = NULL_TREE;
-
-  timevar_push (TV_NAME_LOOKUP);
-  b = innermost_nonclass_level ();
-
-  if (b->kind == sk_namespace)
-    {
-      t = IDENTIFIER_NAMESPACE_VALUE (name);
-
-      /* extern "C" function() */
-      if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
-       t = TREE_VALUE (t);
-    }
-  else if (IDENTIFIER_BINDING (name)
-          && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
-    {
-      while (1)
-       {
-         if (IDENTIFIER_BINDING (name)->scope == b)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
-
-         if (b->kind == sk_cleanup)
-           b = b->level_chain;
-         else
-           break;
-       }
-    }
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
-}
-
-/* Like lookup_name_current_level, but for types.  */
-
-tree
-lookup_type_current_level (tree name)
-{
-  register tree t = NULL_TREE;
-
-  timevar_push (TV_NAME_LOOKUP);
-  my_friendly_assert (current_binding_level->kind != sk_namespace, 
-                     980716);
-
-  if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
-      && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
-    {
-      struct cp_binding_level *b = current_binding_level;
-      while (1)
-       {
-         if (purpose_member (name, b->type_shadowed))
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                                    REAL_IDENTIFIER_TYPE_VALUE (name));
-         if (b->kind == sk_cleanup)
-           b = b->level_chain;
-         else
-           break;
-       }
-    }
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
-}
-
 \f
 
 /* A chain of TYPE_DECLs for the builtin types.  */
@@ -13457,7 +11206,7 @@ store_parm_decls (tree current_function_parms)
 
       /* Must clear this because it might contain TYPE_DECLs declared
             at class level.  */
-      storedecls (NULL_TREE);
+      current_binding_level->names = NULL;
 
       /* If we're doing semantic analysis, then we'll call pushdecl
             for each of these.  We must do them in reverse order so that
@@ -13496,7 +11245,7 @@ store_parm_decls (tree current_function_parms)
      as the decl-chain of the current lexical scope.
      Put the enumerators in as well, at the front so that
      DECL_ARGUMENTS is not modified.  */
-  storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
+  current_binding_level->names = chainon (nonparms, DECL_ARGUMENTS (fndecl));
 
   /* Do the starting of the exception specifications, if we have any.  */
   if (flag_exceptions && !processing_template_decl
@@ -14250,15 +11999,6 @@ cp_tree_node_structure (union lang_tree_node * t)
     }
 }
 
-/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
-   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
-
-tree
-identifier_global_value        (tree t)
-{
-  return IDENTIFIER_GLOBAL_VALUE (t);
-}
-
 /* Build the void_list_node (void_type_node having been created).  */
 tree
 build_void_list_node (void)
index 3e9d2ca..4f59998 100644 (file)
@@ -28,6 +28,11 @@ Boston, MA 02111-1307, USA.  */
 #include "name-lookup.h"
 #include "timevar.h"
 #include "toplev.h"
+#include "diagnostic.h"
+
+static cxx_scope *innermost_nonclass_level (void);
+static tree select_decl (cxx_binding *, int);
+
 
 /* Compute the chain index of a binding_entry given the HASH value of its
    name and the total COUNT of chains.  COUNT is assumed to be a power
@@ -100,7 +105,7 @@ binding_table_construct (binding_table table, size_t chain_count)
 
 /* Make TABLE's entries ready for reuse.  */
 
-void
+static void
 binding_table_free (binding_table table)
 {
   size_t i;
@@ -125,7 +130,7 @@ binding_table_free (binding_table table)
 
 /* Allocate a table with CHAIN_COUNT, assumed to be a power of two.  */
 
-binding_table
+static inline binding_table
 binding_table_new (size_t chain_count)
 {
   binding_table table = ggc_alloc (sizeof (struct binding_table_s));
@@ -164,7 +169,7 @@ binding_table_expand (binding_table table)
 
 /* Insert a binding for NAME to TYPE into TABLE.  */
 
-void
+static void
 binding_table_insert (binding_table table, tree name, tree type)
 {
   const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
@@ -195,7 +200,7 @@ binding_table_find (binding_table table, tree name)
 
 /* Return the binding_entry, if any, that maps NAME to an anonymous type.  */
 
-tree
+static tree
 binding_table_find_anon_type (binding_table table, tree name)
 {
   const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
@@ -210,7 +215,7 @@ binding_table_find_anon_type (binding_table table, tree name)
 /* Return the binding_entry, if any, that has TYPE as target.  If NAME
    is non-null, then set the domain and rehash that entry.  */
 
-binding_entry
+static binding_entry
 binding_table_reverse_maybe_remap (binding_table table, tree type, tree name)
 {
   const size_t chain_count = table->chain_count;
@@ -285,6 +290,11 @@ binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
     }
 }
 \f
+#ifndef ENABLE_SCOPE_CHECKING
+#  define ENABLE_SCOPE_CHECKING 0
+#else
+#  define ENABLE_SCOPE_CHECKING 1
+#endif
 
 /* A free list of "cxx_binding"s, connected by their PREVIOUS.  */
 
@@ -292,7 +302,7 @@ static GTY((deletable (""))) cxx_binding *free_bindings;
 
 /* (GC)-allocate a binding object with VALUE and TYPE member initialized.  */
 
-cxx_binding *
+static cxx_binding *
 cxx_binding_make (tree value, tree type)
 {
   cxx_binding *binding;
@@ -313,7 +323,7 @@ cxx_binding_make (tree value, tree type)
 
 /* Put BINDING back on the free list.  */
 
-void
+static inline void
 cxx_binding_free (cxx_binding *binding)
 {
   binding->scope = NULL;
@@ -321,6 +331,64 @@ cxx_binding_free (cxx_binding *binding)
   free_bindings = binding;
 }
 
+/* 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, cxx_scope* level)
+{
+   cxx_binding *binding = cxx_binding_make (decl, NULL);
+
+  /* Now, fill in the binding information.  */
+  binding->previous = IDENTIFIER_BINDING (id);
+  binding->scope = level;
+  INHERITED_VALUE_BINDING_P (binding) = 0;
+  LOCAL_BINDING_P (binding) = (level != class_binding_level);
+
+  /* And put it on the front of the list of bindings for ID.  */
+  IDENTIFIER_BINDING (id) = binding;
+}
+
+/* Remove the binding for DECL which should be the innermost binding
+   for ID.  */
+
+void
+pop_binding (tree id, tree decl)
+{
+  cxx_binding *binding;
+
+  if (id == NULL_TREE)
+    /* It's easiest to write the loops that call this function without
+       checking whether or not the entities involved have names.  We
+       get here for such an entity.  */
+    return;
+
+  /* Get the innermost binding for ID.  */
+  binding = IDENTIFIER_BINDING (id);
+
+  /* The name should be bound.  */
+  my_friendly_assert (binding != NULL, 0);
+
+  /* The DECL will be either the ordinary binding or the type
+     binding for this identifier.  Remove that binding.  */
+  if (binding->value == decl)
+    binding->value = NULL_TREE;
+  else if (binding->type == decl)
+    binding->type = NULL_TREE;
+  else
+    abort ();
+
+  if (!binding->value && !binding->type)
+    {
+      /* We're completely done with the innermost binding for this
+        identifier.  Unhook it from the list of bindings.  */
+      IDENTIFIER_BINDING (id) = binding->previous;
+
+      /* Add it to the free list.  */
+      cxx_binding_free (binding);
+    }
+}
+
 /* BINDING records an existing declaration for a namein the current scope.
    But, DECL is another declaration for that same identifier in the
    same scope.  This is the `struct stat' hack whereby a non-typedef
@@ -339,7 +407,7 @@ cxx_binding_free (cxx_binding *binding)
    inserting this name is valid here.  Returns nonzero if the new binding
    was successful.  */
 
-bool
+static bool
 supplement_binding (cxx_binding *binding, tree decl)
 {
   tree bval = binding->value;
@@ -407,7 +475,649 @@ supplement_binding (cxx_binding *binding, tree decl)
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
 }
+
+/* Add DECL to the list of things declared in B.  */
+
+void
+add_decl_to_level (tree decl, cxx_scope *b)
+{
+  if (TREE_CODE (decl) == NAMESPACE_DECL 
+      && !DECL_NAMESPACE_ALIAS (decl))
+    {
+      TREE_CHAIN (decl) = b->namespaces;
+      b->namespaces = decl;
+    }
+  else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
+    {
+      TREE_CHAIN (decl) = b->vtables;
+      b->vtables = decl;
+    }
+  else       
+    {
+      /* We build up the list in reverse order, and reverse it later if
+         necessary.  */
+      TREE_CHAIN (decl) = b->names;
+      b->names = decl;
+      b->names_size++;
+
+      /* If appropriate, add decl to separate list of statics */
+      if (b->kind == sk_namespace)
+       if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+           || (TREE_CODE (decl) == FUNCTION_DECL
+               && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
+         VARRAY_PUSH_TREE (b->static_decls, decl);
+    }
+}
+
+/* Bind DECL to ID in the current_binding_level, assumed to be a local
+   binding level.  If PUSH_USING is set in FLAGS, we know that DECL
+   doesn't really belong to this binding level, that it got here
+   through a using-declaration.  */
+
+void
+push_local_binding (tree id, tree decl, int flags)
+{
+  struct cp_binding_level *b;
+
+  /* Skip over any local classes.  This makes sense if we call
+     push_local_binding with a friend decl of a local class.  */
+  b = innermost_nonclass_level ();
+
+  if (lookup_name_current_level (id))
+    {
+      /* Supplement the existing binding.  */
+      if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
+       /* It didn't work.  Something else must be bound at this
+          level.  Do not add DECL to the list of things to pop
+          later.  */
+       return;
+    }
+  else
+    /* Create a new binding.  */
+    push_binding (id, decl, b);
+
+  if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
+    /* We must put the OVERLOAD into a TREE_LIST since the
+       TREE_CHAIN of an OVERLOAD is already used.  Similarly for
+       decls that got here through a using-declaration.  */
+    decl = build_tree_list (NULL_TREE, decl);
+
+  /* And put DECL on the list of things declared by the current
+     binding level.  */
+  add_decl_to_level (decl, b);
+}
+\f
+/* true means unconditionally make a BLOCK for the next level pushed.  */
+
+static bool keep_next_level_flag;
+
+static int binding_depth = 0;
+static int is_class_level = 0;
+
+static void
+indent (int depth)
+{
+  int i;
+
+  for (i = 0; i < depth * 2; i++)
+    putc (' ', stderr);
+}
+
+/* Return a string describing the kind of SCOPE we have.  */
+static const char *
+cxx_scope_descriptor (cxx_scope *scope)
+{
+  /* The order of this table must match the "scope_kind"
+     enumerators.  */
+  static const char* scope_kind_names[] = {
+    "block-scope",
+    "cleanup-scope",
+    "try-scope",
+    "catch-scope",
+    "for-scope",
+    "function-parameter-scope",
+    "class-scope",
+    "namespace-scope",
+    "template-parameter-scope",
+    "template-explicit-spec-scope"
+  };
+  const scope_kind kind = scope->explicit_spec_p
+    ? sk_template_spec : scope->kind;
+
+  return scope_kind_names[kind];
+}
+
+/* Output a debugging information about SCOPE when performning
+   ACTION at LINE.  */
+static void
+cxx_scope_debug (cxx_scope *scope, int line, const char *action)
+{
+  const char *desc = cxx_scope_descriptor (scope);
+  if (scope->this_entity)
+    verbatim ("%s %s(%E) %p %d\n", action, desc,
+              scope->this_entity, (void *) scope, line);
+  else
+    verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
+}
+
+/* Return the estimated initial size of the hashtable of a NAMESPACE
+   scope.  */
+
+static inline size_t
+namespace_scope_ht_size (tree ns)
+{
+  tree name = DECL_NAME (ns);
+
+  return name == std_identifier
+    ? NAMESPACE_STD_HT_SIZE
+    : (name == global_scope_name
+       ? GLOBAL_SCOPE_HT_SIZE
+       : NAMESPACE_ORDINARY_HT_SIZE);
+}
+
+/* A chain of binding_level structures awaiting reuse.  */
+
+static GTY((deletable (""))) struct cp_binding_level *free_binding_level;
+
+/* Create a new KIND scope and make it the top of the active scopes stack.
+   ENTITY is the scope of the associated C++ entity (namespace, class,
+   function); it is NULL otherwise.  */
+
+cxx_scope *
+begin_scope (scope_kind kind, tree entity)
+{
+  cxx_scope *scope;
+  
+  /* Reuse or create a struct for this binding level.  */
+  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
+    {
+      scope = free_binding_level;
+      free_binding_level = scope->level_chain;
+    }
+  else
+    scope = ggc_alloc (sizeof (cxx_scope));
+  memset (scope, 0, sizeof (cxx_scope));
+
+  scope->this_entity = entity;
+  scope->more_cleanups_ok = true;
+  switch (kind)
+    {
+    case sk_cleanup:
+      scope->keep = true;
+      break;
+      
+    case sk_template_spec:
+      scope->explicit_spec_p = true;
+      kind = sk_template_parms;
+      /* fall through */
+    case sk_template_parms:
+    case sk_block:
+    case sk_try:
+    case sk_catch:
+    case sk_for:
+    case sk_class:
+    case sk_function_parms:
+      scope->keep = keep_next_level_flag;
+      break;
+
+    case sk_namespace:
+      scope->type_decls = binding_table_new (namespace_scope_ht_size (entity));
+      NAMESPACE_LEVEL (entity) = scope;
+      VARRAY_TREE_INIT (scope->static_decls,
+                        DECL_NAME (entity) == std_identifier
+                        || DECL_NAME (entity) == global_scope_name
+                        ? 200 : 10,
+                        "Static declarations");
+      break;
+
+    default:
+      /* Should not happen.  */
+      my_friendly_assert (false, 20030922);
+      break;
+    }
+  scope->kind = kind;
+
+  /* Add it to the front of currently active scopes stack.  */
+  scope->level_chain = current_binding_level;
+  current_binding_level = scope;
+  keep_next_level_flag = false;
+
+  if (ENABLE_SCOPE_CHECKING)
+    {
+      scope->binding_depth = binding_depth;
+      indent (binding_depth);
+      cxx_scope_debug (scope, input_location.line, "push");
+      is_class_level = 0;
+      binding_depth++;
+    }
+
+  return scope;
+}
+
+/* We're about to leave current scope.  Pop the top of the stack of
+   currently active scopes.  Return the enclosing scope, now active.  */
+
+cxx_scope *
+leave_scope (void)
+{
+  cxx_scope *scope = current_binding_level;
+
+  if (scope->kind == sk_namespace && class_binding_level)
+    current_binding_level = class_binding_level;
+
+  /* We cannot leave a scope, if there are none left.  */
+  if (NAMESPACE_LEVEL (global_namespace))
+    my_friendly_assert (!global_scope_p (scope), 20030527);
+  
+  if (ENABLE_SCOPE_CHECKING)
+    {
+      indent (--binding_depth);
+      cxx_scope_debug (scope, input_location.line, "leave");
+      if (is_class_level != (scope == class_binding_level))
+        {
+          indent (binding_depth);
+          verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
+        }
+      is_class_level = 0;
+    }
+
+  /* Move one nesting level up.  */
+  current_binding_level = scope->level_chain;
+
+  /* Namespace-scopes are left most probably temporarily, not completely;
+     they can be reopen later, e.g. in namespace-extension or any name
+     binding acttivity that requires us to resume a namespace.  For other
+     scopes, we just make the structure available for reuse.  */
+  if (scope->kind != sk_namespace)
+    {
+      scope->level_chain = free_binding_level;
+      if (scope->kind == sk_class)
+        scope->type_decls = NULL;
+      else
+        binding_table_free (scope->type_decls);
+      my_friendly_assert (!ENABLE_SCOPE_CHECKING
+                          || scope->binding_depth == binding_depth,
+                          20030529);
+      free_binding_level = scope;
+    }
+
+  /* Find the innermost enclosing class scope, and reset
+     CLASS_BINDING_LEVEL appropriately.  */
+  for (scope = current_binding_level;
+       scope && scope->kind != sk_class;
+       scope = scope->level_chain)
+    ;
+  class_binding_level = scope && scope->kind == sk_class ? scope : NULL;
+
+  return current_binding_level;
+}
+
+static void
+resume_scope (struct cp_binding_level* b)
+{
+  /* Resuming binding levels is meant only for namespaces,
+     and those cannot nest into classes.  */
+  my_friendly_assert(!class_binding_level, 386);
+  /* Also, resuming a non-directly nested namespace is a no-no.  */
+  my_friendly_assert(b->level_chain == current_binding_level, 386);
+  current_binding_level = b;
+  if (ENABLE_SCOPE_CHECKING)
+    {
+      b->binding_depth = binding_depth;
+      indent (binding_depth);
+      cxx_scope_debug (b, input_location.line, "resume");
+      is_class_level = 0;
+      binding_depth++;
+    }
+}
+
+/* Return the innermost binding level that is not for a class scope.  */
+
+static cxx_scope *
+innermost_nonclass_level (void)
+{
+  cxx_scope *b;
+
+  b = current_binding_level;
+  while (b->kind == sk_class)
+    b = b->level_chain;
+
+  return b;
+}
+
+/* We're defining an object of type TYPE.  If it needs a cleanup, but
+   we're not allowed to add any more objects with cleanups to the current
+   scope, create a new binding level.  */
+
+void
+maybe_push_cleanup_level (tree type)
+{
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+      && current_binding_level->more_cleanups_ok == 0)
+    {
+      begin_scope (sk_cleanup, NULL);
+      clear_last_expr ();
+      add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
+    }
+}
+
+/* Nonzero if we are currently in the global binding level.  */
+
+int
+global_bindings_p (void)
+{
+  return global_scope_p (current_binding_level);
+}
+
+/* True if we are currently in a toplevel binding level.  This
+   means either the global binding level or a namespace in a toplevel
+   binding level.  Since there are no non-toplevel namespace levels,
+   this really means any namespace or template parameter level.  We
+   also include a class whose context is toplevel.  */
+
+bool
+toplevel_bindings_p (void)
+{
+  struct cp_binding_level *b = innermost_nonclass_level ();
+
+  return b->kind == sk_namespace || b->kind == sk_template_parms;
+}
+
+/* True if this is a namespace scope, or if we are defining a class
+   which is itself at namespace scope, or whose enclosing class is
+   such a class, etc.  */
+
+bool
+namespace_bindings_p (void)
+{
+  struct cp_binding_level *b = innermost_nonclass_level ();
+
+  return b->kind == sk_namespace;
+}
+
+/* True if the current level needs to have a BLOCK made.  */
+
+bool
+kept_level_p (void)
+{
+  return (current_binding_level->blocks != NULL_TREE
+         || current_binding_level->keep
+          || current_binding_level->kind == sk_cleanup
+         || current_binding_level->names != NULL_TREE
+         || current_binding_level->type_decls != NULL);
+}
+
+/* Returns the kind of the innermost scope.  */
+
+scope_kind
+innermost_scope_kind (void)
+{
+  return current_binding_level->kind;
+}
+
+/* Returns true if this scope was created to store template parameters.  */
+
+bool
+template_parm_scope_p (void)
+{
+  return innermost_scope_kind () == sk_template_parms;
+}
+
+/* If KEEP is true, make a BLOCK node for the next binding level,
+   unconditionally.  Otherwise, use the normal logic to decide whether
+   or not to create a BLOCK.  */
+
+void
+keep_next_level (bool keep)
+{
+  keep_next_level_flag = keep;
+}
+
+/* Return the list of declarations of the current level.
+   Note that this list is in reverse order unless/until
+   you nreverse it; and when you do nreverse it, you must
+   store the result back using `storedecls' or you will lose.  */
+
+tree
+getdecls (void)
+{
+  return current_binding_level->names;
+}
+
+/* Set the current binding TABLE for type declarations..  This is a
+   temporary workaround of the fact that the data structure classtypes
+   does not currently carry its allocated cxx_scope structure.  */
+void
+cxx_remember_type_decls (binding_table table)
+{
+  current_binding_level->type_decls = table;
+}
+
+/* For debugging.  */
+static int no_print_functions = 0;
+static int no_print_builtins = 0;
+
+/* Called from print_binding_level through binding_table_foreach to
+   print the content of binding ENTRY.  DATA is a pointer to line offset
+   marker.  */
+static void
+bt_print_entry (binding_entry entry, void *data)
+{
+  int *p = (int *) data;
+  int len;
+
+  if (entry->name == NULL)
+    len = 3;
+  else if (entry->name == TYPE_IDENTIFIER (entry->type))
+    len = 2;
+  else
+    len = 4;
+    len = 4;
+
+  *p += len;
+
+  if (*p > 5)
+    {
+      fprintf (stderr, "\n\t");
+      *p = len;
+    }
+  if (entry->name == NULL)
+    {
+      print_node_brief (stderr, "<unnamed-typedef", entry->type, 0);
+      fprintf (stderr, ">");
+    }
+  else if (entry->name == TYPE_IDENTIFIER (entry->type))
+    print_node_brief (stderr, "", entry->type, 0);
+  else
+    {
+      print_node_brief (stderr, "<typedef", entry->name, 0);
+      print_node_brief (stderr, "", entry->type, 0);
+      fprintf (stderr, ">");
+    }
+}
+
+void
+print_binding_level (struct cp_binding_level* lvl)
+{
+  tree t;
+  int i = 0, len;
+  fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
+  if (lvl->more_cleanups_ok)
+    fprintf (stderr, " more-cleanups-ok");
+  if (lvl->have_cleanups)
+    fprintf (stderr, " have-cleanups");
+  fprintf (stderr, "\n");
+  if (lvl->names)
+    {
+      fprintf (stderr, " names:\t");
+      /* We can probably fit 3 names to a line?  */
+      for (t = lvl->names; t; t = TREE_CHAIN (t))
+       {
+         if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
+           continue;
+         if (no_print_builtins
+             && (TREE_CODE (t) == TYPE_DECL)
+             && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))
+           continue;
+
+         /* Function decls tend to have longer names.  */
+         if (TREE_CODE (t) == FUNCTION_DECL)
+           len = 3;
+         else
+           len = 2;
+         i += len;
+         if (i > 6)
+           {
+             fprintf (stderr, "\n\t");
+             i = len;
+           }
+         print_node_brief (stderr, "", t, 0);
+         if (t == error_mark_node)
+           break;
+       }
+      if (i)
+        fprintf (stderr, "\n");
+    }
+  if (lvl->type_decls)
+    {
+      fprintf (stderr, " tags:\t");
+      i = 0;
+      binding_table_foreach (lvl->type_decls, bt_print_entry, &i);
+      if (i)
+       fprintf (stderr, "\n");
+    }
+  if (lvl->class_shadowed)
+    {
+      fprintf (stderr, " class-shadowed:");
+      for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
+       {
+         fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+       }
+      fprintf (stderr, "\n");
+    }
+  if (lvl->type_shadowed)
+    {
+      fprintf (stderr, " type-shadowed:");
+      for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
+        {
+         fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+        }
+      fprintf (stderr, "\n");
+    }
+}
+
+void
+print_other_binding_stack (struct cp_binding_level *stack)
+{
+  struct cp_binding_level *level;
+  for (level = stack; !global_scope_p (level); level = level->level_chain)
+    {
+      fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level);
+      print_binding_level (level);
+    }
+}
+
+void
+print_binding_stack (void)
+{
+  struct cp_binding_level *b;
+  fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF
+          "\nclass_binding_level=" HOST_PTR_PRINTF
+          "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n",
+          (void *) current_binding_level, (void *) class_binding_level,
+           (void *) NAMESPACE_LEVEL (global_namespace));
+  if (class_binding_level)
+    {
+      for (b = class_binding_level; b; b = b->level_chain)
+       if (b == current_binding_level)
+         break;
+      if (b)
+       b = class_binding_level;
+      else
+       b = current_binding_level;
+    }
+  else
+    b = current_binding_level;
+  print_other_binding_stack (b);
+  fprintf (stderr, "global:\n");
+  print_binding_level (NAMESPACE_LEVEL (global_namespace));
+}
 \f
+/* Return the type associated with id.  */
+
+tree
+identifier_type_value (tree id)
+{
+  timevar_push (TV_NAME_LOOKUP);
+  /* There is no type with that name, anywhere.  */
+  if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+  /* This is not the type marker, but the real thing.  */
+  if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
+  /* Have to search for it. It must be on the global level, now.
+     Ask lookup_name not to return non-types.  */
+  id = lookup_name_real (id, 2, 1, 0, LOOKUP_COMPLAIN);
+  if (id)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+}
+
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+   the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
+
+tree
+identifier_global_value        (tree t)
+{
+  return IDENTIFIER_GLOBAL_VALUE (t);
+}
+
+/* Push a definition of struct, union or enum tag named ID.  into
+   binding_level B.  DECL is a TYPE_DECL for the type.  We assume that
+   the tag ID is not already defined.  */
+
+static void
+set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b)
+{
+  tree type;
+
+  if (b->kind != sk_namespace)
+    {
+      /* Shadow the marker, not the real thing, so that the marker
+        gets restored later.  */
+      tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+      b->type_shadowed
+       = tree_cons (id, old_type_value, b->type_shadowed);
+      type = decl ? TREE_TYPE (decl) : NULL_TREE;
+    }
+  else
+    {
+      cxx_binding *binding =
+       binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
+      if (decl)
+       {
+         if (binding->value)
+           supplement_binding (binding, decl);
+         else
+           binding->value = decl;
+       }
+      else
+       abort ();
+      /* Store marker instead of real type.  */
+      type = global_type_node;
+    }
+  SET_IDENTIFIER_TYPE_VALUE (id, type);
+}
+
+/* As set_identifier_type_value_with_scope, but using
+   current_binding_level.  */
+
+void
+set_identifier_type_value (tree id, tree decl)
+{
+  set_identifier_type_value_with_scope (id, decl, current_binding_level);
+}
+
 /* Return (from the stack of) the BINDING, if any, establihsed at SCOPE.  */ 
 
 static inline cxx_binding *
@@ -458,25 +1168,531 @@ binding_for_name (cxx_scope *scope, tree name)
   IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
   return result;
 }
-\f
-/* Namespace-scope manipulation routines.  */
 
-/* Return the binding value for name in scope.  */
+/* Same as pushdecl, but define X in binding-level LEVEL.  We rely on the
+   caller to set DECL_CONTEXT properly.  */
 
 tree
-namespace_binding (tree name, tree scope)
+pushdecl_with_scope (tree x, cxx_scope *level)
 {
-  cxx_binding *binding;
-
-  if (scope == NULL)
-    scope = global_namespace;
-  scope = ORIGINAL_NAMESPACE (scope);
-  binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+  register struct cp_binding_level *b;
+  tree function_decl = current_function_decl;
 
-  return binding ? binding->value : NULL_TREE;
-}
-
-/* Set the binding value for name in scope.  */
+  timevar_push (TV_NAME_LOOKUP);
+  current_function_decl = NULL_TREE;
+  if (level->kind == sk_class)
+    {
+      b = class_binding_level;
+      class_binding_level = level;
+      pushdecl_class_level (x);
+      class_binding_level = b;
+    }
+  else
+    {
+      b = current_binding_level;
+      current_binding_level = level;
+      x = pushdecl (x);
+      current_binding_level = b;
+    }
+  current_function_decl = function_decl;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+}
+
+/* Return the type that should be used when TYPE's name is preceded
+   by a tag such as 'struct' or 'union', or null if the name cannot
+   be used in this way.
+
+   For example, when processing the third line of:
+
+       struct A;
+       typedef struct A A;
+       struct A;
+
+   lookup of A will find the typedef.  Given A's typedef, this function
+   will return the type associated with "struct A".  For the tag to be
+   anything other than TYPE, TYPE must be a typedef whose original type
+   has the same name and context as TYPE itself.
+
+   It is not valid for a typedef of an anonymous type to be used with
+   an explicit tag:
+
+       typedef struct { ... } B;
+       struct B;
+
+   Return null for this case.  */
+
+static tree
+follow_tag_typedef (tree type)
+{
+  tree original;
+
+  original = original_type (type);
+  if (! TYPE_NAME (original))
+    return NULL_TREE;
+  if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type)
+      && (CP_DECL_CONTEXT (TYPE_NAME (original))
+         == CP_DECL_CONTEXT (TYPE_NAME (type)))
+      && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original)))
+    return original;
+  else
+    return NULL_TREE;
+}
+
+/* Given NAME, an IDENTIFIER_NODE,
+   return the structure (or union or enum) definition for that name.
+   Searches binding levels from its SCOPE up to the global level.
+   If THISLEVEL_ONLY is nonzero, searches only the specified context
+   (but skips any sk_cleanup contexts to find one that is
+   meaningful for tags).
+   FORM says which kind of type the caller wants;
+   it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
+   If the wrong kind of type is found, and it's not a template, an error is
+   reported.  */
+
+tree
+lookup_tag (enum tree_code form, tree name,
+            cxx_scope *binding_level, int thislevel_only)
+{
+  register struct cp_binding_level *level;
+  /* Nonzero if, we should look past a template parameter level, even
+     if THISLEVEL_ONLY.  */
+  int allow_template_parms_p = 1;
+  bool type_is_anonymous = ANON_AGGRNAME_P (name);
+
+  timevar_push (TV_NAME_LOOKUP);
+  for (level = binding_level; level; level = level->level_chain)
+    {
+      register tree tail;
+      if (type_is_anonymous && level->type_decls != NULL)
+        {
+          tree type = binding_table_find_anon_type (level->type_decls, name);
+          /* There is no need for error checking here, because
+           anon names are unique throughout the compilation.  */
+          if (type != NULL)
+            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
+        }
+      else if (level->kind == sk_namespace)
+       /* Do namespace lookup.  */
+       for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
+         {
+            cxx_binding *binding =
+              cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
+           tree old;
+
+           /* If we just skipped past a template parameter level,
+              even though THISLEVEL_ONLY, and we find a template
+              class declaration, then we use the _TYPE node for the
+              template.  See the example below.  */
+           if (thislevel_only && !allow_template_parms_p
+               && binding && binding->value
+               && DECL_CLASS_TEMPLATE_P (binding->value))
+             old = binding->value;
+           else if (binding)
+             old = select_decl (binding, LOOKUP_PREFER_TYPES);
+            else
+              old = NULL_TREE;
+
+           if (old)
+             {
+               /* We've found something at this binding level.  If it is
+                  a typedef, extract the tag it refers to.  Lookup fails
+                  if the typedef doesn't refer to a taggable type.  */
+               old = TREE_TYPE (old);
+               old = follow_tag_typedef (old);
+               if (!old)
+                 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+               if (TREE_CODE (old) != form
+                   && (form == ENUMERAL_TYPE
+                       || TREE_CODE (old) == ENUMERAL_TYPE))
+                 {
+                   error ("`%#D' redeclared as %C", old, form);
+                   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+                 }
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
+             }
+           if (thislevel_only || tail == global_namespace)
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+         }
+      else if (level->type_decls != NULL)
+        {
+          binding_entry entry = binding_table_find (level->type_decls, name);
+          if (entry != NULL)
+            {
+              enum tree_code code = TREE_CODE (entry->type);
+               
+              if (code != form
+                  && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
+                {
+                  /* Definition isn't the kind we were looking for.  */
+                  error ("`%#D' redeclared as %C", entry->type, form);
+                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+                }
+              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
+            }
+         }
+      if (thislevel_only && level->kind != sk_cleanup)
+       {
+         if (level->kind == sk_template_parms && allow_template_parms_p)
+           {
+             /* We must deal with cases like this:
+
+                  template <class T> struct S;
+                  template <class T> struct S {};
+
+                When looking up `S', for the second declaration, we
+                would like to find the first declaration.  But, we
+                are in the pseudo-global level created for the
+                template parameters, rather than the (surrounding)
+                namespace level.  Thus, we keep going one more level,
+                even though THISLEVEL_ONLY is nonzero.  */
+             allow_template_parms_p = 0;
+             continue;
+           }
+         else
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+       }
+    }
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+}
+
+/* Given a type, find the tag that was defined for it and return the tag name.
+   Otherwise return 0.  However, the value can never be 0
+   in the cases in which this is used.
+
+   C++: If NAME is nonzero, this is the new name to install.  This is
+   done when replacing anonymous tags with real tag names.  */
+
+tree
+lookup_tag_reverse (tree type, tree name)
+{
+  register struct cp_binding_level *level;
+
+  timevar_push (TV_NAME_LOOKUP);
+  for (level = current_binding_level; level; level = level->level_chain)
+    {
+      binding_entry entry = level->type_decls == NULL
+        ? NULL
+        : binding_table_reverse_maybe_remap (level->type_decls, type, name);
+      if (entry)
+        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name);
+    }
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+}
+\f
+/* Do a pushlevel for class declarations.  */
+
+void
+pushlevel_class (void)
+{
+  if (ENABLE_SCOPE_CHECKING)
+    is_class_level = 1;
+
+  class_binding_level = begin_scope (sk_class, current_class_type);
+}
+
+/* ...and a poplevel for class declarations.  */
+
+void
+poplevel_class (void)
+{
+  register struct cp_binding_level *level = class_binding_level;
+  tree shadowed;
+
+  timevar_push (TV_NAME_LOOKUP);
+  my_friendly_assert (level != 0, 354);
+
+  /* If we're leaving a toplevel class, don't bother to do the setting
+     of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
+     shouldn't even be used when current_class_type isn't set, and second,
+     if we don't touch it here, we're able to use the cache effect if the
+     next time we're entering a class scope, it is the same class.  */
+  if (current_class_depth != 1)
+    {
+      struct cp_binding_level* b;
+
+      /* Clear out our IDENTIFIER_CLASS_VALUEs.  */
+      for (shadowed = level->class_shadowed;
+          shadowed;
+          shadowed = TREE_CHAIN (shadowed))
+       IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
+
+      /* Find the next enclosing class, and recreate
+        IDENTIFIER_CLASS_VALUEs appropriate for that class.  */
+      b = level->level_chain;
+      while (b && b->kind != sk_class)
+       b = b->level_chain;
+
+      if (b)
+       for (shadowed = b->class_shadowed;
+            shadowed;
+            shadowed = TREE_CHAIN (shadowed))
+         {
+           cxx_binding *binding;
+            
+           binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
+           while (binding && binding->scope != b)
+             binding = binding->previous;
+
+           if (binding)
+             IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
+               = binding->value;
+         }
+    }
+  else
+    /* Remember to save what IDENTIFIER's were bound in this scope so we
+       can recover from cache misses.  */
+    {
+      previous_class_type = current_class_type;
+      previous_class_values = class_binding_level->class_shadowed;
+    }
+  for (shadowed = level->type_shadowed;
+       shadowed;
+       shadowed = TREE_CHAIN (shadowed))
+    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
+
+  /* Remove the bindings for all of the class-level declarations.  */
+  for (shadowed = level->class_shadowed;
+       shadowed;
+       shadowed = TREE_CHAIN (shadowed))
+    pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
+
+  /* Now, pop out of the binding level which we created up in the
+     `pushlevel_class' routine.  */
+  if (ENABLE_SCOPE_CHECKING)
+    is_class_level = 1;
+
+  leave_scope ();
+  timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Bind DECL to ID in the class_binding_level.  Returns nonzero if the
+   binding was successful.  */
+
+int
+push_class_binding (tree id, tree decl)
+{
+  int result = 1;
+  cxx_binding *binding = IDENTIFIER_BINDING (id);
+  tree context;
+
+  timevar_push (TV_NAME_LOOKUP);
+  /* Note that we declared this value so that we can issue an error if
+     this is an invalid redeclaration of a name already used for some
+     other purpose.  */
+  note_name_declared_in_class (id, decl);
+
+  if (binding && binding->scope == class_binding_level)
+    /* Supplement the existing binding.  */
+    result = supplement_binding (IDENTIFIER_BINDING (id), decl);
+  else
+    /* Create a new binding.  */
+    push_binding (id, decl, class_binding_level);
+
+  /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the
+     class-level declaration.  Note that we do not use DECL here
+     because of the possibility of the `struct stat' hack; if DECL is
+     a class-name or enum-name we might prefer a field-name, or some
+     such.  */
+  IDENTIFIER_CLASS_VALUE (id) = IDENTIFIER_BINDING (id)->value;
+
+  /* If this is a binding from a base class, mark it as such.  */
+  binding = IDENTIFIER_BINDING (id);
+  if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)
+    {
+      if (TREE_CODE (decl) == OVERLOAD)
+       context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
+      else
+       {
+         my_friendly_assert (DECL_P (decl), 0);
+         context = context_for_name_lookup (decl);
+       }
+
+      if (is_properly_derived_from (current_class_type, context))
+       INHERITED_VALUE_BINDING_P (binding) = 1;
+      else
+       INHERITED_VALUE_BINDING_P (binding) = 0;
+    }
+  else if (binding->value == decl)
+    /* We only encounter a TREE_LIST when push_class_decls detects an
+       ambiguity.  Such an ambiguity can be overridden by a definition
+       in this class.  */
+    INHERITED_VALUE_BINDING_P (binding) = 1;
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result);
+}
+
+/* We are entering the scope of a class.  Clear IDENTIFIER_CLASS_VALUE
+   for any names in enclosing classes.  */
+
+void
+clear_identifier_class_values (void)
+{
+  tree t;
+
+  if (!class_binding_level)
+    return;
+
+  for (t = class_binding_level->class_shadowed;
+       t;
+       t = TREE_CHAIN (t))
+    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
+}
+
+/* Make the declaration of X appear in CLASS scope.  */
+
+bool
+pushdecl_class_level (tree x)
+{
+  tree name;
+  bool is_valid = true;
+
+  timevar_push (TV_NAME_LOOKUP);
+  /* Get the name of X.  */
+  if (TREE_CODE (x) == OVERLOAD)
+    name = DECL_NAME (get_first_fn (x));
+  else
+    name = DECL_NAME (x);
+
+  if (name)
+    {
+      is_valid = push_class_level_binding (name, x);
+      if (TREE_CODE (x) == TYPE_DECL)
+       set_identifier_type_value (name, x);
+    }
+  else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+    {
+      /* If X is an anonymous aggregate, all of its members are
+        treated as if they were members of the class containing the
+        aggregate, for naming purposes.  */
+      tree f;
+
+      for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
+       {
+         location_t save_location = input_location;
+         input_location = DECL_SOURCE_LOCATION (f);
+         if (!pushdecl_class_level (f))
+           is_valid = false;
+         input_location = save_location;
+       }
+    }
+  timevar_pop (TV_NAME_LOOKUP);
+
+  return is_valid;
+}
+
+/* Make the declaration(s) of X appear in CLASS scope under the name
+   NAME.  Returns true if the binding is valid.  */
+
+bool
+push_class_level_binding (tree name, tree x)
+{
+  cxx_binding *binding;
+
+  timevar_push (TV_NAME_LOOKUP);
+  /* The class_binding_level will be NULL if x is a template
+     parameter name in a member template.  */
+  if (!class_binding_level)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+
+  /* Make sure that this new member does not have the same name
+     as a template parameter.  */
+  if (TYPE_BEING_DEFINED (current_class_type))
+    check_template_shadow (x);
+
+  /* If this declaration shadows a declaration from an enclosing
+     class, then we will need to restore IDENTIFIER_CLASS_VALUE when
+     we leave this class.  Record the shadowed declaration here.  */
+  binding = IDENTIFIER_BINDING (name);
+  if (binding && binding->value)
+    {
+      tree bval = binding->value;
+      tree old_decl = NULL_TREE;
+
+      if (INHERITED_VALUE_BINDING_P (binding))
+       {
+         /* If the old binding was from a base class, and was for a
+            tag name, slide it over to make room for the new binding.
+            The old binding is still visible if explicitly qualified
+            with a class-key.  */
+         if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
+             && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
+           {
+             old_decl = binding->type;
+             binding->type = bval;
+             binding->value = NULL_TREE;
+             INHERITED_VALUE_BINDING_P (binding) = 0;
+           }
+         else
+           old_decl = bval;
+       }
+      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
+       old_decl = bval;
+      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
+       old_decl = bval;
+      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+      
+      if (old_decl)
+       {
+         tree shadow;
+         
+         /* Find the previous binding of name on the class-shadowed
+             list, and update it.  */
+         for (shadow = class_binding_level->class_shadowed;
+              shadow;
+              shadow = TREE_CHAIN (shadow))
+           if (TREE_PURPOSE (shadow) == name
+               && TREE_TYPE (shadow) == old_decl)
+             {
+               binding->value = x;
+               INHERITED_VALUE_BINDING_P (binding) = 0;
+               TREE_TYPE (shadow) = x;
+               IDENTIFIER_CLASS_VALUE (name) = x;
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+             }
+       }
+    }
+
+  /* If we didn't replace an existing binding, put the binding on the
+     stack of bindings for the identifier, and update the shadowed list.  */
+  if (push_class_binding (name, x))
+    {
+      class_binding_level->class_shadowed
+       = tree_cons (name, NULL,
+                    class_binding_level->class_shadowed);
+      /* Record the value we are binding NAME to so that we can know
+        what to pop later.  */
+      TREE_TYPE (class_binding_level->class_shadowed) = x;
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+    }
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+}
+
+void
+set_class_shadows (tree shadows)
+{
+  class_binding_level->class_shadowed = shadows;
+}
+\f
+/* 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)
@@ -494,4 +1710,1011 @@ set_namespace_binding (tree name, tree scope, tree 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.  */
+
+void
+push_namespace (tree name)
+{
+  tree d = NULL_TREE;
+  int need_new = 1;
+  int implicit_use = 0;
+
+  timevar_push (TV_NAME_LOOKUP);
+  
+  /* We should not get here if the global_namespace is not yet constructed
+     nor if NAME designates the global namespace:  The global scope is
+     constructed elsewhere.  */
+  my_friendly_assert (global_namespace != NULL && name != global_scope_name,
+                      20030531);
+
+  if (!name)
+    {
+      /* The name of anonymous namespace is unique for the translation
+         unit.  */
+      if (!anonymous_namespace_name)
+        anonymous_namespace_name = get_file_function_name ('N');
+      name = anonymous_namespace_name;
+      d = IDENTIFIER_NAMESPACE_VALUE (name);
+      if (d)
+        /* Reopening anonymous namespace.  */
+        need_new = 0;
+      implicit_use = 1;
+    }
+  else
+    {
+      /* Check whether this is an extended namespace definition.  */
+      d = IDENTIFIER_NAMESPACE_VALUE (name);
+      if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
+        {
+          need_new = 0;
+          if (DECL_NAMESPACE_ALIAS (d))
+            {
+              error ("namespace alias `%D' not allowed here, assuming `%D'",
+                        d, DECL_NAMESPACE_ALIAS (d));
+              d = DECL_NAMESPACE_ALIAS (d);
+            }
+        }
+    }
+
+  if (need_new)
+    {
+      /* Make a new namespace, binding the name to it.  */
+      d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
+      DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
+      d = pushdecl (d);
+      begin_scope (sk_namespace, d);
+    }
+  else
+    resume_scope (NAMESPACE_LEVEL (d));
+
+  if (implicit_use)
+    do_using_directive (d);
+  /* Enter the name space.  */
+  current_namespace = d;
+
+  timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Pop from the scope of the current namespace.  */
+
+void
+pop_namespace (void)
+{
+  my_friendly_assert (current_namespace != global_namespace, 20010801);
+  current_namespace = CP_DECL_CONTEXT (current_namespace);
+  /* The binding level is not popped, as it might be re-opened later.  */
+  leave_scope ();
+}
+
+/* Push into the scope of the namespace NS, even if it is deeply
+   nested within another namespace.  */
+
+void
+push_nested_namespace (tree ns)
+{
+  if (ns == global_namespace)
+    push_to_top_level ();
+  else
+    {
+      push_nested_namespace (CP_DECL_CONTEXT (ns));
+      push_namespace (DECL_NAME (ns));
+    }
+}
+
+/* Pop back from the scope of the namespace NS, which was previously
+   entered with push_nested_namespace.  */
+
+void
+pop_nested_namespace (tree ns)
+{
+  timevar_push (TV_NAME_LOOKUP);
+  while (ns != global_namespace)
+    {
+      pop_namespace ();
+      ns = CP_DECL_CONTEXT (ns);
+    }
+
+  pop_from_top_level ();
+  timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Like pushdecl, only it places X in the current namespace,
+   if appropriate.  */
+
+tree
+pushdecl_namespace_level (tree x)
+{
+  register struct cp_binding_level *b = current_binding_level;
+  register tree t;
+
+  timevar_push (TV_NAME_LOOKUP);
+  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
+
+  /* Now, the type_shadowed stack may screw us.  Munge it so it does
+     what we want.  */
+  if (TREE_CODE (x) == TYPE_DECL)
+    {
+      tree name = DECL_NAME (x);
+      tree newval;
+      tree *ptr = (tree *)0;
+      for (; !global_scope_p (b); b = b->level_chain)
+        {
+          tree shadowed = b->type_shadowed;
+          for (; shadowed; shadowed = TREE_CHAIN (shadowed))
+            if (TREE_PURPOSE (shadowed) == name)
+              {
+               ptr = &TREE_VALUE (shadowed);
+               /* Can't break out of the loop here because sometimes
+                  a binding level will have duplicate bindings for
+                  PT names.  It's gross, but I haven't time to fix it.  */
+              }
+        }
+      newval = TREE_TYPE (x);
+      if (ptr == (tree *)0)
+        {
+          /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
+             up here if this is changed to an assertion.  --KR  */
+         SET_IDENTIFIER_TYPE_VALUE (name, x);
+       }
+      else
+        {
+         *ptr = newval;
+        }
+    }
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+}
+
+/* Return the declarations that are members of the namespace NS.  */
+
+tree
+cp_namespace_decls (tree ns)
+{
+  return NAMESPACE_LEVEL (ns)->names;
+}
+
+/* Combine prefer_type and namespaces_only into flags.  */
+
+static int
+lookup_flags (int prefer_type, int namespaces_only)
+{
+  if (namespaces_only)
+    return LOOKUP_PREFER_NAMESPACES;
+  if (prefer_type > 1)
+    return LOOKUP_PREFER_TYPES;
+  if (prefer_type > 0)
+    return LOOKUP_PREFER_BOTH;
+  return 0;
+}
+
+/* Given a lookup that returned VAL, use FLAGS to decide if we want to
+   ignore it or not.  Subroutine of lookup_name_real.  */
+
+static tree
+qualify_lookup (tree val, int flags)
+{
+  if (val == NULL_TREE)
+    return val;
+  if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
+    return val;
+  if ((flags & LOOKUP_PREFER_TYPES)
+      && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
+    return val;
+  if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
+    return NULL_TREE;
+  return val;
+}
+
+/* Look up NAME in the NAMESPACE.  */
+
+tree
+lookup_namespace_name (tree namespace, tree name)
+{
+  tree val;
+  tree template_id = NULL_TREE;
+  cxx_binding binding;
+
+  timevar_push (TV_NAME_LOOKUP);
+  my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
+
+  if (TREE_CODE (name) == NAMESPACE_DECL)
+    /* This happens for A::B<int> when B is a namespace.  */
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
+  else if (TREE_CODE (name) == TEMPLATE_DECL)
+    {
+      /* This happens for A::B where B is a template, and there are no
+        template arguments.  */
+      error ("invalid use of `%D'", name);
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+    }
+
+  namespace = ORIGINAL_NAMESPACE (namespace);
+
+  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+    {
+      template_id = name;
+      name = TREE_OPERAND (name, 0);
+      if (TREE_CODE (name) == OVERLOAD)
+       name = DECL_NAME (OVL_CURRENT (name));
+      else if (DECL_P (name))
+       name = DECL_NAME (name);
+    }
+
+  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
+
+  cxx_binding_clear (&binding);
+  if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
+  if (binding.value)
+    {
+      val = binding.value;
+
+      if (template_id)
+       {
+         if (DECL_CLASS_TEMPLATE_P (val))
+           val = lookup_template_class (val,
+                                        TREE_OPERAND (template_id, 1),
+                                        /*in_decl=*/NULL_TREE,
+                                        /*context=*/NULL_TREE,
+                                        /*entering_scope=*/0,
+                                        tf_error | tf_warning);
+         else if (DECL_FUNCTION_TEMPLATE_P (val)
+                  || TREE_CODE (val) == OVERLOAD)
+           val = lookup_template_function (val,
+                                           TREE_OPERAND (template_id, 1));
+         else
+           {
+             error ("`%D::%D' is not a template",
+                       namespace, name);
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+           }
+       }
+
+      /* If we have a single function from a using decl, pull it out.  */
+      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
+       val = OVL_FUNCTION (val);
+
+      /* Ignore built-in functions that haven't been prototyped yet.  */
+      if (!val || !DECL_P(val)
+          || !DECL_LANG_SPECIFIC(val)
+          || !DECL_ANTICIPATED (val))
+        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+    }
+
+  error ("`%D' undeclared in namespace `%D'", name, namespace);
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+}
+
+/* Select the right _DECL from multiple choices.  */
+
+static tree
+select_decl (cxx_binding *binding, int flags)
+{
+  tree val;
+  val = binding->value;
+
+  timevar_push (TV_NAME_LOOKUP);
+  if (LOOKUP_NAMESPACES_ONLY (flags))
+    {
+      /* We are not interested in types.  */
+      if (val && TREE_CODE (val) == NAMESPACE_DECL)
+        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+    }
+
+  /* If looking for a type, or if there is no non-type binding, select
+     the value binding.  */
+  if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
+    val = binding->type;
+  /* Don't return non-types if we really prefer types.  */
+  else if (val && LOOKUP_TYPES_ONLY (flags)  && TREE_CODE (val) != TYPE_DECL
+          && (TREE_CODE (val) != TEMPLATE_DECL
+              || !DECL_CLASS_TEMPLATE_P (val)))
+    val = NULL_TREE;
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+}
+
+/* Unscoped lookup of a global: iterate over current namespaces,
+   considering using-directives.  If SPACESP is non-NULL, store a list
+   of the namespaces we've considered in it.  */
+
+tree
+unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
+{
+  tree initial = current_decl_namespace ();
+  tree scope = initial;
+  tree siter;
+  struct cp_binding_level *level;
+  tree val = NULL_TREE;
+  cxx_binding binding;
+
+  timevar_push (TV_NAME_LOOKUP);
+  cxx_binding_clear (&binding);
+  if (spacesp)
+    *spacesp = NULL_TREE;
+
+  for (; !val; scope = CP_DECL_CONTEXT (scope))
+    {
+      cxx_binding *b =
+         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+      if (spacesp)
+       *spacesp = tree_cons (scope, NULL_TREE, *spacesp);
+
+      /* Ignore anticipated built-in functions.  */
+      if (b && b->value && DECL_P (b->value)
+          && DECL_LANG_SPECIFIC (b->value) && DECL_ANTICIPATED (b->value))
+        /* Keep binding cleared.  */;
+      else if (b)
+        {
+          /* Initialize binding for this context.  */
+          binding.value = b->value;
+          binding.type = b->type;
+        }
+
+      /* Add all _DECLs seen through local using-directives.  */
+      for (level = current_binding_level;
+          level->kind != sk_namespace;
+          level = level->level_chain)
+       if (!lookup_using_namespace (name, &binding, level->using_directives,
+                                     scope, flags, spacesp))
+         /* Give up because of error.  */
+         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
+      /* Add all _DECLs seen through global using-directives.  */
+      /* XXX local and global using lists should work equally.  */
+      siter = initial;
+      while (1)
+       {
+         if (!lookup_using_namespace (name, &binding,
+                                       DECL_NAMESPACE_USING (siter),
+                                      scope, flags, spacesp))
+           /* Give up because of error.  */
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+         if (siter == scope) break;
+         siter = CP_DECL_CONTEXT (siter);
+       }
+
+      val = select_decl (&binding, flags);
+      if (scope == global_namespace)
+       break;
+    }
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+}
+
+/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
+   or a class TYPE).  If IS_TYPE_P is TRUE, then ignore non-type
+   bindings.  
+
+   Returns a DECL (or OVERLOAD, or BASELINK) representing the
+   declaration found.  If no suitable declaration can be found,
+   ERROR_MARK_NODE is returned.  Iif COMPLAIN is true and SCOPE is
+   neither a class-type nor a namespace a diagnostic is issued.  */
+
+tree
+lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
+{
+  int flags = 0;
+
+  if (TREE_CODE (scope) == NAMESPACE_DECL)
+    {
+      cxx_binding binding;
+
+      cxx_binding_clear (&binding);
+      flags |= LOOKUP_COMPLAIN;
+      if (is_type_p)
+       flags |= LOOKUP_PREFER_TYPES;
+      if (qualified_lookup_using_namespace (name, scope, &binding, 
+                                           flags))
+       return select_decl (&binding, flags);
+    }
+  else if (is_aggr_type (scope, complain))
+    {
+      tree t;
+      t = lookup_member (scope, name, 0, is_type_p);
+      if (t)
+       return t;
+    }
+
+  return error_mark_node;
+}
+
+/* Look up NAME in the current binding level and its superiors in the
+   namespace of variables, functions and typedefs.  Return a ..._DECL
+   node of some kind representing its definition if there is only one
+   such declaration, or return a TREE_LIST with all the overloaded
+   definitions if there are many, or return 0 if it is undefined.
+
+   If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
+   If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
+   Otherwise we prefer non-TYPE_DECLs.
+
+   If NONCLASS is nonzero, we don't look for the NAME in class scope,
+   using IDENTIFIER_CLASS_VALUE.  */
+
+tree
+lookup_name_real (tree name, int prefer_type, int nonclass, 
+                 int namespaces_only, int flags)
+{
+  cxx_binding *iter;
+  tree val = NULL_TREE;
+
+  timevar_push (TV_NAME_LOOKUP);
+  /* Conversion operators are handled specially because ordinary
+     unqualified name lookup will not find template conversion
+     operators.  */
+  if (IDENTIFIER_TYPENAME_P (name)) 
+    {
+      struct cp_binding_level *level;
+
+      for (level = current_binding_level; 
+          level && level->kind != sk_namespace;
+          level = level->level_chain)
+       {
+         tree class_type;
+         tree operators;
+         
+         /* A conversion operator can only be declared in a class 
+            scope.  */
+         if (level->kind != sk_class)
+           continue;
+         
+         /* Lookup the conversion operator in the class.  */
+         class_type = level->this_entity;
+         operators = lookup_fnfields (class_type, name, /*protect=*/0);
+         if (operators)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
+       }
+
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+    }
+
+  flags |= lookup_flags (prefer_type, namespaces_only);
+
+  /* First, look in non-namespace scopes.  */
+
+  if (current_class_type == NULL_TREE)
+    nonclass = 1;
+
+  for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
+    {
+      tree binding;
+
+      if (!LOCAL_BINDING_P (iter) && nonclass)
+       /* We're not looking for class-scoped bindings, so keep going.  */
+       continue;
+
+      /* If this is the kind of thing we're looking for, we're done.  */
+      if (qualify_lookup (iter->value, flags))
+       binding = iter->value;
+      else if ((flags & LOOKUP_PREFER_TYPES)
+              && qualify_lookup (iter->type, flags))
+       binding = iter->type;
+      else
+       binding = NULL_TREE;
+
+      if (binding)
+       {
+         val = binding;
+         break;
+       }
+    }
+
+  /* Now lookup in namespace scopes.  */
+  if (!val)
+    {
+      tree t = unqualified_namespace_lookup (name, flags, 0);
+      if (t)
+       val = t;
+    }
+
+  if (val)
+    {
+      /* If we have a single function from a using decl, pull it out.  */
+      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
+       val = OVL_FUNCTION (val);
+    }
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+}
+
+tree
+lookup_name_nonclass (tree name)
+{
+  return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN);
+}
+
+tree
+lookup_function_nonclass (tree name, tree args)
+{
+  return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
+}
+
+tree
+lookup_name (tree name, int prefer_type)
+{
+  return lookup_name_real (name, prefer_type, 0, 0, LOOKUP_COMPLAIN);
+}
+
+/* Similar to `lookup_name' but look only in the innermost non-class
+   binding level.  */
+
+tree
+lookup_name_current_level (tree name)
+{
+  struct cp_binding_level *b;
+  tree t = NULL_TREE;
+
+  timevar_push (TV_NAME_LOOKUP);
+  b = innermost_nonclass_level ();
+
+  if (b->kind == sk_namespace)
+    {
+      t = IDENTIFIER_NAMESPACE_VALUE (name);
+
+      /* extern "C" function() */
+      if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
+       t = TREE_VALUE (t);
+    }
+  else if (IDENTIFIER_BINDING (name)
+          && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
+    {
+      while (1)
+       {
+         if (IDENTIFIER_BINDING (name)->scope == b)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
+
+         if (b->kind == sk_cleanup)
+           b = b->level_chain;
+         else
+           break;
+       }
+    }
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+}
+
+/* Like lookup_name_current_level, but for types.  */
+
+tree
+lookup_type_current_level (tree name)
+{
+  register tree t = NULL_TREE;
+
+  timevar_push (TV_NAME_LOOKUP);
+  my_friendly_assert (current_binding_level->kind != sk_namespace, 
+                     980716);
+
+  if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
+      && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
+    {
+      struct cp_binding_level *b = current_binding_level;
+      while (1)
+       {
+         if (purpose_member (name, b->type_shadowed))
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+                                    REAL_IDENTIFIER_TYPE_VALUE (name));
+         if (b->kind == sk_cleanup)
+           b = b->level_chain;
+         else
+           break;
+       }
+    }
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+}
+
+/* Add namespace to using_directives. Return NULL_TREE if nothing was
+   changed (i.e. there was already a directive), or the fresh
+   TREE_LIST otherwise.  */
+
+tree
+push_using_directive (tree used)
+{
+  tree ud = current_binding_level->using_directives;
+  tree iter, ancestor;
+
+  timevar_push (TV_NAME_LOOKUP);
+  /* Check if we already have this.  */
+  if (purpose_member (used, ud) != NULL_TREE)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+
+  ancestor = namespace_ancestor (current_decl_namespace (), used);
+  ud = current_binding_level->using_directives;
+  ud = tree_cons (used, ancestor, ud);
+  current_binding_level->using_directives = ud;
+
+  /* Recursively add all namespaces used.  */
+  for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
+    push_using_directive (TREE_PURPOSE (iter));
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud);
+}
+
+/* The type TYPE is being declared.  If it is a class template, or a
+   specialization of a class template, do any processing required and
+   perform error-checking.  If IS_FRIEND is nonzero, this TYPE is
+   being declared a friend.  B is the binding level at which this TYPE
+   should be bound.
+
+   Returns the TYPE_DECL for TYPE, which may have been altered by this
+   processing.  */
+
+static tree
+maybe_process_template_type_declaration (tree type, int globalize,
+                                         cxx_scope *b)
+{
+  tree decl = TYPE_NAME (type);
+
+  if (processing_template_parmlist)
+    /* You can't declare a new template type in a template parameter
+       list.  But, you can declare a non-template type:
+
+         template <class A*> struct S;
+
+       is a forward-declaration of `A'.  */
+    ;
+  else
+    {
+      maybe_check_template_type (type);
+
+      my_friendly_assert (IS_AGGR_TYPE (type)
+                         || TREE_CODE (type) == ENUMERAL_TYPE, 0);
+
+
+      if (processing_template_decl)
+       {
+         /* This may change after the call to
+            push_template_decl_real, but we want the original value.  */
+         tree name = DECL_NAME (decl);
+
+         decl = push_template_decl_real (decl, globalize);
+         /* If the current binding level is the binding level for the
+            template parameters (see the comment in
+            begin_template_parm_list) and the enclosing level is a class
+            scope, and we're not looking at a friend, push the
+            declaration of the member class into the class scope.  In the
+            friend case, push_template_decl will already have put the
+            friend into global scope, if appropriate.  */
+         if (TREE_CODE (type) != ENUMERAL_TYPE
+             && !globalize && b->kind == sk_template_parms
+             && b->level_chain->kind == sk_class)
+           {
+             finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
+             /* Put this UDT in the table of UDTs for the class, since
+                that won't happen below because B is not the class
+                binding level, but is instead the pseudo-global level.  */
+              if (b->level_chain->type_decls == NULL)
+                b->level_chain->type_decls =
+                  binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+              binding_table_insert (b->level_chain->type_decls, name, type);
+             if (!COMPLETE_TYPE_P (current_class_type))
+               {
+                 maybe_add_class_template_decl_list (current_class_type,
+                                                     type, /*friend_p=*/0);
+                 CLASSTYPE_NESTED_UTDS (current_class_type) =
+                    b->level_chain->type_decls;
+               }
+           }
+       }
+    }
+
+  return decl;
+}
+
+/* Push a tag name NAME for struct/class/union/enum type TYPE.
+   Normally put it into the inner-most non-sk_cleanup scope,
+   but if GLOBALIZE is true, put it in the inner-most non-class scope.
+   The latter is needed for implicit declarations.  */
+
+void
+pushtag (tree name, tree type, int globalize)
+{
+  register struct cp_binding_level *b;
+
+  timevar_push (TV_NAME_LOOKUP);
+  b = current_binding_level;
+  while (b->kind == sk_cleanup
+        || (b->kind == sk_class
+            && (globalize
+                /* We may be defining a new type in the initializer
+                   of a static member variable. We allow this when
+                   not pedantic, and it is particularly useful for
+                   type punning via an anonymous union.  */
+                || COMPLETE_TYPE_P (b->this_entity))))
+    b = b->level_chain;
+
+  if (b->type_decls == NULL)
+    b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+  binding_table_insert (b->type_decls, name, type);
+
+  if (name)
+    {
+      /* Do C++ gratuitous typedefing.  */
+      if (IDENTIFIER_TYPE_VALUE (name) != type)
+        {
+          register tree d = NULL_TREE;
+         int in_class = 0;
+         tree context = TYPE_CONTEXT (type);
+
+         if (! context)
+           {
+             tree cs = current_scope ();
+
+             if (! globalize)
+               context = cs;
+             else if (cs != NULL_TREE && TYPE_P (cs))
+               /* When declaring a friend class of a local class, we want
+                  to inject the newly named class into the scope
+                  containing the local class, not the namespace scope.  */
+               context = decl_function_context (get_type_decl (cs));
+           }
+         if (!context)
+           context = current_namespace;
+
+         if (b->kind == sk_class
+             || (b->kind == sk_template_parms 
+                 && b->level_chain->kind == sk_class))
+           in_class = 1;
+
+         if (current_lang_name == lang_name_java)
+           TYPE_FOR_JAVA (type) = 1;
+
+         d = create_implicit_typedef (name, type);
+         DECL_CONTEXT (d) = FROB_CONTEXT (context);
+         if (! in_class)
+           set_identifier_type_value_with_scope (name, d, b);
+
+         d = maybe_process_template_type_declaration (type,
+                                                      globalize, b);
+
+         if (b->kind == sk_class)
+           {
+             if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+               /* Put this TYPE_DECL on the TYPE_FIELDS list for the
+                  class.  But if it's a member template class, we
+                  want the TEMPLATE_DECL, not the TYPE_DECL, so this
+                  is done later.  */
+               finish_member_declaration (d);
+             else
+               pushdecl_class_level (d);
+           }
+         else
+           d = pushdecl_with_scope (d, b);
+
+         /* FIXME what if it gets a name from typedef?  */
+         if (ANON_AGGRNAME_P (name))
+           DECL_IGNORED_P (d) = 1;
+
+         TYPE_CONTEXT (type) = DECL_CONTEXT (d);
+
+         /* If this is a local class, keep track of it.  We need this
+            information for name-mangling, and so that it is possible to find
+            all function definitions in a translation unit in a convenient
+            way.  (It's otherwise tricky to find a member function definition
+            it's only pointed to from within a local class.)  */
+         if (TYPE_CONTEXT (type)
+             && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
+             && !processing_template_decl)
+           VARRAY_PUSH_TREE (local_classes, type);
+        }
+      if (b->kind == sk_class
+         && !COMPLETE_TYPE_P (current_class_type))
+       {
+         maybe_add_class_template_decl_list (current_class_type,
+                                             type, /*friend_p=*/0);
+         CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
+       }
+    }
+
+  if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+    /* Use the canonical TYPE_DECL for this node.  */
+    TYPE_STUB_DECL (type) = TYPE_NAME (type);
+  else
+    {
+      /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
+        will be the tagged type we just added to the current
+        binding level.  This fake NULL-named TYPE_DECL node helps
+        dwarfout.c to know when it needs to output a
+        representation of a tagged type, and it also gives us a
+        convenient place to record the "scope start" address for
+        the tagged type.  */
+
+      tree d = build_decl (TYPE_DECL, NULL_TREE, type);
+      TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
+    }
+  timevar_pop (TV_NAME_LOOKUP);
+}
+\f
+/* Allocate storage for saving a C++ binding.  */
+#define cxx_saved_binding_make() \
+  (ggc_alloc (sizeof (cxx_saved_binding)))
+
+struct cxx_saved_binding GTY(())
+{
+  /* Link that chains saved C++ bindings for a given name into a stack.  */
+  cxx_saved_binding *previous;
+  /* The name of the current binding.  */
+  tree identifier;
+  /* The binding we're saving.  */
+  cxx_binding *binding;
+  tree class_value;
+  tree real_type_value;
+};
+
+/* Subroutines for reverting temporarily to top-level for instantiation
+   of templates and such.  We actually need to clear out the class- and
+   local-value slots of all identifiers, so that only the global values
+   are at all visible.  Simply setting current_binding_level to the global
+   scope isn't enough, because more binding levels may be pushed.  */
+struct saved_scope *scope_chain;
+
+static cxx_saved_binding *
+store_bindings (tree names, cxx_saved_binding *old_bindings)
+{
+  tree t;
+  cxx_saved_binding *search_bindings = old_bindings;
+
+  timevar_push (TV_NAME_LOOKUP);
+  for (t = names; t; t = TREE_CHAIN (t))
+    {
+      tree id;
+      cxx_saved_binding *saved;
+      cxx_saved_binding *t1;
+
+      if (TREE_CODE (t) == TREE_LIST)
+       id = TREE_PURPOSE (t);
+      else
+       id = DECL_NAME (t);
+
+      if (!id
+         /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
+            we have no IDENTIFIER_BINDING if we have left the class
+            scope, but cached the class-level declarations.  */
+         || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
+       continue;
+
+      for (t1 = search_bindings; t1; t1 = t1->previous)
+       if (t1->identifier == id)
+         goto skip_it;
+
+      my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
+      saved = cxx_saved_binding_make ();
+      saved->previous = old_bindings;
+      saved->identifier = id;
+      saved->binding = IDENTIFIER_BINDING (id);
+      saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
+      saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+      IDENTIFIER_BINDING (id) = NULL;
+      IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
+      old_bindings = saved;
+    skip_it:
+      ;
+    }
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
+}
+
+void
+maybe_push_to_top_level (int pseudo)
+{
+  struct saved_scope *s;
+  struct cp_binding_level *b;
+  cxx_saved_binding *old_bindings;
+  int need_pop;
+
+  timevar_push (TV_NAME_LOOKUP);
+  s = ggc_alloc_cleared (sizeof (struct saved_scope));
+
+  b = scope_chain ? current_binding_level : 0;
+
+  /* If we're in the middle of some function, save our state.  */
+  if (cfun)
+    {
+      need_pop = 1;
+      push_function_context_to (NULL_TREE);
+    }
+  else
+    need_pop = 0;
+
+  old_bindings = NULL;
+  if (scope_chain && previous_class_type)
+    old_bindings = store_bindings (previous_class_values, old_bindings);
+
+  /* Have to include the global scope, because class-scope decls
+     aren't listed anywhere useful.  */
+  for (; b; b = b->level_chain)
+    {
+      tree t;
+
+      /* Template IDs are inserted into the global level. If they were
+        inserted into namespace level, finish_file wouldn't find them
+        when doing pending instantiations. Therefore, don't stop at
+        namespace level, but continue until :: .  */
+      if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms))
+       break;
+
+      old_bindings = store_bindings (b->names, old_bindings);
+      /* We also need to check class_shadowed to save class-level type
+        bindings, since pushclass doesn't fill in b->names.  */
+      if (b->kind == sk_class)
+       old_bindings = store_bindings (b->class_shadowed, old_bindings);
+
+      /* Unwind type-value slots back to top level.  */
+      for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
+       SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
+    }
+  s->prev = scope_chain;
+  s->old_bindings = old_bindings;
+  s->bindings = b;
+  s->need_pop_function_context = need_pop;
+  s->function_decl = current_function_decl;
+  s->last_parms = last_function_parms;
+
+  scope_chain = s;
+  current_function_decl = NULL_TREE;
+  VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
+  current_lang_name = lang_name_cplusplus;
+  current_namespace = global_namespace;
+  timevar_pop (TV_NAME_LOOKUP);
+}
+
+void
+push_to_top_level (void)
+{
+  maybe_push_to_top_level (0);
+}
+
+void
+pop_from_top_level (void)
+{
+  struct saved_scope *s = scope_chain;
+  cxx_saved_binding *saved;
+
+  timevar_push (TV_NAME_LOOKUP); 
+  /* Clear out class-level bindings cache.  */
+  if (previous_class_type)
+    invalidate_class_lookup_cache ();
+
+  current_lang_base = 0;
+
+  scope_chain = s->prev;
+  for (saved = s->old_bindings; saved; saved = saved->previous)
+    {
+      tree id = saved->identifier;
+
+      IDENTIFIER_BINDING (id) = saved->binding;
+      IDENTIFIER_CLASS_VALUE (id) = saved->class_value;
+      SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
+    }
+
+  /* If we were in the middle of compiling a function, restore our
+     state.  */
+  if (s->need_pop_function_context)
+    pop_function_context_from (NULL_TREE);
+  current_function_decl = s->function_decl;
+  last_function_parms = s->last_parms;
+  timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Pop off extraneous binding levels left over due to syntax errors.
+
+   We don't pop past namespaces, as they might be valid.  */
+
+void
+pop_everything (void)
+{
+  if (ENABLE_SCOPE_CHECKING)
+    verbatim ("XXX entering pop_everything ()\n");
+  while (!toplevel_bindings_p ())
+    {
+      if (current_binding_level->kind == sk_class)
+       pop_nested_class ();
+      else
+       poplevel (0, 0, 0);
+    }
+  if (ENABLE_SCOPE_CHECKING)
+    verbatim ("XXX leaving pop_everything ()\n");
+}
+
 #include "gt-cp-name-lookup.h"
index 15f1936..7153cbe 100644 (file)
@@ -46,12 +46,6 @@ struct binding_entry_s GTY(())
 #define NAMESPACE_STD_HT_SIZE                        (1 << 8)
 #define GLOBAL_SCOPE_HT_SIZE                         (1 << 8)
 
-extern binding_table binding_table_new (size_t);
-extern void binding_table_free (binding_table);
-extern void binding_table_insert (binding_table, tree, tree);
-extern tree binding_table_find_anon_type (binding_table, tree);
-extern binding_entry binding_table_reverse_maybe_remap (binding_table,
-                                                        tree, tree);
 extern void binding_table_remove_anonymous_types (binding_table);
 extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
 extern binding_entry binding_table_find (binding_table, tree);
@@ -93,9 +87,10 @@ struct cxx_binding GTY(())
   unsigned is_local : 1;
 };
 
-extern cxx_binding *cxx_binding_make (tree, tree);
-extern void cxx_binding_free (cxx_binding *);
-extern bool supplement_binding (cxx_binding *, tree);
+extern tree identifier_type_value (tree);
+extern void set_identifier_type_value (tree, tree);
+extern void pop_binding (tree, tree);
+extern void clear_identifier_class_values (void);
 \f
 /* The kinds of scopes we recognize.  */
 typedef enum scope_kind {
@@ -246,16 +241,66 @@ struct cp_binding_level GTY(())
 
 /* The tree node representing the global scope.  */
 extern GTY(()) tree global_namespace;
+extern GTY(()) tree global_scope_name;
+
+/* Indicates that there is a type value in some namespace, although
+   that is not necessarily in scope at the moment.  */
+
+extern GTY(()) tree global_type_node;
 
 /* True if SCOPE designates the global scope binding contour.  */
 #define global_scope_p(SCOPE) \
   ((SCOPE) == NAMESPACE_LEVEL (global_namespace))
 
+extern cxx_scope *leave_scope (void);
+extern bool kept_level_p (void);
+extern int global_bindings_p (void);
+extern bool toplevel_bindings_p        (void);
+extern bool namespace_bindings_p (void);
+extern bool template_parm_scope_p (void);
+extern scope_kind innermost_scope_kind (void);
+extern cxx_scope *begin_scope (scope_kind, tree);
+extern void print_binding_stack        (void);
+extern void print_binding_level        (cxx_scope *);
+extern void push_to_top_level (void);
+extern void pop_from_top_level (void);
+extern void maybe_push_to_top_level (int);
+extern void pop_everything (void);
+extern void keep_next_level (bool);
+\f
+extern void push_namespace (tree);
+extern void pop_namespace (void);
+extern void push_nested_namespace (tree);
+extern void pop_nested_namespace (tree);
+extern tree push_using_directive (tree);
+extern void pushlevel_class (void);
+extern void poplevel_class (void);
 extern cxx_binding *cxx_scope_find_binding_for_name (cxx_scope *, tree);
 extern cxx_binding *binding_for_name (cxx_scope *, tree);
-\f
+extern tree pushdecl_with_scope (tree, cxx_scope *);
+extern tree lookup_tag (enum tree_code, tree, cxx_scope *, int);
+extern tree lookup_tag_reverse (tree, tree);
+extern tree lookup_name        (tree, int);
+extern tree lookup_name_real (tree, int, int, int, int);
+extern tree lookup_name_current_level (tree);
+extern tree lookup_type_current_level (tree);
 extern tree namespace_binding (tree, tree);
+extern void add_decl_to_level (tree, cxx_scope *);
 extern void set_namespace_binding (tree, tree, tree);
+extern tree lookup_namespace_name (tree, tree);
+extern tree unqualified_namespace_lookup (tree, int, tree *);
+extern tree lookup_qualified_name (tree, tree, bool, bool);
+extern tree lookup_name_nonclass (tree);
+extern tree lookup_function_nonclass (tree, tree);
+extern void push_local_binding (tree, tree, int);
+extern int push_class_binding (tree, tree);
+extern bool pushdecl_class_level (tree);
+extern tree pushdecl_namespace_level (tree);
+extern bool push_class_level_binding (tree, tree);
+extern void storetags (tree);
+extern tree getdecls (void);
+extern tree cp_namespace_decls (tree);
+extern void set_class_shadows (tree);
 
 
 /* Set *DECL to the (non-hidden) declaration for ID at global scope,