OSDN Git Service

PR c++/10428
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 1e26b0f..84e267e 100644 (file)
@@ -1,27 +1,27 @@
-/* Process declarations and variables for C compiler.
+/* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002  Free Software Foundation, Inc.
+   2001, 2002, 2003  Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
+along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
-/* Process declarations and symbol lookup for C front end.
+/* Process declarations and symbol lookup for C++ front end.
    Also constructs types; the standard scalar types at initialization,
    and structure, union, array and enum types when they are declared.  */
 
@@ -30,6 +30,8 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "rtl.h"
 #include "expr.h"
@@ -42,113 +44,112 @@ Boston, MA 02111-1307, USA.  */
 #include "except.h"
 #include "toplev.h"
 #include "hashtab.h"
-#include "ggc.h"
 #include "tm_p.h"
 #include "target.h"
 #include "c-common.h"
 #include "c-pragma.h"
 #include "diagnostic.h"
 #include "debug.h"
-
-static tree grokparms                          PARAMS ((tree));
-static const char *redeclaration_error_message PARAMS ((tree, tree));
-
-static void push_binding_level PARAMS ((struct cp_binding_level *, int,
-                                     int));
-static void pop_binding_level PARAMS ((void));
-static void suspend_binding_level PARAMS ((void));
-static void resume_binding_level PARAMS ((struct cp_binding_level *));
-static struct cp_binding_level *make_binding_level PARAMS ((void));
-static void declare_namespace_level PARAMS ((void));
-static int decl_jump_unsafe PARAMS ((tree));
-static void storedecls PARAMS ((tree));
-static void require_complete_types_for_parms PARAMS ((tree));
-static int ambi_op_p PARAMS ((enum tree_code));
-static int unary_op_p PARAMS ((enum tree_code));
-static tree store_bindings PARAMS ((tree, tree));
-static tree lookup_tag_reverse PARAMS ((tree, tree));
-static tree lookup_name_real PARAMS ((tree, int, int, int));
-static void push_local_name PARAMS ((tree));
-static void warn_extern_redeclared_static PARAMS ((tree, tree));
-static tree grok_reference_init PARAMS ((tree, tree, tree));
-static tree grokfndecl PARAMS ((tree, tree, tree, tree, int,
-                             enum overload_flags, tree,
-                             tree, int, int, int, int, int, int, tree));
-static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree));
-static tree follow_tag_typedef PARAMS ((tree));
-static tree lookup_tag PARAMS ((enum tree_code, tree,
-                             struct cp_binding_level *, int));
+#include "timevar.h"
+
+static tree grokparms (tree);
+static const char *redeclaration_error_message (tree, tree);
+
+static void push_binding_level (struct cp_binding_level *, int,
+                               int);
+static void pop_binding_level (void);
+static void suspend_binding_level (void);
+static void resume_binding_level (struct cp_binding_level *);
+static struct cp_binding_level *make_binding_level (void);
+static void declare_namespace_level (void);
+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);
+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
-       PARAMS ((tree, tree, struct cp_binding_level *));
-static void record_unknown_type PARAMS ((tree, const char *));
-static tree builtin_function_1 PARAMS ((const char *, tree, tree, int,
-                                      enum built_in_class, const char *,
-                                     tree));
-static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
-static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
-static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
-                                 int));
-static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct cp_binding_level*));
-static void check_for_uninitialized_const_var PARAMS ((tree));
-static hashval_t typename_hash PARAMS ((const void *));
-static int typename_compare PARAMS ((const void *, const void *));
-static void push_binding PARAMS ((tree, tree, struct cp_binding_level*));
-static int add_binding PARAMS ((tree, tree));
-static void pop_binding PARAMS ((tree, tree));
-static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *));
-static tree find_binding PARAMS ((tree, tree));
-static tree select_decl PARAMS ((tree, int));
-static int lookup_flags PARAMS ((int, int));
-static tree qualify_lookup PARAMS ((tree, int));
-static tree record_builtin_java_type PARAMS ((const char *, int));
-static const char *tag_name PARAMS ((enum tag_types code));
-static void find_class_binding_level PARAMS ((void));
-static struct cp_binding_level *innermost_nonclass_level PARAMS ((void));
-static void warn_about_implicit_typename_lookup PARAMS ((tree, tree));
-static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *));
-static int walk_globals_r PARAMS ((tree, void *));
-static int walk_vtables_r PARAMS ((tree, void*));
-static void add_decl_to_level PARAMS ((tree, struct cp_binding_level *));
-static tree make_label_decl PARAMS ((tree, int));
-static void use_label PARAMS ((tree));
-static void check_previous_goto_1 PARAMS ((tree, struct cp_binding_level *, tree,
-                                          const char *, int));
-static void check_previous_goto PARAMS ((struct named_label_use_list *));
-static void check_switch_goto PARAMS ((struct cp_binding_level *));
-static void check_previous_gotos PARAMS ((tree));
-static void pop_label PARAMS ((tree, tree));
-static void pop_labels PARAMS ((tree));
-static void maybe_deduce_size_from_array_init PARAMS ((tree, tree));
-static void layout_var_decl PARAMS ((tree));
-static void maybe_commonize_var PARAMS ((tree));
+       (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 *,
+                               tree);
+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 int add_binding (tree, tree);
+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 void find_class_binding_level (void);
+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,
+                                  const char *, int);
+static void check_previous_goto (struct named_label_use_list *);
+static void check_switch_goto (struct cp_binding_level *);
+static void check_previous_gotos (tree);
+static void pop_label (tree, tree);
+static void pop_labels (tree);
+static void maybe_deduce_size_from_array_init (tree, tree);
+static void layout_var_decl (tree);
+static void maybe_commonize_var (tree);
 static tree check_initializer (tree, tree, int);
-static void make_rtl_for_nonlocal_decl PARAMS ((tree, tree, const char *));
-static void save_function_data PARAMS ((tree));
-static void check_function_type PARAMS ((tree, tree));
-static void begin_constructor_body PARAMS ((void));
-static void finish_constructor_body PARAMS ((void));
-static void begin_destructor_body PARAMS ((void));
-static void finish_destructor_body PARAMS ((void));
-static tree create_array_type_for_decl PARAMS ((tree, tree, tree));
-static tree get_atexit_node PARAMS ((void));
-static tree get_dso_handle_node PARAMS ((void));
-static tree start_cleanup_fn PARAMS ((void));
-static void end_cleanup_fn PARAMS ((void));
-static tree cp_make_fname_decl PARAMS ((tree, int));
-static void initialize_predefined_identifiers PARAMS ((void));
-static tree check_special_function_return_type
-  PARAMS ((special_function_kind, tree, tree));
-static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
-static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
-static void store_parm_decls PARAMS ((tree));
-static int cp_missing_noreturn_ok_p PARAMS ((tree));
+static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
+static void save_function_data (tree);
+static void check_function_type (tree, tree);
+static void begin_constructor_body (void);
+static void finish_constructor_body (void);
+static void begin_destructor_body (void);
+static void finish_destructor_body (void);
+static tree create_array_type_for_decl (tree, tree, tree);
+static tree get_atexit_node (void);
+static tree get_dso_handle_node (void);
+static tree start_cleanup_fn (void);
+static void end_cleanup_fn (void);
+static tree cp_make_fname_decl (tree, int);
+static void initialize_predefined_identifiers (void);
+static tree check_special_function_return_type 
+       (special_function_kind, tree, tree);
+static tree push_cp_library_fn (enum tree_code, tree);
+static tree build_cp_library_fn (tree, enum tree_code, tree);
+static void store_parm_decls (tree);
+static int cp_missing_noreturn_ok_p (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
 static tree next_initializable_field (tree);
 static tree reshape_init (tree, tree *);
+static tree build_typename_type (tree, tree, tree);
 
 #if defined (DEBUG_BINDING_LEVELS)
-static void indent PARAMS ((void));
+static void indent (void);
 #endif
 
 /* Erroneous argument lists can use this *IFF* they do not modify it.  */
@@ -206,9 +207,6 @@ tree cp_global_trees[CPTI_MAX];
 
 static GTY(()) tree global_type_node;
 
-/* Expect only namespace names now.  */
-static int only_namespace_names;
-
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
@@ -328,6 +326,9 @@ struct cp_binding_level GTY(())
     /* A chain of NAMESPACE_DECL nodes.  */
     tree namespaces;
 
+    /* An array of static functions and variables (for namespaces only) */
+    varray_type static_decls;
+
     /* A chain of VTABLE_DECL nodes.  */
     tree vtables; 
 
@@ -433,9 +434,9 @@ struct cp_binding_level GTY(())
 /* The binding level currently in effect.  */
 
 #define current_binding_level                  \
-  (cfun && cp_function_chain->bindings         \
-   ? cp_function_chain->bindings               \
-   : scope_chain->bindings)
+  (*(cfun && cp_function_chain->bindings       \
+   ? &cp_function_chain->bindings              \
+   : &scope_chain->bindings))
 
 /* The binding level of the current class, if any.  */
 
@@ -466,7 +467,7 @@ static int binding_depth = 0;
 static int is_class_level = 0;
 
 static void
-indent ()
+indent (void)
 {
   register unsigned i;
 
@@ -475,12 +476,12 @@ indent ()
 }
 #endif /* defined(DEBUG_BINDING_LEVELS) */
 
-static tree pushdecl_with_scope        PARAMS ((tree, struct cp_binding_level *));
+static tree pushdecl_with_scope        (tree, struct cp_binding_level *);
 
 static void
-push_binding_level (newlevel, tag_transparent, keep)
-     struct cp_binding_level *newlevel;
-     int tag_transparent, keep;
+push_binding_level (struct cp_binding_level *newlevel, 
+                    int tag_transparent, 
+                    int keep)
 {
   /* Add this level to the front of the chain (stack) of levels that
      are active.  */
@@ -505,7 +506,7 @@ push_binding_level (newlevel, tag_transparent, keep)
    CLASS_BINDING_LEVEL appropriately.  */
 
 static void
-find_class_binding_level ()
+find_class_binding_level (void)
 {
   struct cp_binding_level *level = current_binding_level;
 
@@ -518,7 +519,7 @@ find_class_binding_level ()
 }
 
 static void
-pop_binding_level ()
+pop_binding_level (void)
 {
   if (global_binding_level)
     {
@@ -554,7 +555,7 @@ pop_binding_level ()
 }
 
 static void
-suspend_binding_level ()
+suspend_binding_level (void)
 {
   if (class_binding_level)
     current_binding_level = class_binding_level;
@@ -584,8 +585,7 @@ suspend_binding_level ()
 }
 
 static void
-resume_binding_level (b)
-     struct cp_binding_level *b;
+resume_binding_level (struct cp_binding_level* b)
 {
   /* Resuming binding levels is meant only for namespaces,
      and those cannot nest into classes.  */
@@ -607,7 +607,7 @@ resume_binding_level (b)
 
 static
 struct cp_binding_level *
-make_binding_level ()
+make_binding_level (void)
 {
   /* NOSTRICT */
   return (struct cp_binding_level *) ggc_alloc (sizeof (struct cp_binding_level));
@@ -616,7 +616,7 @@ make_binding_level ()
 /* Nonzero if we are currently in the global binding level.  */
 
 int
-global_bindings_p ()
+global_bindings_p (void)
 {
   return current_binding_level == global_binding_level;
 }
@@ -624,7 +624,7 @@ global_bindings_p ()
 /* Return the innermost binding level that is not for a class scope.  */
 
 static struct cp_binding_level *
-innermost_nonclass_level ()
+innermost_nonclass_level (void)
 {
   struct cp_binding_level *b;
 
@@ -642,7 +642,7 @@ innermost_nonclass_level ()
    also include a class whose context is toplevel.  */
 
 int
-toplevel_bindings_p ()
+toplevel_bindings_p (void)
 {
   struct cp_binding_level *b = innermost_nonclass_level ();
 
@@ -654,7 +654,7 @@ toplevel_bindings_p ()
    such a class, etc.  */
 
 int
-namespace_bindings_p ()
+namespace_bindings_p (void)
 {
   struct cp_binding_level *b = innermost_nonclass_level ();
 
@@ -666,8 +666,7 @@ namespace_bindings_p ()
    or not to create a BLOCK.  */
 
 void
-keep_next_level (keep)
-     int keep;
+keep_next_level (int keep)
 {
   keep_next_level_flag = keep;
 }
@@ -675,7 +674,7 @@ keep_next_level (keep)
 /* Nonzero if the current level needs to have a BLOCK made.  */
 
 int
-kept_level_p ()
+kept_level_p (void)
 {
   return (current_binding_level->blocks != NULL_TREE
          || current_binding_level->keep
@@ -685,7 +684,7 @@ kept_level_p ()
 }
 
 static void
-declare_namespace_level ()
+declare_namespace_level (void)
 {
   current_binding_level->namespace_p = 1;
 }
@@ -694,7 +693,7 @@ declare_namespace_level ()
    parameters.  */
 
 int
-template_parm_scope_p ()
+template_parm_scope_p (void)
 {
   return current_binding_level->template_parms_p;
 }
@@ -704,8 +703,7 @@ template_parm_scope_p ()
    explicit scope qualifications.  */
 
 tmpl_spec_kind
-current_tmpl_spec_kind (n_class_scopes)
-     int n_class_scopes;
+current_tmpl_spec_kind (int n_class_scopes)
 {
   int n_template_parm_scopes = 0;
   int seen_specialization_p = 0;
@@ -789,8 +787,7 @@ current_tmpl_spec_kind (n_class_scopes)
 }
 
 void
-set_class_shadows (shadows)
-     tree shadows;
+set_class_shadows (tree shadows)
 {
   class_binding_level->class_shadowed = shadows;
 }
@@ -800,8 +797,7 @@ set_class_shadows (shadows)
    not for that of tags.  */
 
 void
-pushlevel (tag_transparent)
-     int tag_transparent;
+pushlevel (int tag_transparent)
 {
   struct cp_binding_level *newlevel;
 
@@ -830,8 +826,7 @@ pushlevel (tag_transparent)
    scope, create a new binding level.  */
 
 void
-maybe_push_cleanup_level (type)
-     tree type;
+maybe_push_cleanup_level (tree type)
 {
   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
       && current_binding_level->more_cleanups_ok == 0)
@@ -847,13 +842,27 @@ maybe_push_cleanup_level (type)
    created.  */
 
 void
-begin_scope (sk)
-     scope_kind sk;
+begin_scope (scope_kind sk)
 {
   pushlevel (0);
 
   switch (sk)
     {
+    case sk_block:
+      break;
+
+    case sk_try:
+      current_binding_level->is_try_scope = 1;
+      break;
+
+    case sk_catch:
+      current_binding_level->is_catch_scope = 1;
+      break;
+
+    case sk_for:
+      current_binding_level->is_for_scope = 1;
+      break;
+
     case sk_template_spec:
       current_binding_level->template_spec_p = 1;
       /* Fall through.  */
@@ -870,72 +879,26 @@ begin_scope (sk)
 /* Exit the current scope.  */
 
 void
-finish_scope ()
+finish_scope (void)
 {
   poplevel (0, 0, 0);
 }
 
-void
-note_level_for_for ()
-{
-  current_binding_level->is_for_scope = 1;
-}
-
-/* Record that the current binding level represents a try block.  */
-
-void
-note_level_for_try ()
-{
-  current_binding_level->is_try_scope = 1;
-}
-
-/* Record that the current binding level represents a catch block.  */
-
-void
-note_level_for_catch ()
-{
-  current_binding_level->is_catch_scope = 1;
-}
-
-/* For a binding between a name and an entity at a block scope,
-   this is the `struct cp_binding_level' for the block.  */
-#define BINDING_LEVEL(NODE) \
-  (((struct tree_binding*)(NODE))->scope.level)
-
-/* A free list of CPLUS_BINDING nodes, connected by their
-   TREE_CHAINs.  */
-
-static GTY((deletable (""))) tree free_bindings;
-
 /* Make DECL the innermost binding for ID.  The LEVEL is the binding
    level at which this declaration is being bound.  */
 
 static void
-push_binding (id, decl, level)
-     tree id;
-     tree decl;
-     struct cp_binding_level* level;
+push_binding (tree id, tree decl, cxx_scope* level)
 {
-  tree binding;
-
-  if (free_bindings)
-    {
-      binding = free_bindings;
-      free_bindings = TREE_CHAIN (binding);
-    }
-  else
-    binding = make_node (CPLUS_BINDING);
+   cxx_binding *binding = cxx_binding_make (decl, NULL);
 
   /* Now, fill in the binding information.  */
-  BINDING_VALUE (binding) = decl;
-  BINDING_TYPE (binding) = NULL_TREE;
-  BINDING_LEVEL (binding) = level;
+  binding->previous = IDENTIFIER_BINDING (id);
+  BINDING_SCOPE (binding) = level;
   INHERITED_VALUE_BINDING_P (binding) = 0;
   LOCAL_BINDING_P (binding) = (level != class_binding_level);
-  BINDING_HAS_LEVEL_P (binding) = 1;
 
   /* And put it on the front of the list of bindings for ID.  */
-  TREE_CHAIN (binding) = IDENTIFIER_BINDING (id);
   IDENTIFIER_BINDING (id) = binding;
 }
 
@@ -946,13 +909,12 @@ push_binding (id, decl, level)
    responsibility of the caller to check that inserting this name is
    valid here.  Returns nonzero if the new binding was successful.  */
 static int
-add_binding (id, decl)
-     tree id;
-     tree decl;
+add_binding (tree id, tree decl)
 {
-  tree binding = IDENTIFIER_BINDING (id);
+  cxx_binding *binding = IDENTIFIER_BINDING (id);
   int ok = 1;
 
+  timevar_push (TV_NAME_LOOKUP);
   if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
     /* The new name is the type name.  */
     BINDING_TYPE (binding) = decl;
@@ -1009,15 +971,14 @@ add_binding (id, decl)
       ok = 0;
     }
 
-  return ok;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
 }
 
 /* Add DECL to the list of things declared in B.  */
 
 static void
-add_decl_to_level (decl, b)
-     tree decl;
-     struct cp_binding_level *b;
+add_decl_to_level (tree decl, 
+                   struct cp_binding_level* b)
 {
   if (TREE_CODE (decl) == NAMESPACE_DECL 
       && !DECL_NAMESPACE_ALIAS (decl))
@@ -1037,6 +998,13 @@ add_decl_to_level (decl, b)
       TREE_CHAIN (decl) = b->names;
       b->names = decl;
       b->names_size++;
+
+      /* If appropriate, add decl to separate list of statics */
+      if (b->namespace_p)
+       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);
     }
 }
 
@@ -1046,10 +1014,7 @@ add_decl_to_level (decl, b)
    through a using-declaration.  */
 
 void
-push_local_binding (id, decl, flags)
-     tree id;
-     tree decl;
-     int flags;
+push_local_binding (tree id, tree decl, int flags)
 {
   struct cp_binding_level *b;
 
@@ -1087,20 +1052,19 @@ push_local_binding (id, decl, flags)
    binding was successful.  */
 
 int
-push_class_binding (id, decl)
-     tree id;
-     tree decl;
+push_class_binding (tree id, tree decl)
 {
   int result = 1;
-  tree binding = IDENTIFIER_BINDING (id);
+  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_LEVEL (binding) == class_binding_level)
+  if (binding && BINDING_SCOPE (binding) == class_binding_level)
     /* Supplement the existing binding.  */
     result = add_binding (id, decl);
   else
@@ -1118,27 +1082,18 @@ push_class_binding (id, decl)
   binding = IDENTIFIER_BINDING (id);
   if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST)
     {
-      /* Any implicit typename must be from a base-class.  The
-        context for an implicit typename declaration is always
-        the derived class in which the lookup was done, so the checks
-        based on the context of DECL below will not trigger.  */
-      if (IMPLICIT_TYPENAME_TYPE_DECL_P (decl))
-       INHERITED_VALUE_BINDING_P (binding) = 1;
+      if (TREE_CODE (decl) == OVERLOAD)
+       context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
       else
        {
-         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;
+         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 (binding) == decl)
     /* We only encounter a TREE_LIST when push_class_decls detects an
@@ -1146,18 +1101,16 @@ push_class_binding (id, decl)
        in this class.  */
     INHERITED_VALUE_BINDING_P (binding) = 1;
 
-  return result;
+  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 (id, decl)
-     tree id;
-     tree decl;
+pop_binding (tree id, tree decl)
 {
-  tree binding;
+  cxx_binding *binding;
 
   if (id == NULL_TREE)
     /* It's easiest to write the loops that call this function without
@@ -1169,7 +1122,7 @@ pop_binding (id, decl)
   binding = IDENTIFIER_BINDING (id);
 
   /* The name should be bound.  */
-  my_friendly_assert (binding != NULL_TREE, 0);
+  my_friendly_assert (binding != NULL, 0);
 
   /* The DECL will be either the ordinary binding or the type
      binding for this identifier.  Remove that binding.  */
@@ -1184,15 +1137,14 @@ pop_binding (id, decl)
     {
       /* We're completely done with the innermost binding for this
         identifier.  Unhook it from the list of bindings.  */
-      IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+      IDENTIFIER_BINDING (id) = binding->previous;
 
       /* Add it to the free list.  */
-      TREE_CHAIN (binding) = free_bindings;
-      free_bindings = binding;
+      cxx_binding_free (binding);
 
-      /* Clear the BINDING_LEVEL so the garbage collector doesn't walk
+      /* Clear the BINDING_SCOPE so the garbage collector doesn't walk
         it.  */
-      BINDING_LEVEL (binding) = NULL;
+      BINDING_SCOPE (binding) = NULL;
     }
 }
 
@@ -1200,9 +1152,7 @@ pop_binding (id, decl)
    in a valid manner, and issue any appropriate warnings or errors.  */
 
 static void
-pop_label (label, old_value)
-     tree label;
-     tree old_value;
+pop_label (tree label, tree old_value)
 {
   if (!processing_template_decl && doing_semantic_analysis_p ())
     {
@@ -1224,8 +1174,7 @@ pop_label (label, old_value)
    function.  */
 
 static void
-pop_labels (block)
-     tree block;
+pop_labels (tree block)
 {
   struct named_label_list *link;
 
@@ -1259,10 +1208,7 @@ pop_labels (block)
    them into the BLOCK.  */
 
 tree
-poplevel (keep, reverse, functionbody)
-     int keep;
-     int reverse;
-     int functionbody;
+poplevel (int keep, int reverse, int functionbody)
 {
   register tree link;
   /* The chain of decls was accumulated in reverse order.
@@ -1276,8 +1222,9 @@ poplevel (keep, reverse, functionbody)
   tree decl;
   int leaving_for_scope;
 
+  timevar_push (TV_NAME_LOOKUP);
   if (cfun && !doing_semantic_analysis_p ())
-    return NULL_TREE;
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
 
   my_friendly_assert (current_binding_level->parm_flag != 2,
                      19990916);
@@ -1393,7 +1340,7 @@ poplevel (keep, reverse, functionbody)
 
   /* We still support the old for-scope rules, whereby the variables
      in a for-init statement were in scope after the for-statement
-     ended.  We only use the new rules in flag_new_for_scope is
+     ended.  We only use the new rules if flag_new_for_scope is
      nonzero.  */
   leaving_for_scope
     = current_binding_level->is_for_scope && flag_new_for_scope == 1;
@@ -1404,8 +1351,8 @@ poplevel (keep, reverse, functionbody)
       if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
           && DECL_NAME (link))
        {
-         tree outer_binding
-           = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link)));
+         cxx_binding *outer_binding
+           = IDENTIFIER_BINDING (DECL_NAME (link))->previous;
          tree ns_binding;
 
          if (!outer_binding)
@@ -1414,7 +1361,7 @@ poplevel (keep, reverse, functionbody)
            ns_binding = NULL_TREE;
 
          if (outer_binding
-             && (BINDING_LEVEL (outer_binding)
+             && (BINDING_SCOPE (outer_binding)
                  == current_binding_level->level_chain))
            /* We have something like:
 
@@ -1460,10 +1407,9 @@ poplevel (keep, reverse, functionbody)
                             current_binding_level->level_chain->
                             dead_vars_from_for);
 
-             /* Although we don't pop the CPLUS_BINDING, we do clear
-                its BINDING_LEVEL since the level is going away now.  */
-             BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link)))
-               = 0;
+             /* Although we don't pop the cxx_binding, we do clear
+                its BINDING_SCOPE since the level is going away now.  */
+             BINDING_SCOPE (IDENTIFIER_BINDING (DECL_NAME (link))) = 0;
            }
        }
       else
@@ -1568,7 +1514,7 @@ poplevel (keep, reverse, functionbody)
       block = poplevel (keep, reverse, functionbody);
     }
 
-  return block;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);
 }
 
 /* Delete the node BLOCK from the current binding level.
@@ -1576,8 +1522,7 @@ poplevel (keep, reverse, functionbody)
    so that the block can be reinserted where appropriate.  */
 
 void
-delete_block (block)
-     tree block;
+delete_block (tree block)
 {
   tree t;
   if (current_binding_level->blocks == block)
@@ -1600,8 +1545,7 @@ delete_block (block)
    to handle the BLOCK node inside the BIND_EXPR.  */
 
 void
-insert_block (block)
-     tree block;
+insert_block (tree block)
 {
   TREE_USED (block) = 1;
   current_binding_level->blocks
@@ -1612,8 +1556,7 @@ insert_block (block)
    (the one we are currently in).  */
 
 void
-set_block (block)
-    tree block ATTRIBUTE_UNUSED;
+set_block (tree block ATTRIBUTE_UNUSED )
 {
   /* The RTL expansion machinery requires us to provide this callback,
      but it is not applicable in function-at-a-time mode.  */
@@ -1623,7 +1566,7 @@ set_block (block)
 /* Do a pushlevel for class declarations.  */
 
 void
-pushlevel_class ()
+pushlevel_class (void)
 {
   register struct cp_binding_level *newlevel;
 
@@ -1654,11 +1597,12 @@ pushlevel_class ()
 /* ...and a poplevel for class declarations.  */
 
 void
-poplevel_class ()
+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
@@ -1687,15 +1631,15 @@ poplevel_class ()
             shadowed;
             shadowed = TREE_CHAIN (shadowed))
          {
-           tree t;
-
-           t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
-           while (t && BINDING_LEVEL (t) != b)
-             t = TREE_CHAIN (t);
+           cxx_binding *binding;
+            
+           binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
+           while (binding && BINDING_SCOPE (binding) != b)
+             binding = binding->previous;
 
-           if (t)
+           if (binding)
              IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
-               = BINDING_VALUE (t);
+               = BINDING_VALUE (binding);
          }
     }
   else
@@ -1723,13 +1667,14 @@ poplevel_class ()
 #endif /* defined(DEBUG_BINDING_LEVELS) */
 
   pop_binding_level ();
+  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 ()
+clear_identifier_class_values (void)
 {
   tree t;
 
@@ -1745,9 +1690,7 @@ clear_identifier_class_values ()
 /* Returns nonzero if T is a virtual function table.  */
 
 int
-vtable_decl_p (t, data)
-     tree t;
-     void *data ATTRIBUTE_UNUSED;
+vtable_decl_p (tree t, void* data ATTRIBUTE_UNUSED )
 {
   return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t));
 }
@@ -1756,9 +1699,7 @@ vtable_decl_p (t, data)
    functions.  */
 
 int
-vtype_decl_p (t, data)
-     tree t;
-     void *data ATTRIBUTE_UNUSED;
+vtype_decl_p (tree t, void *data ATTRIBUTE_UNUSED )
 {
   return (TREE_CODE (t) == TYPE_DECL
          && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
@@ -1768,8 +1709,7 @@ vtype_decl_p (t, data)
 /* Return the declarations that are members of the namespace NS.  */
 
 tree
-cp_namespace_decls (ns)
-     tree ns;
+cp_namespace_decls (tree ns)
 {
   return NAMESPACE_LEVEL (ns)->names;
 }
@@ -1785,9 +1725,7 @@ struct walk_globals_data {
    to F returns a nonzero value, return a nonzero value.  */
 
 static int
-walk_vtables_r (namespace, data)
-     tree namespace;
-     void *data;
+walk_vtables_r (tree namespace, void* data)
 {
   struct walk_globals_data* wgd = (struct walk_globals_data *) data;
   walk_globals_fn f = wgd->f;
@@ -1804,11 +1742,8 @@ walk_vtables_r (namespace, data)
 /* Walk the vtable declarations.  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.  */
-int
-walk_vtables (p, f, data)
-     walk_globals_pred p;
-     walk_globals_fn f;
-     void *data;
+bool
+walk_vtables (walk_globals_pred p, walk_globals_fn f, void *data)
 {    
   struct walk_globals_data wgd;
   wgd.p = p;    
@@ -1822,10 +1757,7 @@ walk_vtables (p, f, data)
    itself, calling F for each.  The DATA is passed to F as well.  */
 
 static int
-walk_namespaces_r (namespace, f, data)
-     tree namespace;
-     walk_namespaces_fn f;
-     void *data;
+walk_namespaces_r (tree namespace, walk_namespaces_fn f, void* data)
 {
   int result = 0;
   tree current = NAMESPACE_LEVEL (namespace)->namespaces;     
@@ -1842,9 +1774,7 @@ walk_namespaces_r (namespace, f, data)
    F as well.  */
 
 int
-walk_namespaces (f, data)
-     walk_namespaces_fn f;
-     void *data;
+walk_namespaces (walk_namespaces_fn f, void* data)
 {
   return walk_namespaces_r (global_namespace, f, data);
 }
@@ -1854,9 +1784,7 @@ walk_namespaces (f, data)
    to F returns a nonzero value, return a nonzero value.  */
 
 static int
-walk_globals_r (namespace, data)
-     tree namespace;
-     void *data;
+walk_globals_r (tree namespace, void* data)
 {
   struct walk_globals_data* wgd = (struct walk_globals_data *) data;
   walk_globals_pred p = wgd->p;
@@ -1884,14 +1812,11 @@ walk_globals_r (namespace, data)
 }
 
 /* Walk the global declarations.  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.  */
+   returns true, call F with its address.  If any call to F
+   returns true, return true.  */
 
-int
-walk_globals (p, f, data)
-     walk_globals_pred p;
-     walk_globals_fn f;
-     void *data;
+bool
+walk_globals (walk_globals_pred p, walk_globals_fn f, void *data)
 {
   struct walk_globals_data wgd;
   wgd.p = p;
@@ -1906,27 +1831,14 @@ walk_globals (p, f, data)
    wrapup_global_declarations for this NAMESPACE.  */
 
 int
-wrapup_globals_for_namespace (namespace, data)
-     tree namespace;
-     void *data;
+wrapup_globals_for_namespace (tree namespace, void* data)
 {
-  tree globals = cp_namespace_decls (namespace);
-  int len = NAMESPACE_LEVEL (namespace)->names_size;
-  tree *vec = (tree *) alloca (sizeof (tree) * len);
-  int i;
-  int result;
-  tree decl;
+  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 && namespace == global_namespace)
-    /* Let compile_file handle the global namespace.  */
-    return 0;
-
-  /* Process the decls in reverse order--earliest first.
-     Put them into VEC from back to front, then take out from front.  */       
-  for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
-    vec[len - i - 1] = decl;
-
   if (last_time)
     {
       check_global_declarations (vec, len);
@@ -1934,9 +1846,7 @@ wrapup_globals_for_namespace (namespace, data)
     }
 
   /* Write out any globals that need to be output.  */
-  result = wrapup_global_declarations (vec, len);
-
-  return result;
+  return wrapup_global_declarations (vec, len);
 }
 
 \f
@@ -1945,13 +1855,12 @@ static int no_print_functions = 0;
 static int no_print_builtins = 0;
 
 void
-print_binding_level (lvl)
-     struct cp_binding_level *lvl;
+print_binding_level (struct cp_binding_level* lvl)
 {
   tree t;
   int i = 0, len;
   fprintf (stderr, " blocks=");
-  fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks);
+  fprintf (stderr, HOST_PTR_PRINTF, (void *) lvl->blocks);
   if (lvl->tag_transparent)
     fprintf (stderr, " tag-transparent");
   if (lvl->more_cleanups_ok)
@@ -2046,29 +1955,28 @@ print_binding_level (lvl)
 }
 
 void
-print_other_binding_stack (stack)
-     struct cp_binding_level *stack;
+print_other_binding_stack (struct cp_binding_level *stack)
 {
   struct cp_binding_level *level;
   for (level = stack; level != global_binding_level; level = level->level_chain)
     {
       fprintf (stderr, "binding level ");
-      fprintf (stderr, HOST_PTR_PRINTF, level);
+      fprintf (stderr, HOST_PTR_PRINTF, (void *) level);
       fprintf (stderr, "\n");
       print_binding_level (level);
     }
 }
 
 void
-print_binding_stack ()
+print_binding_stack (void)
 {
   struct cp_binding_level *b;
   fprintf (stderr, "current_binding_level=");
-  fprintf (stderr, HOST_PTR_PRINTF, current_binding_level);
+  fprintf (stderr, HOST_PTR_PRINTF, (void *) current_binding_level);
   fprintf (stderr, "\nclass_binding_level=");
-  fprintf (stderr, HOST_PTR_PRINTF, class_binding_level);
+  fprintf (stderr, HOST_PTR_PRINTF, (void *) class_binding_level);
   fprintf (stderr, "\nglobal_binding_level=");
-  fprintf (stderr, HOST_PTR_PRINTF, global_binding_level);
+  fprintf (stderr, HOST_PTR_PRINTF, (void *) global_binding_level);
   fprintf (stderr, "\n");
   if (class_binding_level)
     {
@@ -2089,135 +1997,21 @@ print_binding_stack ()
 
 /* Namespace binding access routines: The namespace_bindings field of
    the identifier is polymorphic, with three possible values:
-   NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node
-   indicating the BINDING_VALUE of global_namespace.  */
-
-/* Check whether the a binding for the name to scope is known.
-   Assumes that the bindings of the name are already a list
-   of bindings. Returns the binding found, or NULL_TREE.  */
-
-static tree
-find_binding (name, scope)
-     tree name;
-     tree scope;
-{
-  tree iter, prev = NULL_TREE;
-
-  scope = ORIGINAL_NAMESPACE (scope);
-
-  for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
-       iter = TREE_CHAIN (iter))
-    {
-      my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
-      if (BINDING_SCOPE (iter) == scope)
-       {
-         /* Move binding found to the front of the list, so
-             subsequent lookups will find it faster.  */
-         if (prev)
-           {
-             TREE_CHAIN (prev) = TREE_CHAIN (iter);
-             TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
-             IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
-           }
-         return iter;
-       }
-      prev = iter;
-    }
-  return NULL_TREE;
-}
-
-/* Always returns a binding for name in scope. If the
-   namespace_bindings is not a list, convert it to one first.
-   If no binding is found, make a new one.  */
-
-tree
-binding_for_name (name, scope)
-     tree name;
-     tree scope;
-{
-  tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
-  tree result;
-
-  scope = ORIGINAL_NAMESPACE (scope);
-
-  if (b && TREE_CODE (b) != CPLUS_BINDING)
-    {
-      /* Get rid of optimization for global scope.  */
-      IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE;
-      BINDING_VALUE (binding_for_name (name, global_namespace)) = b;
-      b = IDENTIFIER_NAMESPACE_BINDINGS (name);
-    }
-  if (b && (result = find_binding (name, scope)))
-    return result;
-  /* Not found, make a new one.  */
-  result = make_node (CPLUS_BINDING);
-  TREE_CHAIN (result) = b;
-  IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
-  BINDING_SCOPE (result) = scope;
-  BINDING_TYPE (result) = NULL_TREE;
-  BINDING_VALUE (result) = NULL_TREE;
-  return result;
-}
-
-/* Return the binding value for name in scope, considering that
-   namespace_binding may or may not be a list of CPLUS_BINDINGS.  */
-
-tree
-namespace_binding (name, scope)
-     tree name;
-     tree scope;
-{
-  tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
-  if (b == NULL_TREE)
-    return NULL_TREE;
-  if (scope == NULL_TREE)
-    scope = global_namespace;
-  if (TREE_CODE (b) != CPLUS_BINDING)
-    return (scope == global_namespace) ? b : NULL_TREE;
-  name = find_binding (name,scope);
-  if (name == NULL_TREE)
-    return name;
-  return BINDING_VALUE (name);
-}
-
-/* Set the binding value for name in scope. If modifying the binding
-   of global_namespace is attempted, try to optimize it.  */
-
-void
-set_namespace_binding (name, scope, val)
-     tree name;
-     tree scope;
-     tree val;
-{
-  tree b;
-
-  if (scope == NULL_TREE)
-    scope = global_namespace;
-
-  if (scope == global_namespace)
-    {
-      b = IDENTIFIER_NAMESPACE_BINDINGS (name);
-      if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING)
-       {
-         IDENTIFIER_NAMESPACE_BINDINGS (name) = val;
-         return;
-       }
-    }
-  b = binding_for_name (name, scope);
-  BINDING_VALUE (b) = val;
-}
+   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 (name)
-     tree name;
+push_namespace (tree name)
 {
   tree d = NULL_TREE;
   int need_new = 1;
   int implicit_use = 0;
   int global = 0;
+
+  timevar_push (TV_NAME_LOOKUP);
+  
   if (!global_namespace)
     {
       /* This must be ::.  */
@@ -2266,6 +2060,9 @@ push_namespace (name)
          pushlevel (0);
          declare_namespace_level ();
          NAMESPACE_LEVEL (d) = current_binding_level;
+         VARRAY_TREE_INIT (current_binding_level->static_decls,
+                           name != std_identifier ? 10 : 200,
+                           "Static declarations");
        }
     }
   else
@@ -2275,12 +2072,14 @@ push_namespace (name)
     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 ()
+pop_namespace (void)
 {
   my_friendly_assert (current_namespace != global_namespace, 20010801);
   current_namespace = CP_DECL_CONTEXT (current_namespace);
@@ -2292,8 +2091,7 @@ pop_namespace ()
    nested within another namespace.  */
 
 void
-push_nested_namespace (ns)
-     tree ns;
+push_nested_namespace (tree ns)
 {
   if (ns == global_namespace)
     push_to_top_level ();
@@ -2308,9 +2106,9 @@ push_nested_namespace (ns)
    entered with push_nested_namespace.  */
 
 void
-pop_nested_namespace (ns)
-     tree ns;
+pop_nested_namespace (tree ns)
 {
+  timevar_push (TV_NAME_LOOKUP);
   while (ns != global_namespace)
     {
       pop_namespace ();
@@ -2318,9 +2116,26 @@ pop_nested_namespace (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
@@ -2328,16 +2143,18 @@ pop_nested_namespace (ns)
    scope isn't enough, because more binding levels may be pushed.  */
 struct saved_scope *scope_chain;
 
-static tree
-store_bindings (names, old_bindings)
-     tree names, old_bindings;
+static cxx_saved_binding *
+store_bindings (tree names, cxx_saved_binding *old_bindings)
 {
   tree t;
-  tree search_bindings = old_bindings;
+  cxx_saved_binding *search_bindings = old_bindings;
 
+  timevar_push (TV_NAME_LOOKUP);
   for (t = names; t; t = TREE_CHAIN (t))
     {
-      tree binding, t1, id;
+      tree id;
+      cxx_saved_binding *saved;
+      cxx_saved_binding *t1;
 
       if (TREE_CODE (t) == TREE_LIST)
        id = TREE_PURPOSE (t);
@@ -2351,35 +2168,35 @@ store_bindings (names, old_bindings)
          || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
        continue;
 
-      for (t1 = search_bindings; t1; t1 = TREE_CHAIN (t1))
-       if (TREE_VEC_ELT (t1, 0) == id)
+      for (t1 = search_bindings; t1; t1 = t1->previous)
+       if (t1->identifier == id)
          goto skip_it;
 
       my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
-      binding = make_tree_vec (4);
-      TREE_VEC_ELT (binding, 0) = id;
-      TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
-      TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
-      TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
-      IDENTIFIER_BINDING (id) = NULL_TREE;
+      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;
-      TREE_CHAIN (binding) = old_bindings;
-      old_bindings = binding;
+      old_bindings = saved;
     skip_it:
       ;
     }
-  return old_bindings;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
 }
 
 void
-maybe_push_to_top_level (pseudo)
-     int pseudo;
+maybe_push_to_top_level (int pseudo)
 {
   struct saved_scope *s;
   struct cp_binding_level *b;
-  tree old_bindings;
+  cxx_saved_binding *old_bindings;
   int need_pop;
 
+  timevar_push (TV_NAME_LOOKUP);
   s = (struct saved_scope *) ggc_alloc_cleared (sizeof (struct saved_scope));
 
   b = scope_chain ? current_binding_level : 0;
@@ -2393,7 +2210,7 @@ maybe_push_to_top_level (pseudo)
   else
     need_pop = 0;
 
-  old_bindings = NULL_TREE;
+  old_bindings = NULL;
   if (scope_chain && previous_class_type)
     old_bindings = store_bindings (previous_class_values, old_bindings);
 
@@ -2426,26 +2243,29 @@ maybe_push_to_top_level (pseudo)
   s->need_pop_function_context = need_pop;
   s->function_decl = current_function_decl;
   s->last_parms = last_function_parms;
+  s->check_access = flag_access_control;
 
   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 ()
+push_to_top_level (void)
 {
   maybe_push_to_top_level (0);
 }
 
 void
-pop_from_top_level ()
+pop_from_top_level (void)
 {
   struct saved_scope *s = scope_chain;
-  tree t;
+  cxx_saved_binding *saved;
 
+  timevar_push (TV_NAME_LOOKUP); 
   /* Clear out class-level bindings cache.  */
   if (previous_class_type)
     invalidate_class_lookup_cache ();
@@ -2453,13 +2273,13 @@ pop_from_top_level ()
   current_lang_base = 0;
 
   scope_chain = s->prev;
-  for (t = s->old_bindings; t; t = TREE_CHAIN (t))
+  for (saved = s->old_bindings; saved; saved = saved->previous)
     {
-      tree id = TREE_VEC_ELT (t, 0);
+      tree id = saved->identifier;
 
-      SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
-      IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
-      IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
+      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
@@ -2468,6 +2288,7 @@ pop_from_top_level ()
     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 "name".
@@ -2484,10 +2305,9 @@ pop_from_top_level ()
    the type that ID maps to.  */
 
 static void
-set_identifier_type_value_with_scope (id, type, b)
-     tree id;
-     tree type;
-     struct cp_binding_level *b;
+set_identifier_type_value_with_scope (tree id, 
+                                      tree type, 
+                                      struct cp_binding_level* b)
 {
   if (!b->namespace_p)
     {
@@ -2499,7 +2319,8 @@ set_identifier_type_value_with_scope (id, type, b)
     }
   else
     {
-      tree binding = binding_for_name (id, current_namespace);
+      cxx_binding *binding =
+         binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
       BINDING_TYPE (binding) = type;
       /* Store marker instead of real type.  */
       type = global_type_node;
@@ -2510,9 +2331,7 @@ set_identifier_type_value_with_scope (id, type, b)
 /* As set_identifier_type_value_with_scope, but using current_binding_level.  */
 
 void
-set_identifier_type_value (id, type)
-     tree id;
-     tree type;
+set_identifier_type_value (tree id, tree type)
 {
   set_identifier_type_value_with_scope (id, type, current_binding_level);
 }
@@ -2520,21 +2339,21 @@ set_identifier_type_value (id, type)
 /* Return the type associated with id.  */
 
 tree
-identifier_type_value (id)
-     tree id;
+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)
-    return 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)
-    return REAL_IDENTIFIER_TYPE_VALUE (id);
+    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);
+     Ask lookup_name not to return non-types. */
+  id = lookup_name_real (id, 2, 1, 0, LOOKUP_COMPLAIN);
   if (id)
-    return TREE_TYPE (id);
-  return NULL_TREE;
+    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.
@@ -2542,7 +2361,7 @@ identifier_type_value (id)
    We don't pop past namespaces, as they might be valid.  */
 
 void
-pop_everything ()
+pop_everything (void)
 {
 #ifdef DEBUG_BINDING_LEVELS
   fprintf (stderr, "XXX entering pop_everything ()\n");
@@ -2569,10 +2388,9 @@ pop_everything ()
    processing.  */
 
 static tree
-maybe_process_template_type_declaration (type, globalize, b)
-     tree type;
-     int globalize;
-     struct cp_binding_level* b;
+maybe_process_template_type_declaration (tree type, 
+                                         int globalize, 
+                                         struct cp_binding_level* b)
 {
   tree decl = TYPE_NAME (type);
 
@@ -2635,9 +2453,7 @@ maybe_process_template_type_declaration (type, globalize, b)
    the TYPE_DECL for TYPE.  */
 
 tree
-create_implicit_typedef (name, type)
-     tree name;
-     tree type;
+create_implicit_typedef (tree name, tree type)
 {
   tree decl;
 
@@ -2655,12 +2471,12 @@ create_implicit_typedef (name, type)
 /* Remember a local name for name-mangling purposes.  */
 
 static void
-push_local_name (decl)
-     tree decl;
+push_local_name (tree decl)
 {
   size_t i, nelts;
   tree t, name;
 
+  timevar_push (TV_NAME_LOOKUP);
   if (!local_names)
     VARRAY_TREE_INIT (local_names, 8, "local_names");
 
@@ -2681,11 +2497,13 @@ push_local_name (decl)
            DECL_DISCRIMINATOR (decl) = 1;
 
          VARRAY_TREE (local_names, i) = decl;
+         timevar_pop (TV_NAME_LOOKUP);
          return;
        }
     }
 
   VARRAY_PUSH_TREE (local_names, decl);
+  timevar_pop (TV_NAME_LOOKUP);
 }
 
 /* Push a tag name NAME for struct/class/union/enum type TYPE.
@@ -2694,12 +2512,11 @@ push_local_name (decl)
    The latter is needed for implicit declarations.  */
 
 void
-pushtag (name, type, globalize)
-     tree name, type;
-     int globalize;
+pushtag (tree name, tree type, int globalize)
 {
   register struct cp_binding_level *b;
 
+  timevar_push (TV_NAME_LOOKUP);
   b = current_binding_level;
   while (b->tag_transparent
         || (b->parm_flag == 2
@@ -2809,17 +2626,18 @@ pushtag (name, type, globalize)
       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 int anon_cnt = 0;
+static GTY(()) int anon_cnt;
 
 /* Return an IDENTIFIER which can be used as a name for
    anonymous structs and unions.  */
 
 tree
-make_anon_name ()
+make_anon_name (void)
 {
   char buf[32];
 
@@ -2831,7 +2649,7 @@ make_anon_name ()
    This keeps dbxout from getting confused.  */
 
 void
-clear_anon_tags ()
+clear_anon_tags (void)
 {
   register struct cp_binding_level *b;
   register tree tags;
@@ -2866,8 +2684,7 @@ clear_anon_tags ()
    `const int&'.  */
 
 int
-decls_match (newdecl, olddecl)
-     tree newdecl, olddecl;
+decls_match (tree newdecl, tree olddecl)
 {
   int types_match;
 
@@ -2970,8 +2787,7 @@ decls_match (newdecl, olddecl)
    the user's control.  */
 
 static void
-warn_extern_redeclared_static (newdecl, olddecl)
-     tree newdecl, olddecl;
+warn_extern_redeclared_static (tree newdecl, tree olddecl)
 {
   static const char *const explicit_extern_static_warning
     = "`%D' was declared `extern' and later `static'";
@@ -3016,8 +2832,7 @@ warn_extern_redeclared_static (newdecl, olddecl)
    Otherwise, return 0.  */
 
 int
-duplicate_decls (newdecl, olddecl)
-     tree newdecl, olddecl;
+duplicate_decls (tree newdecl, tree olddecl)
 {
   unsigned olddecl_uid = DECL_UID (olddecl);
   int olddecl_friend = 0, types_match = 0;
@@ -3054,19 +2869,19 @@ duplicate_decls (newdecl, olddecl)
               && DECL_UNINLINABLE (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
        {
-         warning_with_decl (newdecl,
-                            "function `%s' redeclared as inline");
-         warning_with_decl (olddecl,
-                            "previous declaration of function `%s' with attribute noinline");
+         warning ("%Hfunction '%D' redeclared as inline",
+                   &DECL_SOURCE_LOCATION (newdecl), newdecl);
+         warning ("%Hprevious declaration of '%D' with attribute noinline",
+                   &DECL_SOURCE_LOCATION (olddecl), olddecl);
        }
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && DECL_UNINLINABLE (newdecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
        {
-         warning_with_decl (newdecl,
-                            "function `%s' redeclared with attribute noinline");
-         warning_with_decl (olddecl,
-                            "previous declaration of function `%s' was inline");
+         warning ("%Hfunction '%D' redeclared with attribute noinline",
+                   &DECL_SOURCE_LOCATION (newdecl), newdecl);
+         warning ("%Hprevious declaration of '%D' was inline",
+                   &DECL_SOURCE_LOCATION (olddecl), olddecl);
        }
     }
 
@@ -3135,6 +2950,10 @@ duplicate_decls (newdecl, olddecl)
          /* Replace the old RTL to avoid problems with inlining.  */
          SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
        }
+      /* Even if the types match, prefer the new declarations type
+        for anitipated built-ins, for exception lists, etc...  */
+      else if (DECL_ANTICIPATED (olddecl))
+       TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
 
       if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
        {
@@ -3210,7 +3029,11 @@ duplicate_decls (newdecl, olddecl)
                   && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
                                 TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
                   && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
-                                          DECL_TEMPLATE_PARMS (olddecl)))
+                                          DECL_TEMPLATE_PARMS (olddecl))
+                  /* Template functions can be disambiguated by
+                     return type.  */
+                  && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
+                                  TREE_TYPE (TREE_TYPE (olddecl))))
            {
              error ("new declaration `%#D'", newdecl);
              cp_error_at ("ambiguates old declaration `%#D'", olddecl);
@@ -3536,8 +3359,12 @@ duplicate_decls (newdecl, olddecl)
        {
          DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
            |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
-         DECL_NO_LIMIT_STACK (newdecl)
-           |= DECL_NO_LIMIT_STACK (olddecl);
+         DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
+         TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+         TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
+         TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
+         DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
+         DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
          /* Keep the old RTL.  */
          COPY_DECL_RTL (olddecl, newdecl);
        }
@@ -3601,7 +3428,10 @@ duplicate_decls (newdecl, olddecl)
          DECL_BEFRIENDING_CLASSES (newdecl)
            = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
                       DECL_BEFRIENDING_CLASSES (olddecl));
-         DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
+         /* DECL_THUNKS is only valid for virtual functions,
+            otherwise it is a DECL_FRIEND_CONTEXT.  */
+         if (DECL_VIRTUAL_P (newdecl))
+           DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
        }
     }
 
@@ -3612,7 +3442,7 @@ duplicate_decls (newdecl, olddecl)
        {
          /* If newdecl is not a specialization, then it is not a
             template-related function at all.  And that means that we
-            shoud have exited above, returning 0.  */
+            should have exited above, returning 0.  */
          my_friendly_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl),
                              0);
 
@@ -3771,13 +3601,13 @@ duplicate_decls (newdecl, olddecl)
    to agree with what X says.  */
 
 tree
-pushdecl (x)
-     tree x;
+pushdecl (tree x)
 {
   register tree t;
   register tree name;
   int need_new_binding;
 
+  timevar_push (TV_NAME_LOOKUP);
   /* We shouldn't be calling pushdecl when we're generating RTL for a
      function that we already did semantic analysis on previously.  */
   my_friendly_assert (!cfun || doing_semantic_analysis_p (),
@@ -3901,7 +3731,7 @@ pushdecl (x)
 
              /* Check for duplicate params.  */
              if (duplicate_decls (x, t))
-               return t;
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
          else if ((DECL_EXTERN_C_FUNCTION_P (x)
                    || DECL_FUNCTION_TEMPLATE_P (x))
@@ -3914,12 +3744,12 @@ pushdecl (x)
                            TREE_TYPE (x));
 
              /* Throw away the redeclaration.  */
-             return t;
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
          else if (TREE_CODE (t) != TREE_CODE (x))
            {
              if (duplicate_decls (x, t))
-               return t;
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
          else if (duplicate_decls (x, t))
            {
@@ -3928,7 +3758,7 @@ pushdecl (x)
              else if (TREE_CODE (t) == FUNCTION_DECL)
                check_default_args (t);
 
-             return t;
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
          else if (DECL_MAIN_P (x))
            {
@@ -3942,7 +3772,7 @@ pushdecl (x)
              error ("as `%D'", x);
              /* We don't try to push this declaration since that
                 causes a crash.  */
-             return x;
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
            }
        }
 
@@ -3960,7 +3790,7 @@ pushdecl (x)
        {
          t = push_overloaded_decl (x, PUSH_LOCAL);
          if (t != x)
-           return t;
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
          if (!namespace_bindings_p ())
            /* We do not need to create a binding for this name;
               push_overloaded_decl will have already done so if
@@ -3972,7 +3802,7 @@ pushdecl (x)
          t = push_overloaded_decl (x, PUSH_GLOBAL);
          if (t == x)
            add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
-         return t;
+         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
        }
 
       /* If declaring a type as a typedef, copy the type (unless we're
@@ -4049,6 +3879,7 @@ pushdecl (x)
                && t != NULL_TREE)
              && (TREE_CODE (x) == TYPE_DECL
                  || TREE_CODE (x) == VAR_DECL
+                 || TREE_CODE (x) == ALIAS_DECL
                  || TREE_CODE (x) == NAMESPACE_DECL
                  || TREE_CODE (x) == CONST_DECL
                  || TREE_CODE (x) == TEMPLATE_DECL))
@@ -4147,7 +3978,9 @@ pushdecl (x)
          if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
              /* Inline decls shadow nothing.  */
              && !DECL_FROM_INLINE (x)
-             && TREE_CODE (oldlocal) == PARM_DECL)
+             && TREE_CODE (oldlocal) == PARM_DECL
+             /* Don't check the `this' parameter.  */
+             && !DECL_ARTIFICIAL (oldlocal))
            {
              bool err = false;
 
@@ -4159,6 +3992,9 @@ pushdecl (x)
                     them there.  */
                  struct cp_binding_level *b = current_binding_level->level_chain;
 
+                 /* Skip the ctor/dtor cleanup level.  */
+                 b = b->level_chain;
+
                  /* ARM $8.3 */
                  if (b->parm_flag == 1)
                    {
@@ -4169,7 +4005,8 @@ pushdecl (x)
                }
 
              if (warn_shadow && !err)
-               shadow_warning ("a parameter", name, oldlocal);
+               shadow_warning (SW_PARAM,
+                               IDENTIFIER_POINTER (name), oldlocal);
            }
 
          /* Maybe warn if shadowing something else.  */
@@ -4186,11 +4023,13 @@ pushdecl (x)
                            IDENTIFIER_POINTER (name));
              else if (oldlocal != NULL_TREE
                       && TREE_CODE (oldlocal) == VAR_DECL)
-               shadow_warning ("a previous local", name, oldlocal);
+               shadow_warning (SW_LOCAL,
+                               IDENTIFIER_POINTER (name), oldlocal);
              else if (oldglobal != NULL_TREE
                       && TREE_CODE (oldglobal) == VAR_DECL)
                /* XXX shadow warnings in outer-more namespaces */
-               shadow_warning ("a global declaration", name, oldglobal);
+               shadow_warning (SW_GLOBAL,
+                               IDENTIFIER_POINTER (name), oldglobal);
            }
        }
 
@@ -4207,20 +4046,19 @@ pushdecl (x)
                       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
                       : current_binding_level);
 
-  return 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 (x, level)
-     tree x;
-     struct cp_binding_level *level;
+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->parm_flag == 2)
     {
@@ -4237,19 +4075,19 @@ pushdecl_with_scope (x, level)
       current_binding_level = b;
     }
   current_function_decl = function_decl;
-  return x;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
 
 /* Like pushdecl, only it places X in the current namespace,
    if appropriate.  */
 
 tree
-pushdecl_namespace_level (x)
-     tree x;
+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
@@ -4283,30 +4121,30 @@ pushdecl_namespace_level (x)
          *ptr = newval;
         }
     }
-  return t;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL,
    if appropriate.  */
 
 tree
-pushdecl_top_level (x)
-     tree x;
+pushdecl_top_level (tree x)
 {
+  timevar_push (TV_NAME_LOOKUP);
   push_to_top_level ();
   x = pushdecl_namespace_level (x);
   pop_from_top_level ();
-  return x;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
 
 /* Make the declaration of X appear in CLASS scope.  */
 
 void
-pushdecl_class_level (x)
-     tree x;
+pushdecl_class_level (tree x)
 {
   tree name;
 
+  timevar_push (TV_NAME_LOOKUP);
   /* Get the name of X.  */
   if (TREE_CODE (x) == OVERLOAD)
     name = DECL_NAME (get_first_fn (x));
@@ -4329,14 +4167,14 @@ pushdecl_class_level (x)
       for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
        pushdecl_class_level (f);
     }
+  timevar_pop (TV_NAME_LOOKUP);
 }
 
 /* Enter DECL into the symbol table, if that's appropriate.  Returns
    DECL, or a modified version thereof.  */
 
 tree
-maybe_push_decl (decl)
-     tree decl;
+maybe_push_decl (tree decl)
 {
   tree type = TREE_TYPE (decl);
 
@@ -4365,15 +4203,17 @@ maybe_push_decl (decl)
    under the name NAME.  */
 
 void
-push_class_level_binding (name, x)
-     tree name;
-     tree x;
+push_class_level_binding (tree name, tree x)
 {
-  tree binding;
+  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)
-    return;
+    {
+      timevar_pop (TV_NAME_LOOKUP);
+      return;
+    }
 
   /* Make sure that this new member does not have the same name
      as a template parameter.  */
@@ -4423,6 +4263,7 @@ push_class_level_binding (name, x)
            INHERITED_VALUE_BINDING_P (binding) = 0;
            TREE_TYPE (shadow) = x;
            IDENTIFIER_CLASS_VALUE (name) = x;
+           timevar_pop (TV_NAME_LOOKUP);
            return;
          }
     }
@@ -4438,6 +4279,7 @@ push_class_level_binding (name, x)
         what to pop later.  */
       TREE_TYPE (class_binding_level->class_shadowed) = x;
     }
+  timevar_pop (TV_NAME_LOOKUP);
 }
 
 /* Insert another USING_DECL into the current binding level, returning
@@ -4446,24 +4288,24 @@ push_class_level_binding (name, x)
    scope, a using decl might extend any previous bindings).  */
 
 tree
-push_using_decl (scope, name)
-     tree scope;
-     tree name;
+push_using_decl (tree scope, tree name)
 {
   tree decl;
 
+  timevar_push (TV_NAME_LOOKUP);
   my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383);
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384);
   for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
     if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
       break;
   if (decl)
-    return namespace_bindings_p () ? decl : NULL_TREE;
+    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;
-  return decl;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
 }
 
 /* Add namespace to using_directives. Return NULL_TREE if nothing was
@@ -4471,25 +4313,26 @@ push_using_decl (scope, name)
    TREE_LIST otherwise.  */
 
 tree
-push_using_directive (used)
-     tree used;
+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)
-    return NULL_TREE;
-
-  /* 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, 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;
-  return 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);
 }
 
 /* DECL is a FUNCTION_DECL for a non-member function, which may have
@@ -4512,15 +4355,14 @@ push_using_directive (used)
    it's always DECL (and never something that's not a _DECL).  */
 
 tree
-push_overloaded_decl (decl, flags)
-     tree decl;
-     int flags;
+push_overloaded_decl (tree decl, int flags)
 {
   tree name = DECL_NAME (decl);
   tree old;
   tree new_binding;
   int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
 
+  timevar_push (TV_NAME_LOOKUP);
   if (doing_global)
     old = namespace_binding (name, DECL_CONTEXT (decl));
   else
@@ -4553,7 +4395,7 @@ push_overloaded_decl (decl, flags)
                          decl, fn);
 
              if (duplicate_decls (decl, fn))
-               return fn;
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
            }
        }
       else if (old == error_mark_node)
@@ -4563,7 +4405,7 @@ push_overloaded_decl (decl, flags)
        {
          cp_error_at ("previous non-function declaration `%#D'", old);
          error ("conflicts with function declaration `%#D'", decl);
-         return decl;
+         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
        }
     }
 
@@ -4594,7 +4436,7 @@ push_overloaded_decl (decl, flags)
        {
          tree *d;
 
-         for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names;
+         for (d = &BINDING_SCOPE (IDENTIFIER_BINDING (name))->names;
               *d;
               d = &TREE_CHAIN (*d))
            if (*d == old
@@ -4609,10 +4451,10 @@ push_overloaded_decl (decl, flags)
                  *d = tree_cons (NULL_TREE, new_binding,
                                  TREE_CHAIN (*d));
 
-               /* And update the CPLUS_BINDING node.  */
+               /* And update the cxx_binding node.  */
                BINDING_VALUE (IDENTIFIER_BINDING (name))
                  = new_binding;
-               return decl;
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
              }
 
          /* We should always find a previous binding in this case.  */
@@ -4623,15 +4465,14 @@ push_overloaded_decl (decl, flags)
       push_local_binding (name, new_binding, flags);
     }
 
-  return decl;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
 }
 \f
 /* Generate an implicit declaration for identifier FUNCTIONID
    as a function of type int ().  Print a warning if appropriate.  */
 
 tree
-implicitly_declare (functionid)
-     tree functionid;
+implicitly_declare (tree functionid)
 {
   register tree decl;
 
@@ -4667,8 +4508,7 @@ implicitly_declare (functionid)
    where the identifier should go.  */
 
 static const char *
-redeclaration_error_message (newdecl, olddecl)
-     tree newdecl, olddecl;
+redeclaration_error_message (tree newdecl, tree olddecl)
 {
   if (TREE_CODE (newdecl) == TYPE_DECL)
     {
@@ -4744,9 +4584,7 @@ redeclaration_error_message (newdecl, olddecl)
 /* Create a new label, named ID.  */
 
 static tree
-make_label_decl (id, local_p)
-     tree id;
-     int local_p;
+make_label_decl (tree id, int local_p)
 {
   tree decl;
 
@@ -4776,8 +4614,7 @@ make_label_decl (id, local_p)
    this use is valid.  */
 
 static void
-use_label (decl)
-     tree decl;
+use_label (tree decl)
 {
   if (named_label_uses == NULL
       || named_label_uses->names_in_scope != current_binding_level->names
@@ -4801,24 +4638,24 @@ use_label (decl)
    labels, and complain about them at the end of a function.)  */
 
 tree
-lookup_label (id)
-     tree id;
+lookup_label (tree id)
 {
   tree decl;
   struct named_label_list *ent;
 
+  timevar_push (TV_NAME_LOOKUP);
   /* You can't use labels at global scope.  */
   if (current_function_decl == NULL_TREE)
     {
       error ("label `%s' referenced outside of any function",
             IDENTIFIER_POINTER (id));
-      return NULL_TREE;
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
     }
 
   /* See if we've already got this label.  */
   decl = IDENTIFIER_LABEL_VALUE (id);
   if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl)
-    return decl;
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
 
   /* Record this label on the list of labels used in this function.
      We do this before calling make_label_decl so that we get the
@@ -4835,14 +4672,13 @@ lookup_label (id)
   /* Now fill in the information we didn't have before.  */
   ent->label_decl = decl;
 
-  return decl;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
 }
 
 /* Declare a local label named ID.  */
 
 tree
-declare_local_label (id)
-     tree id;
+declare_local_label (tree id)
 {
   tree decl;
 
@@ -4864,8 +4700,7 @@ declare_local_label (id)
    DECL.  Returns 2 if it's also a real problem.  */
 
 static int
-decl_jump_unsafe (decl)
-     tree decl;
+decl_jump_unsafe (tree decl)
 {
   if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
     return 0;
@@ -4889,12 +4724,11 @@ decl_jump_unsafe (decl)
    context; FILE and LINE are the source position of the jump or 0.  */
 
 static void
-check_previous_goto_1 (decl, level, names, file, line)
-     tree decl;
-     struct cp_binding_level *level;
-     tree names;
-     const char *file;
-     int line;
+check_previous_goto_1 (tree decl,
+                       struct cp_binding_level* level,
+                       tree names,
+                       const char* file,
+                       int line)
 {
   int identified = 0;
   int saw_eh = 0;
@@ -4955,8 +4789,7 @@ check_previous_goto_1 (decl, level, names, file, line)
 }
 
 static void
-check_previous_goto (use)
-     struct named_label_use_list *use;
+check_previous_goto (struct named_label_use_list* use)
 {
   check_previous_goto_1 (use->label_decl, use->binding_level,
                         use->names_in_scope, use->filename_o_goto,
@@ -4964,8 +4797,7 @@ check_previous_goto (use)
 }
 
 static void
-check_switch_goto (level)
-     struct cp_binding_level *level;
+check_switch_goto (struct cp_binding_level* level)
 {
   check_previous_goto_1 (NULL_TREE, level, level->names, NULL, 0);
 }
@@ -4974,8 +4806,7 @@ check_switch_goto (level)
    are OK.  Called by define_label.  */
 
 static void
-check_previous_gotos (decl)
-     tree decl;
+check_previous_gotos (tree decl)
 {
   struct named_label_use_list **usep;
 
@@ -4999,8 +4830,7 @@ check_previous_gotos (decl)
    finish_goto_stmt.  */
 
 void
-check_goto (decl)
-     tree decl;
+check_goto (tree decl)
 {
   int identified = 0;
   tree bad;
@@ -5060,15 +4890,13 @@ check_goto (decl)
    Otherwise return 0.  */
 
 tree
-define_label (filename, line, name)
-     const char *filename;
-     int line;
-     tree name;
+define_label (const char* filename, int line, tree name)
 {
   tree decl = lookup_label (name);
   struct named_label_list *ent;
   register struct cp_binding_level *p;
 
+  timevar_push (TV_NAME_LOOKUP);
   for (ent = named_labels; ent; ent = ent->next)
     if (ent->label_decl == decl)
       break;
@@ -5084,7 +4912,7 @@ define_label (filename, line, name)
   if (DECL_INITIAL (decl) != NULL_TREE)
     {
       error ("duplicate label `%D'", decl);
-      return 0;
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
     }
   else
     {
@@ -5099,8 +4927,9 @@ define_label (filename, line, name)
          ent->binding_level = current_binding_level;
        }
       check_previous_gotos (decl);
-      return decl;
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
     }
+  timevar_pop (TV_NAME_LOOKUP);
 }
 
 struct cp_switch
@@ -5129,8 +4958,7 @@ static struct cp_switch *switch_stack;
    SWITCH_STMT is the switch statement being parsed.  */
 
 void
-push_switch (switch_stmt)
-     tree switch_stmt;
+push_switch (tree switch_stmt)
 {
   struct cp_switch *p
     = (struct cp_switch *) xmalloc (sizeof (struct cp_switch));
@@ -5142,7 +4970,7 @@ push_switch (switch_stmt)
 }
 
 void
-pop_switch ()
+pop_switch (void)
 {
   struct cp_switch *cs;
 
@@ -5156,9 +4984,7 @@ pop_switch ()
    is a bad place for one.  */
 
 tree
-finish_case_label (low_value, high_value)
-     tree low_value;
-     tree high_value;
+finish_case_label (tree low_value, tree high_value)
 {
   tree cond, r;
   register struct cp_binding_level *p;
@@ -5191,8 +5017,6 @@ finish_case_label (low_value, high_value)
     cond = TREE_VALUE (cond);
 
   r = c_add_case_label (switch_stack->cases, cond, low_value, high_value);
-  if (r == error_mark_node)
-    r = NULL_TREE;
 
   check_switch_goto (switch_stack->level);
 
@@ -5210,7 +5034,7 @@ finish_case_label (low_value, high_value)
    store the result back using `storedecls' or you will lose.  */
 
 tree
-getdecls ()
+getdecls (void)
 {
   return current_binding_level->names;
 }
@@ -5218,7 +5042,7 @@ getdecls ()
 /* Return the list of type-tags (for structs, etc) of the current level.  */
 
 tree
-gettags ()
+gettags (void)
 {
   return current_binding_level->tags;
 }
@@ -5228,8 +5052,7 @@ gettags ()
    after they are modified in the light of any missing parameters.  */
 
 static void
-storedecls (decls)
-     tree decls;
+storedecls (tree decls)
 {
   current_binding_level->names = decls;
 }
@@ -5237,8 +5060,7 @@ storedecls (decls)
 /* Similarly, store the list of tags of the current level.  */
 
 void
-storetags (tags)
-     tree tags;
+storetags (tree tags)
 {
   current_binding_level->tags = tags;
 }
@@ -5267,8 +5089,7 @@ storetags (tags)
    Return null for this case.  */
 
 static tree
-follow_tag_typedef (type)
-     tree type;
+follow_tag_typedef (tree type)
 {
   tree original;
 
@@ -5286,7 +5107,7 @@ follow_tag_typedef (type)
 
 /* Given NAME, an IDENTIFIER_NODE,
    return the structure (or union or enum) definition for that name.
-   Searches binding levels from BINDING_LEVEL up to the global level.
+   Searches binding levels from BINDING_SCOPE up to the global level.
    If THISLEVEL_ONLY is nonzero, searches only the specified context
    (but skips any tag-transparent contexts to find one that is
    meaningful for tags).
@@ -5296,17 +5117,15 @@ follow_tag_typedef (type)
    reported.  */
 
 static tree
-lookup_tag (form, name, binding_level, thislevel_only)
-     enum tree_code form;
-     tree name;
-     struct cp_binding_level *binding_level;
-     int thislevel_only;
+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;
 
+  timevar_push (TV_NAME_LOOKUP);
   for (level = binding_level; level; level = level->level_chain)
     {
       register tree tail;
@@ -5316,24 +5135,28 @@ lookup_tag (form, name, binding_level, thislevel_only)
            /* There's no need for error checking here, because
               anon names are unique throughout the compilation.  */
            if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name)
-             return TREE_VALUE (tail);
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail));
          }
       else if (level->namespace_p)
        /* Do namespace lookup.  */
        for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
          {
-           tree old = binding_for_name (name, 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
-               && old && BINDING_VALUE (old)
-               && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old)))
-             old = TREE_TYPE (BINDING_VALUE (old));
-           else
-             old = BINDING_TYPE (old);
+               && binding && BINDING_VALUE (binding)
+               && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding)))
+             old = TREE_TYPE (BINDING_VALUE (binding));
+           else if (binding)
+             old = BINDING_TYPE (binding);
+            else
+              old = NULL_TREE;
 
            if (old)
              {
@@ -5342,18 +5165,18 @@ lookup_tag (form, name, binding_level, thislevel_only)
                   if the typedef doesn't refer to a taggable type.  */
                old = follow_tag_typedef (old);
                if (!old)
-                 return NULL_TREE;
+                 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);
-                   return NULL_TREE;
+                   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
                  }
-               return old;
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
              }
            if (thislevel_only || tail == global_namespace)
-             return NULL_TREE;
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
          }
       else
        for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
@@ -5367,9 +5190,9 @@ lookup_tag (form, name, binding_level, thislevel_only)
                  {
                    /* Definition isn't the kind we were looking for.  */
                    error ("`%#D' redeclared as %C", TREE_VALUE (tail), form);
-                   return NULL_TREE;
+                   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
                  }
-               return TREE_VALUE (tail);
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail));
              }
          }
       if (thislevel_only && ! level->tag_transparent)
@@ -5391,21 +5214,12 @@ lookup_tag (form, name, binding_level, thislevel_only)
              continue;
            }
          else
-           return NULL_TREE;
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
        }
     }
-  return NULL_TREE;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
 }
 
-#if 0
-void
-set_current_level_tags_transparency (tags_transparent)
-     int tags_transparent;
-{
-  current_binding_level->tag_transparent = tags_transparent;
-}
-#endif
-
 /* 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.
@@ -5414,12 +5228,11 @@ set_current_level_tags_transparency (tags_transparent)
    done when replacing anonymous tags with real tag names.  */
 
 static tree
-lookup_tag_reverse (type, name)
-     tree type;
-     tree name;
+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)
     {
       register tree tail;
@@ -5429,33 +5242,34 @@ lookup_tag_reverse (type, name)
            {
              if (name)
                TREE_PURPOSE (tail) = name;
-             return TREE_PURPOSE (tail);
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_PURPOSE (tail));
            }
        }
     }
-  return NULL_TREE;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
 }
 \f
 /* Look up NAME in the NAMESPACE.  */
 
 tree
-lookup_namespace_name (namespace, name)
-     tree namespace, name;
+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.  */
-    return name;
+    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);
-      return error_mark_node;
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
     }
 
   namespace = ORIGINAL_NAMESPACE (namespace);
@@ -5472,13 +5286,13 @@ lookup_namespace_name (namespace, name)
 
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
 
-  val = make_node (CPLUS_BINDING);
-  if (!qualified_lookup_using_namespace (name, namespace, val, 0))
-    return error_mark_node;
+  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))
+  if (binding.value)
     {
-      val = BINDING_VALUE (val);
+      val = binding.value;
 
       if (template_id)
        {
@@ -5497,7 +5311,7 @@ lookup_namespace_name (namespace, name)
            {
              error ("`%D::%D' is not a template",
                        namespace, name);
-             return error_mark_node;
+             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
            }
        }
 
@@ -5509,18 +5323,17 @@ lookup_namespace_name (namespace, name)
       if (!val || !DECL_P(val)
           || !DECL_LANG_SPECIFIC(val)
           || !DECL_ANTICIPATED (val))
-        return val;
+        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
     }
 
   error ("`%D' undeclared in namespace `%D'", name, namespace);
-  return error_mark_node;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 }
 
 /* Hash a TYPENAME_TYPE.  K is really of type `tree'.  */
 
 static hashval_t
-typename_hash (k)
-     const void * k;
+typename_hash (const void* k)
 {
   hashval_t hash;
   tree t = (tree) k;
@@ -5534,9 +5347,7 @@ typename_hash (k)
 /* Compare two TYPENAME_TYPEs.  K1 and K2 are really of type `tree'.  */
 
 static int
-typename_compare (k1, k2)
-     const void * k1;
-     const void * k2;
+typename_compare (const void * k1, const void * k2)
 {
   tree t1;
   tree t2;
@@ -5567,11 +5378,7 @@ typename_compare (k1, k2)
 static GTY ((param_is (union tree_node))) htab_t typename_htab;
 
 tree
-build_typename_type (context, name, fullname, base_type)
-     tree context;
-     tree name;
-     tree fullname;
-     tree base_type;
+build_typename_type (tree context, tree name, tree fullname)
 {
   tree t;
   tree d;
@@ -5587,7 +5394,6 @@ build_typename_type (context, name, fullname, base_type)
   t = make_aggr_type (TYPENAME_TYPE);
   TYPE_CONTEXT (t) = FROB_CONTEXT (context);
   TYPENAME_TYPE_FULLNAME (t) = fullname;
-  TREE_TYPE (t) = base_type;
 
   /* Build the corresponding TYPE_DECL.  */
   d = build_decl (TYPE_DECL, name, t);
@@ -5614,9 +5420,7 @@ build_typename_type (context, name, fullname, base_type)
    complain about errors, otherwise be quiet.  */
 
 tree
-make_typename_type (context, name, complain)
-     tree context, name;
-     tsubst_flags_t complain;
+make_typename_type (tree context, tree name, tsubst_flags_t complain)
 {
   tree fullname;
 
@@ -5668,7 +5472,7 @@ make_typename_type (context, name, complain)
        {
          tree tmpl = NULL_TREE;
          if (IS_AGGR_TYPE (context))
-           tmpl = lookup_field (context, name, 0, 0);
+           tmpl = lookup_field (context, name, 0, false);
          if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
            {
              if (complain & tf_error)
@@ -5677,10 +5481,13 @@ make_typename_type (context, name, complain)
              return error_mark_node;
            }
 
-         if (complain & tf_parsing)
-           type_access_control (context, tmpl);
-         else
-           enforce_access (context, tmpl);
+         if (complain & tf_error)
+           {
+             if (complain & tf_parsing)
+               perform_or_defer_access_check (context, tmpl);
+             else
+               enforce_access (context, tmpl);
+           }
 
          return lookup_template_class (tmpl,
                                        TREE_OPERAND (fullname, 1),
@@ -5699,7 +5506,7 @@ make_typename_type (context, name, complain)
              return error_mark_node;
            }
 
-         t = lookup_field (context, name, 0, 1);
+         t = lookup_field (context, name, 0, true);
          if (t)
            {
              if (TREE_CODE (t) != TYPE_DECL)
@@ -5709,23 +5516,16 @@ make_typename_type (context, name, complain)
                  return error_mark_node;
                }
 
-             if (complain & tf_parsing)
-               type_access_control (context, t);
-             else
-               enforce_access (context, t);
+             if (complain & tf_error)
+               {
+                 if (complain & tf_parsing)
+                   perform_or_defer_access_check (context, t);
+                 else
+                   enforce_access (context, t);
+               }
 
              if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
                t = TREE_TYPE (t);
-             if (IMPLICIT_TYPENAME_P (t))
-               {
-                 /* Lookup found an implicit typename that we had
-                    injected into the current scope. Doing things
-                    properly would have located the exact same type,
-                    so there is no error here.  We must remove the
-                    implicitness so that we do not warn about it.  */
-                 t = copy_node (t);
-                 TREE_TYPE (t) = NULL_TREE;
-               }
              
              return t;
            }
@@ -5741,7 +5541,7 @@ make_typename_type (context, name, complain)
       return error_mark_node;
     }
 
-  return build_typename_type (context, name, fullname,  NULL_TREE);
+  return build_typename_type (context, name, fullname);
 }
 
 /* Resolve `CONTEXT::template NAME'.  Returns an appropriate type,
@@ -5751,9 +5551,7 @@ make_typename_type (context, name, complain)
    that occur.  */
 
 tree
-make_unbound_class_template (context, name, complain)
-     tree context, name;
-     int complain;
+make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
 {
   tree t;
   tree d;
@@ -5771,19 +5569,22 @@ make_unbound_class_template (context, name, complain)
       tree tmpl = NULL_TREE;
 
       if (IS_AGGR_TYPE (context))
-       tmpl = lookup_field (context, name, 0, 0);
+       tmpl = lookup_field (context, name, 0, false);
 
       if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
        {
-         if (complain)
+         if (complain & tf_error)
            error ("no class template named `%#T' in `%#T'", name, context);
          return error_mark_node;
        }
       
-      if (complain & tf_parsing)
-       type_access_control (context, tmpl);
-      else
-       enforce_access (context, tmpl);
+      if (complain & tf_error)
+       {
+         if (complain & tf_parsing)
+           perform_or_defer_access_check (context, tmpl);
+         else
+           enforce_access (context, tmpl);
+       }
 
       return tmpl;
     }
@@ -5806,19 +5607,18 @@ make_unbound_class_template (context, name, complain)
 /* Select the right _DECL from multiple choices.  */
 
 static tree
-select_decl (binding, flags)
-     tree binding;
-     int flags;
+select_decl (cxx_binding *binding, int flags)
 {
   tree val;
   val = BINDING_VALUE (binding);
 
+  timevar_push (TV_NAME_LOOKUP);
   if (LOOKUP_NAMESPACES_ONLY (flags))
     {
       /* We are not interested in types.  */
       if (val && TREE_CODE (val) == NAMESPACE_DECL)
-        return val;
-      return NULL_TREE;
+        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
     }
 
   /* If we could have a type and
@@ -5833,7 +5633,7 @@ select_decl (binding, flags)
               || !DECL_CLASS_TEMPLATE_P (val)))
     val = NULL_TREE;
 
-  return val;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
 }
 
 /* Unscoped lookup of a global: iterate over current namespaces,
@@ -5841,77 +5641,74 @@ select_decl (binding, flags)
    of the namespaces we've considered in it.  */
 
 tree
-unqualified_namespace_lookup (name, flags, spacesp)
-     tree name;
-     int flags;
-     tree *spacesp;
+unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
 {
-  tree b = make_node (CPLUS_BINDING);
   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);
-      val = binding_for_name (name, scope);
 
       /* Ignore anticipated built-in functions.  */
-      if (val && BINDING_VALUE (val)
-          && DECL_P (BINDING_VALUE (val))
-          && DECL_LANG_SPECIFIC (BINDING_VALUE (val))
-          && DECL_ANTICIPATED (BINDING_VALUE (val)))
-        {
-          BINDING_VALUE (b) = NULL_TREE;
-          BINDING_TYPE (b) = NULL_TREE;
-        }
-      else
+      if (b && BINDING_VALUE (b)
+          && DECL_P (BINDING_VALUE (b))
+          && DECL_LANG_SPECIFIC (BINDING_VALUE (b))
+          && DECL_ANTICIPATED (BINDING_VALUE (b)))
+        /* Keep binding cleared.  */;
+      else if (b)
         {
           /* Initialize binding for this context.  */
-          BINDING_VALUE (b) = BINDING_VALUE (val);
-          BINDING_TYPE (b) = BINDING_TYPE (val);
+          binding.value = BINDING_VALUE (b);
+          binding.type = BINDING_TYPE (b);
         }
 
       /* Add all _DECLs seen through local using-directives.  */
       for (level = current_binding_level;
           !level->namespace_p;
           level = level->level_chain)
-       if (!lookup_using_namespace (name, b, level->using_directives,
+       if (!lookup_using_namespace (name, &binding, level->using_directives,
                                      scope, flags, spacesp))
          /* Give up because of error.  */
-         return error_mark_node;
+         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, b, DECL_NAMESPACE_USING (siter),
+         if (!lookup_using_namespace (name, &binding,
+                                       DECL_NAMESPACE_USING (siter),
                                       scope, flags, spacesp))
            /* Give up because of error.  */
-           return error_mark_node;
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
          if (siter == scope) break;
          siter = CP_DECL_CONTEXT (siter);
        }
 
-      val = select_decl (b, flags);
+      val = select_decl (&binding, flags);
       if (scope == global_namespace)
        break;
     }
-  return val;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
 }
 
 /* Combine prefer_type and namespaces_only into flags.  */
 
 static int
-lookup_flags (prefer_type, namespaces_only)
-  int prefer_type, namespaces_only;
+lookup_flags (int prefer_type, int namespaces_only)
 {
   if (namespaces_only)
     return LOOKUP_PREFER_NAMESPACES;
@@ -5926,48 +5723,43 @@ lookup_flags (prefer_type, namespaces_only)
    ignore it or not.  Subroutine of lookup_name_real.  */
 
 static tree
-qualify_lookup (val, flags)
-     tree val;
-     int flags;
+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
-         || ((flags & LOOKUP_TEMPLATES_EXPECTED)
-             && DECL_CLASS_TEMPLATE_P (val))))
+  if ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) == TYPE_DECL)
     return val;
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
     return NULL_TREE;
   return val;
 }
 
-/* Any other BINDING overrides an implicit TYPENAME.  Warn about
-   that.  */
+/* 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.  
 
-static void
-warn_about_implicit_typename_lookup (typename, binding)
-     tree typename;
-     tree binding;
-{
-  tree subtype = TREE_TYPE (TREE_TYPE (typename));
-  tree name = DECL_NAME (typename);
+   Returns a DECL (or OVERLOAD, or BASELINK) representing the
+   declaration found.  */
 
-  if (! (TREE_CODE (binding) == TEMPLATE_DECL
-        && CLASSTYPE_TEMPLATE_INFO (subtype)
-        && CLASSTYPE_TI_TEMPLATE (subtype) == binding)
-      && ! (TREE_CODE (binding) == TYPE_DECL
-           && same_type_p (TREE_TYPE (binding), subtype)))
+tree
+lookup_qualified_name (tree scope, tree name, bool is_type_p, int flags)
+{
+  if (TREE_CODE (scope) == NAMESPACE_DECL)
     {
-      warning ("lookup of `%D' finds `%#D'",
-                 name, binding);
-      warning ("  instead of `%D' from dependent base class",
-                 typename);
-      warning ("  (use `typename %T::%D' if that's what you meant)",
-                 constructor_name (current_class_type), name);
+      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 NULL_TREE;
+      return select_decl (&binding, flags);
     }
+  else
+    return lookup_member (scope, name, 0, is_type_p);
 }
 
 /* Check to see whether or not DECL is a variable that would have been
@@ -6037,236 +5829,125 @@ check_for_out_of_scope_variable (tree decl)
 
    If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
    If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
-   If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
    Otherwise we prefer non-TYPE_DECLs.
 
    If NONCLASS is nonzero, we don't look for the NAME in class scope,
    using IDENTIFIER_CLASS_VALUE.  */
 
-static tree
-lookup_name_real (name, prefer_type, nonclass, namespaces_only)
-     tree name;
-     int prefer_type, nonclass, namespaces_only;
+tree
+lookup_name_real (tree name, int prefer_type, int nonclass, 
+                 int namespaces_only, int flags)
 {
-  tree t;
+  cxx_binding *iter;
   tree val = NULL_TREE;
-  int yylex = 0;
-  tree from_obj = NULL_TREE;
-  int flags;
-  int val_is_implicit_typename = 0;
 
-  /* Hack: copy flag set by parser, if set.  */
-  if (only_namespace_names)
-    namespaces_only = 1;
-
-  if (prefer_type == -2)
+  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)) 
     {
-      extern int looking_for_typename;
-      tree type = NULL_TREE;
+      struct cp_binding_level *level;
 
-      yylex = 1;
-      prefer_type = looking_for_typename;
-
-      flags = lookup_flags (prefer_type, namespaces_only);
-      /* If the next thing is '<', class templates are types.  */
-      if (looking_for_template)
-        flags |= LOOKUP_TEMPLATES_EXPECTED;
-
-      if (got_scope)
-       type = got_scope;
-      else if (got_object != error_mark_node)
-       type = got_object;
-
-      if (type)
+      for (level = current_binding_level; 
+          level && !level->namespace_p; 
+          level = level->level_chain)
        {
-         if (type == error_mark_node)
-           return error_mark_node;
-         if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
-           type = TREE_TYPE (type);
-
-         if (TYPE_P (type))
-           type = complete_type (type);
-
-         if (TREE_CODE (type) == VOID_TYPE)
-           type = global_namespace;
-         if (TREE_CODE (type) == NAMESPACE_DECL)
-           {
-             val = make_node (CPLUS_BINDING);
-             flags |= LOOKUP_COMPLAIN;
-             if (!qualified_lookup_using_namespace (name, type, val, flags))
-               return NULL_TREE;
-             val = select_decl (val, flags);
-           }
-         else if (! IS_AGGR_TYPE (type)
-                  || TREE_CODE (type) == TEMPLATE_TYPE_PARM
-                  || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
-                  || TREE_CODE (type) == TYPENAME_TYPE)
-           /* Someone else will give an error about this if needed.  */
-           val = NULL_TREE;
-         else if (type == current_class_type)
-           val = IDENTIFIER_CLASS_VALUE (name);
-         else
-           {
-             val = lookup_member (type, name, 0, prefer_type);
-             if (!uses_template_parms (type))
-               type_access_control (type, val);
-
-             /* Restore the containing TYPENAME_TYPE if we looked
-                through it before.  */
-             if (got_scope && got_scope != type
-                 && val && TREE_CODE (val) == TYPE_DECL
-                 && TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE)
-               {
-                 val = TREE_TYPE (val);
-                 val = build_typename_type (got_scope, name,
-                                            TYPENAME_TYPE_FULLNAME (val),
-                                            TREE_TYPE (val));
-                 val = TYPE_STUB_DECL (val);
-               }
-           }
+         tree class_type;
+         tree operators;
+         
+         /* A conversion operator can only be declared in a class 
+            scope.  */
+         if (level->parm_flag != 2)
+           continue;
+         
+         /* Lookup the conversion operator in the class.  */
+         class_type = level->this_class;
+         operators = lookup_fnfields (class_type, name, /*protect=*/0);
+         if (operators)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
        }
-      else
-       val = NULL_TREE;
 
-      if (got_scope)
-       goto done;
-      else if (got_object && val)
-       {
-         from_obj = val;
-         val = NULL_TREE;
-       }
-    }
-  else
-    {
-      flags = lookup_flags (prefer_type, namespaces_only);
-      /* If we're not parsing, we need to complain.  */
-      flags |= LOOKUP_COMPLAIN;
+      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 (t = IDENTIFIER_BINDING (name); t; t = TREE_CHAIN (t))
+  for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
     {
       tree binding;
 
-      if (!LOCAL_BINDING_P (t) && nonclass)
+      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 (BINDING_VALUE (t), flags))
-       binding = BINDING_VALUE (t);
+      if (qualify_lookup (BINDING_VALUE (iter), flags))
+       binding = BINDING_VALUE (iter);
       else if ((flags & LOOKUP_PREFER_TYPES)
-              && qualify_lookup (BINDING_TYPE (t), flags))
-       binding = BINDING_TYPE (t);
+              && qualify_lookup (BINDING_TYPE (iter), flags))
+       binding = BINDING_TYPE (iter);
       else
        binding = NULL_TREE;
 
-      /* Handle access control on types from enclosing or base classes.  */
-      if (binding && ! yylex
-         && BINDING_LEVEL (t) && BINDING_LEVEL (t)->parm_flag == 2)
-       type_access_control (BINDING_LEVEL (t)->this_class, binding);
-
-      if (binding
-         && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
+      if (binding)
        {
-         if (val_is_implicit_typename && !yylex)
-           warn_about_implicit_typename_lookup (val, binding);
          val = binding;
-         val_is_implicit_typename
-           = IMPLICIT_TYPENAME_TYPE_DECL_P (val);
-         if (!val_is_implicit_typename)
-           break;
+         break;
        }
     }
 
   /* Now lookup in namespace scopes.  */
-  if (!val || val_is_implicit_typename)
+  if (!val)
     {
-      t = unqualified_namespace_lookup (name, flags, 0);
+      tree t = unqualified_namespace_lookup (name, flags, 0);
       if (t)
-       {
-         if (val_is_implicit_typename && !yylex)
-           warn_about_implicit_typename_lookup (val, t);
-         val = t;
-       }
+       val = t;
     }
 
- done:
   if (val)
     {
-      /* This should only warn about types used in qualified-ids.  */
-      if (from_obj && from_obj != val)
-       {
-         if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
-             && TREE_CODE (val) == TYPE_DECL
-             && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
-           pedwarn ("\
-lookup of `%D' in the scope of `%#T' (`%#D') \
-does not match lookup in the current scope (`%#D')",
-                       name, got_object, from_obj, val);
-
-         /* We don't change val to from_obj if got_object depends on
-            template parms because that breaks implicit typename for
-            destructor calls.  */
-         if (! uses_template_parms (got_object))
-           val = from_obj;
-       }
-
       /* 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);
     }
-  else if (from_obj)
-    val = from_obj;
 
-  return val;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
 }
 
 tree
-lookup_name_nonclass (name)
-     tree name;
+lookup_name_nonclass (tree name)
 {
-  return lookup_name_real (name, 0, 1, 0);
+  return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN);
 }
 
 tree
-lookup_function_nonclass (name, args)
-     tree name;
-     tree args;
+lookup_function_nonclass (tree name, tree args)
 {
   return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
 }
 
 tree
-lookup_name_namespace_only (name)
-     tree name;
+lookup_name (tree name, int prefer_type)
 {
-  /* type-or-namespace, nonclass, namespace_only */
-  return lookup_name_real (name, 1, 1, 1);
-}
-
-tree
-lookup_name (name, prefer_type)
-     tree name;
-     int prefer_type;
-{
-  return lookup_name_real (name, prefer_type, 0, 0);
+  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 (name)
-     tree name;
+lookup_name_current_level (tree name)
 {
   struct cp_binding_level *b;
   tree t = NULL_TREE;
 
+  timevar_push (TV_NAME_LOOKUP);
   b = current_binding_level;
   while (b->parm_flag == 2)
     b = b->level_chain;
@@ -6284,8 +5965,8 @@ lookup_name_current_level (name)
     {
       while (1)
        {
-         if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b)
-           return IDENTIFIER_VALUE (name);
+         if (BINDING_SCOPE (IDENTIFIER_BINDING (name)) == b)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
 
          if (b->keep == 2)
            b = b->level_chain;
@@ -6294,17 +5975,17 @@ lookup_name_current_level (name)
        }
     }
 
-  return t;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
 /* Like lookup_name_current_level, but for types.  */
 
 tree
-lookup_type_current_level (name)
-     tree name;
+lookup_type_current_level (tree name)
 {
   register tree t = NULL_TREE;
 
+  timevar_push (TV_NAME_LOOKUP);
   my_friendly_assert (! current_binding_level->namespace_p, 980716);
 
   if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
@@ -6314,7 +5995,8 @@ lookup_type_current_level (name)
       while (1)
        {
          if (purpose_member (name, b->type_shadowed))
-           return REAL_IDENTIFIER_TYPE_VALUE (name);
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+                                    REAL_IDENTIFIER_TYPE_VALUE (name));
          if (b->keep == 2)
            b = b->level_chain;
          else
@@ -6322,20 +6004,9 @@ lookup_type_current_level (name)
        }
     }
 
-  return t;
-}
-
-void
-begin_only_namespace_names ()
-{
-  only_namespace_names = 1;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
-void
-end_only_namespace_names ()
-{
-  only_namespace_names = 0;
-}
 \f
 /* Push the declarations of builtin types into the namespace.
    RID_INDEX is the index of the builtin type
@@ -6343,10 +6014,9 @@ end_only_namespace_names ()
    up the builtin type.  TYPE is the _TYPE node for the builtin type.  */
 
 void
-record_builtin_type (rid_index, name, type)
-     enum rid rid_index;
-     const char *name;
-     tree type;
+record_builtin_type (enum rid rid_index, 
+                     const char* name, 
+                     tree type)
 {
   tree rname = NULL_TREE, tname = NULL_TREE;
   tree tdecl = NULL_TREE;
@@ -6356,8 +6026,6 @@ record_builtin_type (rid_index, name, type)
   if (name)
     tname = get_identifier (name);
 
-  TYPE_BUILT_IN (type) = 1;
-
   if (tname)
     {
       tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
@@ -6387,9 +6055,7 @@ record_builtin_type (rid_index, name, type)
  * otherwise it is the negative of the size of one of the other types.  */
 
 static tree
-record_builtin_java_type (name, size)
-     const char *name;
-     int size;
+record_builtin_java_type (const char* name, int size)
 {
   tree type, decl;
   if (size > 0)
@@ -6420,9 +6086,7 @@ record_builtin_java_type (name, size)
 /* Push a type into the namespace so that the back-ends ignore it.  */
 
 static void
-record_unknown_type (type, name)
-     tree type;
-     const char *name;
+record_unknown_type (tree type, const char* name)
 {
   tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
   /* Make sure the "unknown type" typedecl gets ignored for debug info.  */
@@ -6450,7 +6114,7 @@ typedef struct predefined_identifier
 /* Create all the predefined identifiers.  */
 
 static void
-initialize_predefined_identifiers ()
+initialize_predefined_identifiers (void)
 {
   const predefined_identifier *pid;
 
@@ -6491,7 +6155,7 @@ initialize_predefined_identifiers ()
    Make definitions for built-in primitive functions.  */
 
 void
-cxx_init_decl_processing ()
+cxx_init_decl_processing (void)
 {
   tree void_ftype;
   tree void_ftype_ptr;
@@ -6550,6 +6214,10 @@ cxx_init_decl_processing ()
   NAMESPACE_LEVEL (global_namespace) = global_binding_level;
   declare_namespace_level ();
 
+  VARRAY_TREE_INIT (global_binding_level->static_decls,
+                   200,
+                   "Static declarations");
+
   /* Create the `std' namespace.  */
   push_namespace (std_identifier);
   std_node = current_namespace;
@@ -6699,8 +6367,7 @@ cxx_init_decl_processing ()
    ERROR_MARK node which should be replaced later.  */
 
 tree
-cp_fname_init (name)
-     const char *name;
+cp_fname_init (const char* name)
 {
   tree domain = NULL_TREE;
   tree type;
@@ -6734,16 +6401,14 @@ cp_fname_init (name)
    lazily at the point of first use, so we musn't push the decl now.  */
 
 static tree
-cp_make_fname_decl (id, type_dep)
-     tree id;
-     int type_dep;
+cp_make_fname_decl (tree id, int type_dep)
 {
   const char *const name = (type_dep && processing_template_decl
                      ? NULL : fname_as_string (type_dep));
   tree init = cp_fname_init (name);
   tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init));
 
-  /* As we don't push the decl here, we must set the context.  */
+  /* As we're using pushdecl_with_scope, we must set the context.  */
   DECL_CONTEXT (decl) = current_function_decl;
   DECL_PRETTY_FUNCTION_P (decl) = type_dep;
       
@@ -6754,6 +6419,14 @@ cp_make_fname_decl (id, type_dep)
   
   TREE_USED (decl) = 1;
 
+  if (current_function_decl)
+    {
+      struct cp_binding_level *b = current_binding_level;
+      while (b->level_chain->parm_flag == 0)
+       b = b->level_chain;
+      pushdecl_with_scope (decl, b);
+    }  
+
   cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
       
   return decl;
@@ -6772,14 +6445,13 @@ cp_make_fname_decl (id, type_dep)
    list.  */
 
 static tree
-builtin_function_1 (name, type, context, code, class, libname, attrs)
-     const char *name;
-     tree type;
-     tree context;
-     int code;
-     enum built_in_class class;
-     const char *libname;
-     tree attrs;
+builtin_function_1 (const char* name,
+                    tree type,
+                    tree context,
+                    int code,
+                    enum built_in_class class,
+                    const char* libname,
+                    tree attrs)
 {
   tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
   DECL_BUILT_IN_CLASS (decl) = class;
@@ -6826,13 +6498,12 @@ builtin_function_1 (name, type, context, code, class, libname, attrs)
    list.  */
 
 tree
-builtin_function (name, type, code, class, libname, attrs)
-     const char *name;
-     tree type;
-     int code;
-     enum built_in_class class;
-     const char *libname;
-     tree attrs;
+builtin_function (const char* name,
+                  tree type,
+                  int code,
+                  enum built_in_class class,
+                  const char* libname,
+                  tree attrs)
 {
   /* All builtins that don't begin with an '_' should additionally
      go in the 'std' namespace.  */
@@ -6851,10 +6522,7 @@ builtin_function (name, type, code, class, libname, attrs)
    function.  Not called directly.  */
 
 static tree
-build_library_fn_1 (name, operator_code, type)
-     tree name;
-     enum tree_code operator_code;
-     tree type;
+build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
 {
   tree fn = build_lang_decl (FUNCTION_DECL, name, type);
   DECL_EXTERNAL (fn) = 1;
@@ -6871,9 +6539,7 @@ build_library_fn_1 (name, operator_code, type)
    callers should unset TREE_NOTHROW.  */
 
 tree
-build_library_fn (name, type)
-     tree name;
-     tree type;
+build_library_fn (tree name, tree type)
 {
   return build_library_fn_1 (name, ERROR_MARK, type);
 }
@@ -6881,10 +6547,7 @@ build_library_fn (name, type)
 /* Returns the _DECL for a library function with C++ linkage.  */
 
 static tree
-build_cp_library_fn (name, operator_code, type)
-     tree name;
-     enum tree_code operator_code;
-     tree type;
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
 {
   tree fn = build_library_fn_1 (name, operator_code, type);
   TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
@@ -6898,9 +6561,7 @@ build_cp_library_fn (name, operator_code, type)
    IDENTIFIER_NODE.  */
 
 tree
-build_library_fn_ptr (name, type)
-     const char *name;
-     tree type;
+build_library_fn_ptr (const char* name, tree type)
 {
   return build_library_fn (get_identifier (name), type);
 }
@@ -6909,9 +6570,7 @@ build_library_fn_ptr (name, type)
    IDENTIFIER_NODE.  */
 
 tree
-build_cp_library_fn_ptr (name, type)
-     const char *name;
-     tree type;
+build_cp_library_fn_ptr (const char* name, tree type)
 {
   return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
 }
@@ -6920,8 +6579,7 @@ build_cp_library_fn_ptr (name, type)
    be able to find it via IDENTIFIER_GLOBAL_VALUE.  */
 
 tree
-push_library_fn (name, type)
-     tree name, type;
+push_library_fn (tree name, tree type)
 {
   tree fn = build_library_fn (name, type);
   pushdecl_top_level (fn);
@@ -6932,9 +6590,7 @@ push_library_fn (name, type)
    will be found by normal lookup.  */
 
 static tree
-push_cp_library_fn (operator_code, type)
-     enum tree_code operator_code;
-     tree type;
+push_cp_library_fn (enum tree_code operator_code, tree type)
 {
   tree fn = build_cp_library_fn (ansi_opname (operator_code),
                                 operator_code,
@@ -6947,8 +6603,7 @@ push_cp_library_fn (operator_code, type)
    a FUNCTION_TYPE.  */
 
 tree
-push_void_library_fn (name, parmtypes)
-     tree name, parmtypes;
+push_void_library_fn (tree name, tree parmtypes)
 {
   tree type = build_function_type (void_type_node, parmtypes);
   return push_library_fn (name, type);
@@ -6958,8 +6613,7 @@ push_void_library_fn (name, parmtypes)
    and does not return.  Used for __throw_foo and the like.  */
 
 tree
-push_throw_library_fn (name, type)
-     tree name, type;
+push_throw_library_fn (tree name, tree type)
 {
   tree fn = push_library_fn (name, type);
   TREE_THIS_VOLATILE (fn) = 1;
@@ -6971,8 +6625,7 @@ push_throw_library_fn (name, type)
    attributes.  */
 
 void
-cxx_insert_default_attributes (decl)
-     tree decl;
+cxx_insert_default_attributes (tree decl)
 {
   if (!DECL_EXTERN_C_FUNCTION_P (decl))
     return;
@@ -6992,8 +6645,7 @@ cxx_insert_default_attributes (decl)
    union type.)  */
 
 void
-fixup_anonymous_aggr (t)
-     tree t;
+fixup_anonymous_aggr (tree t)
 {
   tree *q;
 
@@ -7049,24 +6701,28 @@ fixup_anonymous_aggr (t)
 }
 
 /* Make sure that a declaration with no declarator is well-formed, i.e.
-   just defines a tagged type or anonymous union.
+   just declares a tagged type or anonymous union.
 
-   Returns the type defined, if any.  */
+   Returns the type declared; or NULL_TREE if none.  */
 
 tree
-check_tag_decl (declspecs)
-     tree declspecs;
+check_tag_decl (tree declspecs)
 {
   int found_type = 0;
   int saw_friend = 0;
   int saw_typedef = 0;
   tree ob_modifier = NULL_TREE;
   register tree link;
-  register tree t = NULL_TREE;
+  /* If a class, struct, or enum type is declared by the DECLSPECS
+     (i.e, if a class-specifier, enum-specifier, or non-typename
+     elaborated-type-specifier appears in the DECLSPECS),
+     DECLARED_TYPE is set to the corresponding type.  */
+  tree declared_type = NULL_TREE;
+  bool error_p = false;
 
   for (link = declspecs; link; link = TREE_CHAIN (link))
     {
-      register tree value = TREE_VALUE (link);
+      tree value = TREE_VALUE (link);
 
       if (TYPE_P (value)
          || TREE_CODE (value) == TYPE_DECL
@@ -7088,7 +6744,7 @@ check_tag_decl (declspecs)
                  || TREE_CODE (value) == ENUMERAL_TYPE))
            {
              my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
-             t = value;
+             declared_type = value;
            }
        }
       else if (value == ridpointers[(int) RID_TYPEDEF])
@@ -7112,17 +6768,18 @@ check_tag_decl (declspecs)
               || value == ridpointers[(int) RID_EXPLICIT]
               || value == ridpointers[(int) RID_THREAD])
        ob_modifier = value;
+      else if (value == error_mark_node)
+       error_p = true;
     }
 
   if (found_type > 1)
     error ("multiple types in one declaration");
 
-  if (t == NULL_TREE && ! saw_friend)
+  if (declared_type == NULL_TREE && ! saw_friend && !error_p)
     pedwarn ("declaration does not declare anything");
-
   /* Check for an anonymous union.  */
-  else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t))
-          && TYPE_ANONYMOUS_P (t))
+  else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type))
+          && TYPE_ANONYMOUS_P (declared_type))
     {
       /* 7/3 In a simple-declaration, the optional init-declarator-list
          can be omitted only when declaring a class (clause 9) or
@@ -7146,9 +6803,10 @@ check_tag_decl (declspecs)
           return NULL_TREE;
         }
       /* Anonymous unions are objects, so they can have specifiers.  */;
-      SET_ANON_AGGR_TYPE_P (t);
+      SET_ANON_AGGR_TYPE_P (declared_type);
 
-      if (TREE_CODE (t) != UNION_TYPE && pedantic && ! in_system_header)
+      if (TREE_CODE (declared_type) != UNION_TYPE && pedantic 
+         && !in_system_header)
        pedwarn ("ISO C++ prohibits anonymous structs");
     }
 
@@ -7167,7 +6825,7 @@ check_tag_decl (declspecs)
                  ob_modifier);
     }
 
-  return t;
+  return declared_type;
 }
 
 /* Called when a declaration is seen that contains no names to declare.
@@ -7179,23 +6837,26 @@ check_tag_decl (declspecs)
    Otherwise, it is an error.
 
    C++: may have to grok the declspecs to learn about static,
-   complain for anonymous unions.  */
+   complain for anonymous unions.  
 
-void
-shadow_tag (declspecs)
-     tree declspecs;
+   Returns the TYPE declared -- or NULL_TREE if none.  */
+
+tree
+shadow_tag (tree declspecs)
 {
   tree t = check_tag_decl (declspecs);
 
-  if (t)
-    maybe_process_partial_specialization (t);
+  if (!t)
+    return NULL_TREE;
+
+  maybe_process_partial_specialization (t);
 
   /* This is where the variables in an anonymous union are
      declared.  An anonymous union declaration looks like:
      union { ... } ;
      because there is no declarator after the union, the parser
      sends that declaration here.  */
-  if (t && ANON_AGGR_TYPE_P (t))
+  if (ANON_AGGR_TYPE_P (t))
     {
       fixup_anonymous_aggr (t);
 
@@ -7206,13 +6867,14 @@ shadow_tag (declspecs)
          finish_anon_union (decl);
        }
     }
+
+  return t;
 }
 \f
 /* Decode a "typename", such as "int **", returning a ..._TYPE node.  */
 
 tree
-groktypename (typename)
-     tree typename;
+groktypename (tree typename)
 {
   tree specs, attrs;
   tree type;
@@ -7242,20 +6904,16 @@ groktypename (typename)
    grokfield and not through here.  */
 
 tree
-start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
-     tree declarator, declspecs;
-     int initialized;
-     tree attributes, prefix_attributes;
+start_decl (tree declarator, 
+            tree declspecs, 
+            int initialized, 
+            tree attributes, 
+            tree prefix_attributes)
 {
   tree decl;
   register tree type, tem;
   tree context;
 
-#if 0
-  /* See code below that used this.  */
-  int init_written = initialized;
-#endif
-
   /* This should only be done once on the top most decl.  */
   if (have_extern_spec)
     {
@@ -7345,25 +7003,26 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
-    warning_with_decl (decl,
-                      "inline function `%s' given attribute noinline");
+    warning ("%Hinline function '%D' given attribute noinline",
+             &DECL_SOURCE_LOCATION (decl), decl);
 
   if (context && COMPLETE_TYPE_P (complete_type (context)))
     {
-      push_nested_class (context, 2);
+      push_nested_class (context);
 
       if (TREE_CODE (decl) == VAR_DECL)
        {
-         tree field = lookup_field (context, DECL_NAME (decl), 0, 0);
+         tree field = lookup_field (context, DECL_NAME (decl), 0, false);
          if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL)
            error ("`%#D' is not a static member of `%#T'", decl, context);
          else
            {
              if (DECL_CONTEXT (field) != context)
                {
-                 pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
-                             DECL_CONTEXT (field), DECL_NAME (decl),
-                             context, DECL_NAME (decl));
+                 if (!same_type_p (DECL_CONTEXT (field), context))
+                   pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
+                            DECL_CONTEXT (field), DECL_NAME (decl),
+                            context, DECL_NAME (decl));
                  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
                }
              /* Static data member are tricky; an in-class initialization
@@ -7417,7 +7076,9 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
      wrong semantics.  If we say -fno-conserve-space, we want this to
      produce errors about redefs; to do this we force variables into the
      data segment.  */
-  DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
+  DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL
+                       || !DECL_THREAD_LOCAL (tem))
+                      && (flag_conserve_space || ! TREE_PUBLIC (tem)));
 #endif
 
   if (! processing_template_decl)
@@ -7427,8 +7088,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
 }
 
 void
-start_decl_1 (decl)
-     tree decl;
+start_decl_1 (tree decl)
 {
   tree type = TREE_TYPE (decl);
   int initialized = (DECL_INITIAL (decl) != NULL_TREE);
@@ -7502,8 +7162,7 @@ start_decl_1 (decl)
    Quotes on semantics can be found in ARM 8.4.3.  */
 
 static tree
-grok_reference_init (decl, type, init)
-     tree decl, type, init;
+grok_reference_init (tree decl, tree type, tree init)
 {
   tree tmp;
 
@@ -7516,9 +7175,6 @@ grok_reference_init (decl, type, init)
       return NULL_TREE;
     }
 
-  if (init == error_mark_node)
-    return NULL_TREE;
-
   if (TREE_CODE (init) == CONSTRUCTOR)
     {
       error ("ISO C++ forbids use of initializer list to initialize reference `%D'", decl);
@@ -7545,10 +7201,7 @@ grok_reference_init (decl, type, init)
      DECL_INITIAL for local references (instead assigning to them
      explicitly); we need to allow the temporary to be initialized
      first.  */
-  tmp = convert_to_reference
-    (type, init, CONV_IMPLICIT,
-     LOOKUP_ONLYCONVERTING|LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND,
-     decl);
+  tmp = initialize_reference (type, init, decl);
 
   if (tmp == error_mark_node)
     return NULL_TREE;
@@ -7571,9 +7224,7 @@ grok_reference_init (decl, type, init)
    situation we're in, update DECL accordingly.  */
 
 static void
-maybe_deduce_size_from_array_init (decl, init)
-     tree decl;
-     tree init;
+maybe_deduce_size_from_array_init (tree decl, tree init)
 {
   tree type = TREE_TYPE (decl);
 
@@ -7615,8 +7266,7 @@ maybe_deduce_size_from_array_init (decl, init)
    any appropriate error messages regarding the layout.  */
 
 static void
-layout_var_decl (decl)
-     tree decl;
+layout_var_decl (tree decl)
 {
   tree type = TREE_TYPE (decl);
 #if 0
@@ -7680,8 +7330,7 @@ layout_var_decl (decl)
    instance of the variable at link-time.  */
 
 static void
-maybe_commonize_var (decl)
-     tree decl;
+maybe_commonize_var (tree decl)
 {
   /* Static data in a function with comdat linkage also has comdat
      linkage.  */
@@ -7732,8 +7381,7 @@ maybe_commonize_var (decl)
 /* Issue an error message if DECL is an uninitialized const variable.  */
 
 static void
-check_for_uninitialized_const_var (decl)
-     tree decl;
+check_for_uninitialized_const_var (tree decl)
 {
   tree type = TREE_TYPE (decl);
 
@@ -7793,6 +7441,14 @@ reshape_init (tree type, tree *initp)
   old_init_value = (TREE_CODE (*initp) == TREE_LIST
                    ? TREE_VALUE (*initp) : old_init);
 
+  /* For some parse errors, OLD_INIT_VALUE may be NULL.  */
+  if (!old_init_value)
+    {
+      my_friendly_assert (TREE_CODE (old_init) == TREE_LIST, 20021202);
+      TREE_VALUE (old_init) = error_mark_node;
+      return old_init;
+    }
+
   /* If the initializer is brace-enclosed, pull initializers from the
      enclosed elements.  Advance past the brace-enclosed initializer
      now.  */
@@ -7868,7 +7524,7 @@ reshape_init (tree type, tree *initp)
   else
     {
       /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */  
-      new_init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+      new_init = build_constructor (type, NULL_TREE);
       TREE_HAS_CONSTRUCTOR (new_init) = 1;
 
       if (CLASS_TYPE_P (type))
@@ -7892,6 +7548,7 @@ reshape_init (tree type, tree *initp)
            {
              /* Loop through the initializable fields, gathering
                 initializers.  */
+              /* FIXME support non-trivial labeled initializers.  */
              while (*initp && field)
                {
                  tree field_init;
@@ -7906,8 +7563,6 @@ reshape_init (tree type, tree *initp)
                     initializer for the first member of the union.  */
                  if (TREE_CODE (type) == UNION_TYPE)
                    break;
-                 if (TREE_PURPOSE (field_init))
-                   field = TREE_PURPOSE (field_init);
                  field = next_initializable_field (TREE_CHAIN (field));
                }
            }
@@ -8027,6 +7682,12 @@ check_initializer (tree decl, tree init, int flags)
             scalar, so just don't call it.  */
          if (CP_AGGREGATE_TYPE_P (type))
            init = reshape_init (type, &init);
+
+         if ((*targetm.vector_opaque_p) (type))
+           {
+             error ("opaque vector types cannot be initialized");
+             init = error_mark_node;
+           }
        }
 
       /* If DECL has an array type without a specific bound, deduce the
@@ -8105,10 +7766,7 @@ check_initializer (tree decl, tree init, int flags)
 /* If DECL is not a local variable, give it RTL.  */
 
 static void
-make_rtl_for_nonlocal_decl (decl, init, asmspec)
-     tree decl;
-     tree init;
-     const char *asmspec;
+make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
 {
   int toplev = toplevel_bindings_p ();
   int defer_p;
@@ -8193,17 +7851,23 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
    declaration into the surrounding scope.  */
 
 void
-maybe_inject_for_scope_var (decl)
-     tree decl;
+maybe_inject_for_scope_var (tree decl)
 {
+  timevar_push (TV_NAME_LOOKUP);
   if (!DECL_NAME (decl))
-    return;
+    {
+      timevar_pop (TV_NAME_LOOKUP);
+      return;
+    }
   
   /* Declarations of __FUNCTION__ and its ilk appear magically when
      the variable is first used.  If that happens to be inside a
      for-loop, we don't want to do anything special.  */
   if (DECL_PRETTY_FUNCTION_P (decl))
-    return;
+    {
+      timevar_pop (TV_NAME_LOOKUP);
+      return;
+    }
 
   if (current_binding_level->is_for_scope)
     {
@@ -8219,29 +7883,25 @@ maybe_inject_for_scope_var (decl)
         Otherwise, we need to preserve the temp slot for decl to last
         into the outer binding level.  */
 
-      tree outer_binding
-       = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl)));
+      cxx_binding *outer_binding
+       = IDENTIFIER_BINDING (DECL_NAME (decl))->previous;
 
-      if (outer_binding && BINDING_LEVEL (outer_binding) == outer
-         && (TREE_CODE (BINDING_VALUE (outer_binding))
-             == VAR_DECL)
+      if (outer_binding && BINDING_SCOPE (outer_binding) == outer
+         && (TREE_CODE (BINDING_VALUE (outer_binding)) == VAR_DECL)
          && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
        {
          BINDING_VALUE (outer_binding)
            = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding));
          current_binding_level->is_for_scope = 0;
        }
-      else if (DECL_IN_MEMORY_P (decl))
-       preserve_temp_slots (DECL_RTL (decl));
     }
+  timevar_pop (TV_NAME_LOOKUP);
 }
 
 /* Generate code to initialize DECL (a local variable).  */
 
 static void
-initialize_local_var (decl, init)
-     tree decl;
-     tree init;
+initialize_local_var (tree decl, tree init)
 {
   tree type = TREE_TYPE (decl);
 
@@ -8318,10 +7978,7 @@ initialize_local_var (decl, init)
    if the (init) syntax was used.  */
 
 void
-cp_finish_decl (decl, init, asmspec_tree, flags)
-     tree decl, init;
-     tree asmspec_tree;
-     int flags;
+cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 {
   register tree type;
   tree ttype = NULL_TREE;
@@ -8473,6 +8130,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
             necessary zero-initialization has already been performed.  */
          if (TREE_STATIC (decl) && !DECL_INITIAL (decl))
            DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl),
+                                                  /*nelts=*/NULL_TREE,
                                                   /*static_storage_p=*/true);
          /* Remember that the initialization for this variable has
             taken place.  */
@@ -8578,9 +8236,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
 /* This is here for a midend callback from c-common.c */
 
 void
-finish_decl (decl, init, asmspec_tree)
-     tree decl, init;
-     tree asmspec_tree;
+finish_decl (tree decl, tree init, tree asmspec_tree)
 {
   cp_finish_decl (decl, init, asmspec_tree, 0);
 }
@@ -8593,9 +8249,7 @@ finish_decl (decl, init, asmspec_tree)
    variables.  */
 
 tree
-declare_global_var (name, type)
-     tree name;
-     tree type;
+declare_global_var (tree name, tree type)
 {
   tree decl;
 
@@ -8616,7 +8270,7 @@ declare_global_var (name, type)
    `__cxa_atexit' function specified in the IA64 C++ ABI.  */
 
 static tree
-get_atexit_node ()
+get_atexit_node (void)
 {
   tree atexit_fndecl;
   tree arg_types;
@@ -8679,7 +8333,7 @@ get_atexit_node ()
 /* Returns the __dso_handle VAR_DECL.  */
 
 static tree
-get_dso_handle_node ()
+get_dso_handle_node (void)
 {
   if (dso_handle_node)
     return dso_handle_node;
@@ -8695,7 +8349,7 @@ get_dso_handle_node ()
    to destroy some particular variable.  */
 
 static tree
-start_cleanup_fn ()
+start_cleanup_fn (void)
 {
   static int counter = 0;
   int old_interface_only = interface_only;
@@ -8761,7 +8415,7 @@ start_cleanup_fn ()
 /* Finish the cleanup function begun by start_cleanup_fn.  */
 
 static void
-end_cleanup_fn ()
+end_cleanup_fn (void)
 {
   expand_body (finish_function (0));
 
@@ -8772,14 +8426,12 @@ end_cleanup_fn ()
    static storage duration.  */
 
 void
-register_dtor_fn (decl)
-     tree decl;
+register_dtor_fn (tree decl)
 {
   tree cleanup;
   tree compound_stmt;
   tree args;
   tree fcall;
-
   int saved_flag_access_control;
 
   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
@@ -8798,9 +8450,9 @@ register_dtor_fn (decl)
      will make the back-end think that nested functions are in use,
      which causes confusion.  */
   saved_flag_access_control = flag_access_control;
-  flag_access_control = 0;
+  scope_chain->check_access = flag_access_control = 0;
   fcall = build_cleanup (decl);
-  flag_access_control = saved_flag_access_control;
+  scope_chain->check_access = flag_access_control = saved_flag_access_control;
 
   /* Create the body of the anonymous function.  */
   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
@@ -8829,9 +8481,7 @@ register_dtor_fn (decl)
    and destruction of DECL.  */
 
 static void
-expand_static_init (decl, init)
-     tree decl;
-     tree init;
+expand_static_init (tree decl, tree init)
 {
   tree oldstatic;
 
@@ -8931,9 +8581,7 @@ expand_static_init (decl, init)
 /* Finish the declaration of a catch-parameter.  */
 
 tree
-start_handler_parms (declspecs, declarator)
-     tree declspecs;
-     tree declarator;
+start_handler_parms (tree declspecs, tree declarator)
 {
   tree decl;
   if (declspecs)
@@ -8955,9 +8603,7 @@ start_handler_parms (declspecs, declarator)
    2 if there was no information (in which case assume 0 if DO_DEFAULT).  */
 
 int
-complete_array_type (type, initial_value, do_default)
-     tree type, initial_value;
-     int do_default;
+complete_array_type (tree type, tree initial_value, int do_default)
 {
   register tree maxindex = NULL_TREE;
   int value = 0;
@@ -9052,9 +8698,7 @@ complete_array_type (type, initial_value, do_default)
    message to print in that case.  Otherwise, quietly return 1.  */
 
 static int
-member_function_or_else (ctype, cur_type, flags)
-     tree ctype, cur_type;
-     enum overload_flags flags;
+member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags)
 {
   if (ctype && ctype != cur_type)
     {
@@ -9075,10 +8719,13 @@ member_function_or_else (ctype, cur_type, flags)
    This is for ARM $7.1.2.  */
 
 static void
-bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
-     tree object;
-     const char *type;
-     int virtualp, quals, friendp, raises, inlinep;
+bad_specifiers (tree object,
+                const char* type,
+                int virtualp,
+                int quals,
+                int inlinep,
+                int friendp,
+                int raises)
 {
   if (virtualp)
     error ("`%D' declared as a `virtual' %s", object, type);
@@ -9113,17 +8760,21 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
    applicable error messages.  */
 
 static tree
-grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
-           raises, check, friendp, publicp, inlinep, funcdef_flag,
-           template_count, in_namespace)
-     tree ctype, type;
-     tree declarator;
-     tree orig_declarator;
-     int virtualp;
-     enum overload_flags flags;
-     tree quals, raises;
-     int check, friendp, publicp, inlinep, funcdef_flag, template_count;
-     tree in_namespace;
+grokfndecl (tree ctype, 
+            tree type,
+            tree declarator,
+            tree orig_declarator,
+            int virtualp,
+            enum overload_flags flags,
+            tree quals, 
+            tree raises,
+            int check, 
+            int friendp, 
+            int publicp, 
+            int inlinep, 
+            int funcdef_flag, 
+            int template_count,
+            tree in_namespace)
 {
   tree decl;
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
@@ -9225,13 +8876,19 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
       DECL_NOT_REALLY_EXTERN (decl) = 1;
     }
 
+  DID_INLINE_FUNC (decl) = 0;
   /* If the declaration was declared inline, mark it as such.  */
   if (inlinep)
     DECL_DECLARED_INLINE_P (decl) = 1;
   /* We inline functions that are explicitly declared inline, or, when
      the user explicitly asks us to, all functions.  */
-  if (DECL_DECLARED_INLINE_P (decl) || flag_inline_trees == 2)
+  if (DECL_DECLARED_INLINE_P (decl))
     DECL_INLINE (decl) = 1;
+  if (flag_inline_trees == 2 && !DECL_INLINE (decl))
+    {
+      DID_INLINE_FUNC (decl) = 1;
+      DECL_INLINE (decl) = 1;
+    }
 
   DECL_EXTERNAL (decl) = 1;
   if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
@@ -9312,9 +8969,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        }
     }
 
-  if (has_default_arg)
-    add_defarg_fn (decl);
-
   if (funcdef_flag)
     /* Make the init_value nonzero so pushdecl knows this is not
        tentative.  error_mark_node is replaced later with the BLOCK.  */
@@ -9327,7 +8981,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
   if (check < 0)
     return decl;
 
-  if (flags == NO_SPECIAL && ctype && constructor_name (ctype) == declarator)
+  if (flags == NO_SPECIAL && ctype && constructor_name_p (declarator, ctype))
     DECL_CONSTRUCTOR_P (decl) = 1;
 
   /* Function gets the ugly name, field gets the nice one.  This call
@@ -9371,6 +9025,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
       if (old_decl)
        {
+         bool ok;
+
          /* Since we've smashed OLD_DECL to its
             DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
          if (TREE_CODE (decl) == TEMPLATE_DECL)
@@ -9378,9 +9034,15 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
 
          /* Attempt to merge the declarations.  This can fail, in
             the case of some invalid specialization declarations.  */
-         if (!duplicate_decls (decl, old_decl))
-           error ("no `%#D' member function declared in class `%T'",
-                     decl, ctype);
+         push_scope (ctype);
+         ok = duplicate_decls (decl, old_decl);
+         pop_scope (ctype);
+         if (!ok)
+           {
+             error ("no `%#D' member function declared in class `%T'",
+                    decl, ctype);
+             return NULL_TREE;
+           }
          return old_decl;
        }
     }
@@ -9404,13 +9066,12 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
    the innermost enclosings scope.  */
 
 static tree
-grokvardecl (type, name, specbits_in, initialized, constp, scope)
-     tree type;
-     tree name;
-     RID_BIT_TYPE *specbits_in;
-     int initialized;
-     int constp;
-     tree scope;
+grokvardecl (tree type,
+             tree name,
+             RID_BIT_TYPE * specbits_in,
+             int initialized,
+             int constp,
+             tree scope)
 {
   tree decl;
   RID_BIT_TYPE specbits;
@@ -9524,10 +9185,9 @@ grokvardecl (type, name, specbits_in, initialized, constp, scope)
    TYPE, which is a POINTER_TYPE to a METHOD_TYPE.  */
 
 tree
-build_ptrmemfunc_type (type)
-     tree type;
+build_ptrmemfunc_type (tree type)
 {
-  tree fields[4];
+  tree field, fields;
   tree t;
   tree unqualified_variant = NULL_TREE;
 
@@ -9553,10 +9213,14 @@ build_ptrmemfunc_type (type)
   /* ... and not really an aggregate.  */
   SET_IS_AGGR_TYPE (t, 0);
 
-  fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
-  fields[1] = build_decl (FIELD_DECL, delta_identifier,
-                         delta_type_node);
-  finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
+  field = build_decl (FIELD_DECL, pfn_identifier, type);
+  fields = field;
+  
+  field = build_decl (FIELD_DECL, delta_identifier, delta_type_node);
+  TREE_CHAIN (field) = fields;
+  fields = field;
+  
+  finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node);
 
   /* Zap out the name so that the back-end will give us the debugging
      information for this anonymous RECORD_TYPE.  */
@@ -9598,9 +9262,7 @@ build_ptrmem_type (tree class_type, tree member_type)
    otherwise.  */
 
 int
-check_static_variable_definition (decl, type)
-     tree decl;
-     tree type;
+check_static_variable_definition (tree decl, tree type)
 {
   /* Motion 10 at San Diego: If a static const integral data member is
      initialized with an integral constant expression, the initializer
@@ -9608,10 +9270,10 @@ check_static_variable_definition (decl, type)
      the definition, but not both.  If it appears in the class, the
      member is a member constant.  The file-scope definition is always
      required.  */
-  if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
+  if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
     {
       error ("invalid in-class initialization of static data member of non-integral type `%T'",
-               type);
+            type);
       /* If we just return the declaration, crashes will sometimes
         occur.  We therefore return void_type_node, as if this was a
         friend declaration, to cause callers to completely ignore
@@ -9632,9 +9294,7 @@ check_static_variable_definition (decl, type)
    name of the thing being declared.  */
 
 tree
-compute_array_index_type (name, size)
-     tree name;
-     tree size;
+compute_array_index_type (tree name, tree size)
 {
   tree itype;
 
@@ -9651,7 +9311,7 @@ compute_array_index_type (name, size)
          && TREE_OPERAND (size, 0) == current_class_type)
        {
          tree t = lookup_field (current_class_type,
-                                TREE_OPERAND (size, 1), 0, 0);
+                                TREE_OPERAND (size, 1), 0, false);
          if (t)
            size = t;
        }
@@ -9757,15 +9417,53 @@ compute_array_index_type (name, size)
   return build_index_type (itype);
 }
 
+/* Returns the scope (if any) in which the entity declared by
+   DECLARATOR will be located.  If the entity was declared with an
+   unqualified name, NULL_TREE is returned.  */
+
+tree
+get_scope_of_declarator (tree declarator)
+{
+  if (!declarator)
+    return NULL_TREE;
+  
+  switch (TREE_CODE (declarator))
+    {
+    case CALL_EXPR:
+    case ARRAY_REF:
+    case INDIRECT_REF:
+    case ADDR_EXPR:
+      /* For any of these, the main declarator is the first operand.  */
+      return get_scope_of_declarator (TREE_OPERAND
+                                     (declarator, 0));
+
+    case SCOPE_REF:
+      /* For a pointer-to-member, continue descending.  */
+      if (TREE_CODE (TREE_OPERAND (declarator, 1))
+         == INDIRECT_REF)
+       return get_scope_of_declarator (TREE_OPERAND
+                                       (declarator, 1));
+      /* Otherwise, if the declarator-id is a SCOPE_REF, the scope in
+        which the declaration occurs is the first operand.  */
+      return TREE_OPERAND (declarator, 0);
+
+    case TREE_LIST:
+      /* Attributes to be applied. The declarator is TREE_VALUE.  */
+      return get_scope_of_declarator (TREE_VALUE (declarator));
+      
+    default:
+      /* Otherwise, we have a declarator-id which is not a qualified
+        name; the entity will be declared in the current scope.  */
+      return NULL_TREE;
+    }
+}
+
 /* Returns an ARRAY_TYPE for an array with SIZE elements of the
    indicated TYPE.  If non-NULL, NAME is the NAME of the declaration
    with this type.  */
 
 static tree
-create_array_type_for_decl (name, type, size)
-     tree name;
-     tree type;
-     tree size;
+create_array_type_for_decl (tree name, tree type, tree size)
 {
   tree itype = NULL_TREE;
   const char* error_msg;
@@ -9845,10 +9543,9 @@ create_array_type_for_decl (name, type, size)
    special functions.  */
 
 static tree
-check_special_function_return_type (sfk, type, optype)
-     special_function_kind sfk;
-     tree type;
-     tree optype;
+check_special_function_return_type (special_function_kind sfk,
+                                    tree type,
+                                    tree optype)
 {
   switch (sfk)
     {
@@ -9881,11 +9578,9 @@ check_special_function_return_type (sfk, type, optype)
   return type;
 }
 
-/* Given declspecs and a declarator,
-   determine the name and type of the object declared
-   and construct a ..._DECL node for it.
-   (In one case we can return a ..._TYPE node instead.
-    For invalid input we sometimes return 0.)
+/* Given declspecs and a declarator (abstract or otherwise), determine
+   the name and type of the object declared and construct a DECL node
+   for it.
 
    DECLSPECS is a chain of tree_list nodes whose value fields
     are the storage classes and type specifiers.
@@ -9912,43 +9607,22 @@ check_special_function_return_type (sfk, type, optype)
    if there are none; *ATTRLIST may be modified if attributes from inside
    the declarator should be applied to the declaration.
 
-   In the TYPENAME case, DECLARATOR is really an abstract declarator.
-   It may also be so in the PARM case, for a prototype where the
-   argument type is specified but not the name.
-
-   This function is where the complicated C meanings of `static'
-   and `extern' are interpreted.
-
-   For C++, if there is any monkey business to do, the function which
-   calls this one must do it, i.e., prepending instance variables,
-   renaming overloaded function names, etc.
-
-   Note that for this C++, it is an error to define a method within a class
-   which does not belong to that class.
-
-   Except in the case where SCOPE_REFs are implicitly known (such as
-   methods within a class being redundantly qualified),
-   declarations which involve SCOPE_REFs are returned as SCOPE_REFs
-   (class_name::decl_name).  The caller must also deal with this.
+   When this function is called, scoping variables (such as
+   CURRENT_CLASS_TYPE) should reflect the scope in which the
+   declaration occurs, not the scope in which the new declaration will
+   be placed.  For example, on:
 
-   If a constructor or destructor is seen, and the context is FIELD,
-   then the type gains the attribute TREE_HAS_x.  If such a declaration
-   is erroneous, NULL_TREE is returned.
+     void S::f() { ... }
 
-   QUALS is used only for FUNCDEF and MEMFUNCDEF cases.  For a member
-   function, these are the qualifiers to give to the `this' pointer. We
-   apply TYPE_QUAL_RESTRICT to the this ptr, not the object.
-
-   May return void_type_node if the declarator turned out to be a friend.
-   See grokfield for details.  */
+   when grokdeclarator is called for `S::f', the CURRENT_CLASS_TYPE
+   should not be `S'.  */
 
 tree
-grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
-     tree declspecs;
-     tree declarator;
-     enum decl_context decl_context;
-     int initialized;
-     tree *attrlist;
+grokdeclarator (tree declarator,
+                tree declspecs,
+                enum decl_context decl_context,
+                int initialized,
+                tree* attrlist)
 {
   RID_BIT_TYPE specbits;
   int nclasses = 0;
@@ -9973,9 +9647,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   /* See the code below that used this.  */
   tree decl_attr = NULL_TREE;
 #endif
-  /* Set this to error_mark_node for FIELD_DECLs we could not handle properly.
-     All FIELD_DECLs we build here have `init' put into their DECL_INITIAL.  */
-  tree init = NULL_TREE;
 
   /* Keep track of what sort of function is being processed
      so that we can warn about default return values, or explicit
@@ -9991,6 +9662,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   int template_count = 0;
   tree in_namespace = NULL_TREE;
   tree returned_attrs = NULL_TREE;
+  tree scope = NULL_TREE;
 
   RIDBIT_RESET_ALL (specbits);
   if (decl_context == FUNCDEF)
@@ -10030,7 +9702,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              my_friendly_assert (flags == NO_SPECIAL, 152);
              flags = DTOR_FLAG;
              sfk = sfk_destructor;
-             if (TREE_CODE (name) == TYPE_DECL)
+             if (TYPE_P (name))
                TREE_OPERAND (decl, 0) = name = constructor_name (name);
              my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
              if (ctype == NULL_TREE)
@@ -10042,7 +9714,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                    }
                  else
                    {
-                     tree t = constructor_name (current_class_name);
+                     tree t = constructor_name (current_class_type);
                      if (t != name)
                        rename = t;
                    }
@@ -10074,47 +9746,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            break;
 
          case CALL_EXPR:
-           if (parmlist_is_exprlist (CALL_DECLARATOR_PARMS (decl)))
-             {
-               /* This is actually a variable declaration using
-                  constructor syntax.  We need to call start_decl and
-                  cp_finish_decl so we can get the variable
-                  initialized...  */
-
-               tree attributes;
-
-               if (decl_context != NORMAL)
-                 {
-                   error ("variable declaration is not allowed here");
-                   return error_mark_node;
-                 }
-
-               *next = TREE_OPERAND (decl, 0);
-               init = CALL_DECLARATOR_PARMS (decl);
-
-               if (attrlist)
-                 {
-                   attributes = *attrlist;
-                 }
-               else
-                 {
-                   attributes = NULL_TREE;
-                 }
-
-               decl = start_decl (declarator, declspecs, 1,
-                                  attributes, NULL_TREE);
-               decl_type_access_control (decl);
-               if (decl)
-                 {
-                   /* Look for __unused__ attribute */
-                   if (TREE_USED (TREE_TYPE (decl)))
-                     TREE_USED (decl) = 1;
-                   finish_decl (decl, init, NULL_TREE);
-                 }
-               else
-                 error ("invalid declarator");
-               return NULL_TREE;
-             }
            innermost_code = TREE_CODE (decl);
            if (decl_context == FIELD && ctype == NULL_TREE)
              ctype = current_class_type;
@@ -10128,7 +9759,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            decl = *next;
            if (ctype != NULL_TREE
                && decl != NULL_TREE && flags != DTOR_FLAG
-               && decl == constructor_name (ctype))
+               && constructor_name_p (decl, ctype))
              {
                sfk = sfk_constructor;
                ctor_return_type = ctype;
@@ -10195,10 +9826,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                {
                  ctype = NULL_TREE;
                  in_namespace = TREE_OPERAND (decl, 0);
-                 TREE_OPERAND (decl, 0) = NULL_TREE;
                }
              else if (! is_aggr_type (cname, 1))
-               TREE_OPERAND (decl, 0) = NULL_TREE;
+               ctype = NULL_TREE;
              /* Must test TREE_OPERAND (decl, 1), in case user gives
                 us `typedef (class::memfunc)(int); memfunc *memfuncptr;'  */
              else if (TREE_OPERAND (decl, 1)
@@ -10215,19 +9845,35 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              else if (ctype == NULL_TREE)
                ctype = cname;
              else if (TREE_COMPLEXITY (decl) == current_class_depth)
-               TREE_OPERAND (decl, 0) = ctype;
+               ;
              else
                {
                  if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))
                    {
                      error ("type `%T' is not derived from type `%T'",
                                cname, ctype);
-                     TREE_OPERAND (decl, 0) = NULL_TREE;
+                     ctype = NULL_TREE;
                    }
                  else
                    ctype = cname;
                }
 
+             /* It is valid to write:
+
+                  class C { void f(); };
+                  typedef C D;
+                  void D::f();
+
+                The standard is not clear about whether `typedef const C D' is
+                legal; as of 2002-09-15 the committee is considering
+                that question.  EDG 3.0 allows that syntax.
+                Therefore, we do as well.  */
+             if (ctype)
+               ctype = TYPE_MAIN_VARIANT (ctype);
+             /* Update the declarator so that when we process it
+                again the correct type is present.  */
+             TREE_OPERAND (decl, 0) = ctype;
+
              if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
                  && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 1)),
                                         ctype))
@@ -10237,7 +9883,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              if (ctype)
                {
                  if (TREE_CODE (decl) == IDENTIFIER_NODE
-                     && constructor_name (ctype) == decl)
+                     && constructor_name_p (decl, ctype))
                    {
                      sfk = sfk_constructor;
                      ctor_return_type = ctype;
@@ -10425,13 +10071,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  else if (RIDBIT_SETP (i, specbits))
                    pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
 
-                 /* Diagnose "__thread extern".  Recall that this list
-                    is in the reverse order seen in the text.  */
-                 if (i == (int)RID_THREAD)
+                 /* Diagnose "__thread extern" or "__thread static".  */
+                 if (RIDBIT_SETP (RID_THREAD, specbits))
                    {
-                     if (RIDBIT_SETP (RID_EXTERN, specbits))
+                     if (i == (int)RID_EXTERN)
                        error ("`__thread' before `extern'");
-                     if (RIDBIT_SETP (RID_STATIC, specbits))
+                     else if (i == (int)RID_STATIC)
                        error ("`__thread' before `static'");
                    }
 
@@ -10530,21 +10175,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       type = integer_type_node;
     }
   
-  if (type && IMPLICIT_TYPENAME_P (type))
-    {
-      /* The implicit typename extension is deprecated and will be
-        removed.  Warn about its use now.  */
-      warning ("`%T' is implicitly a typename", type);
-      cp_deprecated ("implicit typename");
-
-      /* Now remove its implicitness, so that we don't warn again.
-         For instance this might be a typedef, and we do not want to
-         warn on uses of the typedef itself.  Simply clearing the
-         TREE_TYPE is insufficient.  */
-      type = copy_node (type);
-      TREE_TYPE (type) = NULL_TREE;
-    }
-
   ctype = NULL_TREE;
 
   /* Now process the modifiers that were specified
@@ -10865,6 +10495,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   if (nclasses > 0 && friendp)
     error ("storage class specifiers invalid in friend function declarations");
 
+  scope = get_scope_of_declarator (declarator);
+
   /* Now figure out the structure of the declarator proper.
      Descend through it, creating more complex types, until we reach
      the declared identifier (or NULL_TREE, in an abstract declarator).  */
@@ -10912,7 +10544,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
              grok_method_quals (ctype, dummy, quals);
              type = TREE_TYPE (dummy);
-             ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type)));
              quals = NULL_TREE;
            }
        }
@@ -11020,7 +10651,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
            if (ctype && sfk == sfk_conversion)
              TYPE_HAS_CONVERSION (ctype) = 1;
-           if (ctype && constructor_name (ctype) == dname)
+           if (ctype && constructor_name_p (dname, ctype))
              {
                /* We are within a class's scope. If our declarator name
                   is the same as the class name, and we are defining
@@ -11138,17 +10769,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            /* ANSI says that `const int foo ();'
               does not make the function foo const.  */
            type = build_function_type (type, arg_types);
-
-           {
-             tree t;
-             for (t = arg_types; t; t = TREE_CHAIN (t))
-               if (TREE_PURPOSE (t)
-                   && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
-                 {
-                   add_defarg_fn (type);
-                   break;
-                 }
-           }
          }
          break;
 
@@ -11253,44 +10873,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            if (TREE_CODE (sname) == BIT_NOT_EXPR)
              sname = TREE_OPERAND (sname, 0);
 
-           if (TREE_COMPLEXITY (declarator) == 0)
-             /* This needs to be here, in case we are called
-                multiple times.  */ ;
-           else if (TREE_COMPLEXITY (declarator) == -1)
-             /* Namespace member.  */
-             pop_decl_namespace ();
-           else if (friendp && (TREE_COMPLEXITY (declarator) < 2))
-             /* Don't fall out into global scope. Hides real bug? --eichin */ ;
-           else if (!TREE_OPERAND (declarator, 0)
-                    || !IS_AGGR_TYPE_CODE
-                         (TREE_CODE (TREE_OPERAND (declarator, 0))))
-             ;
-           else if (TREE_COMPLEXITY (declarator) == current_class_depth)
-             {
-               /* Resolve any TYPENAME_TYPEs from the decl-specifier-seq
-                  that refer to ctype.  They couldn't be resolved earlier
-                  because we hadn't pushed into the class yet.
-                  Example: resolve 'B<T>::type' in
-                  'B<typename B<T>::type> B<T>::f () { }'.  */
-               if (current_template_parms
-                   && uses_template_parms (type)
-                   && uses_template_parms (current_class_type))
-                 {
-                   tree args = current_template_args ();
-                   type = tsubst (type, args, tf_error | tf_warning,
-                                  NULL_TREE);
-                 }
-
-               /* This pop_nested_class corresponds to the
-                   push_nested_class used to push into class scope for
-                   parsing the argument list of a function decl, in
-                   qualified_id.  */
-               pop_nested_class ();
-               TREE_COMPLEXITY (declarator) = current_class_depth;
-             }
-           else
-             abort ();
-
            if (TREE_OPERAND (declarator, 0) == NULL_TREE)
              {
                /* We had a reference to a global decl, or
@@ -11354,7 +10936,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                      {
                        error ("cannot declare member function `%T::%s' within `%T'",
                                  ctype, name, current_class_type);
-                       return void_type_node;
+                       return error_mark_node;
                      }
                  }
                else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
@@ -11441,11 +11023,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       type = error_mark_node;
     }
 
-  if (decl_context == FIELD 
+  if ((decl_context == FIELD || decl_context == PARM)
       && !processing_template_decl 
       && variably_modified_type_p (type))
     {
-      error ("data member may not have variably modified type `%T'", type);
+      if (decl_context == FIELD)
+       error ("data member may not have variably modified type `%T'", type);
+      else
+       error ("parameter may not have variably modified type `%T'", type);
       type = error_mark_node;
     }
 
@@ -11515,7 +11100,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
       if (decl_context == FIELD)
        {
-         if (declarator == constructor_name (current_class_type))
+         if (constructor_name_p (declarator, current_class_type))
            pedwarn ("ISO C++ forbids nested type `%D' with same name as enclosing class",
                        declarator);
          decl = build_lang_decl (TYPE_DECL, declarator, type);
@@ -11523,6 +11108,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
       else
        {
          decl = build_decl (TYPE_DECL, declarator, type);
+         if (in_namespace || ctype)
+           cp_error_at ("typedef name may not be a nested-name-specifier",
+                        decl);
          if (!current_function_decl)
            DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
        }
@@ -11563,12 +11151,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
             type with external linkage have external linkage.  */
        }
 
-      if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
-       {
-         cp_error_at ("typedef name may not be class-qualified", decl);
-         return NULL_TREE;
-       }
-      else if (quals)
+      if (quals)
        {
          if (ctype == NULL_TREE)
            {
@@ -11663,8 +11246,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
          /* Only try to do this stuff if we didn't already give up.  */
          if (type != integer_type_node)
            {
-             decl_type_access_control (TYPE_NAME (type));
-
              /* A friendly class?  */
              if (current_class_type)
                make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
@@ -11985,18 +11566,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                  return void_type_node;
              }
 
-           /* 9.2p13 [class.mem] */
-           if (declarator == constructor_name (current_class_type)
-               /* The standard does not allow non-static data members
-                  here either, but we agreed at the 10/99 meeting
-                  to change that in TC 1 so that they are allowed in
-                  classes with no user-defined constructors.  */
-               && staticp)
-             pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
-                         declarator);
-
            if (staticp)
              {
+               /* [class.mem] forbids static data members with the
+                  same name as the enclosing class.  Non-static data
+                  members are checked in check_field_decls.  */
+               if (constructor_name_p (declarator, current_class_type))
+                 pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
+                          declarator);
+                 
                /* C++ allows static class members.  All other work
                   for this is done by grokfield.  */
                decl = build_lang_decl (VAR_DECL, declarator, type);
@@ -12162,40 +11740,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   }
 }
 \f
-/* Tell if a parmlist/exprlist looks like an exprlist or a parmlist.
-   An empty exprlist is a parmlist.  An exprlist which
-   contains only identifiers at the global level
-   is a parmlist.  Otherwise, it is an exprlist.  */
-
-int
-parmlist_is_exprlist (exprs)
-     tree exprs;
-{
-  if (exprs == NULL_TREE || TREE_PARMLIST (exprs))
-    return 0;
-
-  if (toplevel_bindings_p ())
-    {
-      /* At the global level, if these are all identifiers,
-        then it is a parmlist.  */
-      while (exprs)
-       {
-         if (TREE_CODE (TREE_VALUE (exprs)) != IDENTIFIER_NODE)
-           return 1;
-         exprs = TREE_CHAIN (exprs);
-       }
-      return 0;
-    }
-  return 1;
-}
-
 /* Subroutine of start_function.  Ensure that each of the parameter
    types (as listed in PARMS) is complete, as is required for a
    function definition.  */
 
 static void
-require_complete_types_for_parms (parms)
-     tree parms;
+require_complete_types_for_parms (tree parms)
 {
   for (; parms; parms = TREE_CHAIN (parms))
     {
@@ -12203,7 +11753,10 @@ require_complete_types_for_parms (parms)
         /* grokparms will have already issued an error */
         TREE_TYPE (parms) = error_mark_node;
       else if (complete_type_or_else (TREE_TYPE (parms), parms))
-       layout_decl (parms, 0);
+       {
+         layout_decl (parms, 0);
+         DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
+       }
       else
         TREE_TYPE (parms) = error_mark_node;
     }
@@ -12212,8 +11765,7 @@ require_complete_types_for_parms (parms)
 /* Returns nonzero if T is a local variable.  */
 
 int
-local_variable_p (t)
-     tree t;
+local_variable_p (tree t)
 {
   if ((TREE_CODE (t) == VAR_DECL
        /* A VAR_DECL with a context that is a _TYPE is a static data
@@ -12232,8 +11784,7 @@ local_variable_p (t)
    containing them is duplicated.)  */
 
 int
-nonstatic_local_decl_p (t)
-     tree t;
+nonstatic_local_decl_p (tree t)
 {
   return ((local_variable_p (t) && !TREE_STATIC (t))
          || TREE_CODE (t) == LABEL_DECL
@@ -12244,10 +11795,9 @@ nonstatic_local_decl_p (t)
    function.  */
 
 static tree
-local_variable_p_walkfn (tp, walk_subtrees, data)
-     tree *tp;
-     int *walk_subtrees ATTRIBUTE_UNUSED;
-     void *data ATTRIBUTE_UNUSED;
+local_variable_p_walkfn (tree* tp,
+                         int* walk_subtrees ATTRIBUTE_UNUSED ,
+                         void* data ATTRIBUTE_UNUSED )
 {
   return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
          ? *tp : NULL_TREE);
@@ -12259,9 +11809,7 @@ local_variable_p_walkfn (tp, walk_subtrees, data)
    DECL, if there is no DECL available.  */
 
 tree
-check_default_argument (decl, arg)
-     tree decl;
-     tree arg;
+check_default_argument (tree decl, tree arg)
 {
   tree var;
   tree decl_type;
@@ -12343,8 +11891,7 @@ check_default_argument (decl, arg)
    Also set last_function_parms to the chain of PARM_DECLs.  */
 
 static tree
-grokparms (first_parm)
-     tree first_parm;
+grokparms (tree first_parm)
 {
   tree result = NULL_TREE;
   tree decls = NULL_TREE;
@@ -12481,8 +12028,7 @@ grokparms (first_parm)
    operator.  */
 
 int
-copy_fn_p (d)
-     tree d;
+copy_fn_p (tree d)
 {
   tree args;
   tree arg_type;
@@ -12528,8 +12074,7 @@ copy_fn_p (d)
 
 /* Remember any special properties of member function DECL.  */
 
-void grok_special_member_properties (decl)
-     tree decl;
+void grok_special_member_properties (tree decl)
 {
   if (!DECL_NONSTATIC_MEMBER_FUNCTION_P(decl))
     ; /* Not special.  */
@@ -12578,8 +12123,7 @@ void grok_special_member_properties (decl)
    if the class has a constructor of the form X(X).  */
 
 int
-grok_ctor_properties (ctype, decl)
-     tree ctype, decl;
+grok_ctor_properties (tree ctype, tree decl)
 {
   int ctor_parm = copy_fn_p (decl);
 
@@ -12612,8 +12156,7 @@ grok_ctor_properties (ctype, decl)
 /* An operator with this code is unary, but can also be binary.  */
 
 static int
-ambi_op_p (code)
-     enum tree_code code;
+ambi_op_p (enum tree_code code)
 {
   return (code == INDIRECT_REF
          || code == ADDR_EXPR
@@ -12626,8 +12169,7 @@ ambi_op_p (code)
 /* An operator with this name can only be unary.  */
 
 static int
-unary_op_p (code)
-     enum tree_code code;
+unary_op_p (enum tree_code code)
 {
   return (code == TRUTH_NOT_EXPR
          || code == BIT_NOT_EXPR
@@ -12638,9 +12180,7 @@ unary_op_p (code)
 /* Do a little sanity-checking on how they declared their operator.  */
 
 void
-grok_op_properties (decl, friendp)
-     tree decl;
-     int friendp;
+grok_op_properties (tree decl, int friendp)
 {
   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   tree argtype;
@@ -12968,8 +12508,7 @@ grok_op_properties (decl, friendp)
 }
 \f
 static const char *
-tag_name (code)
-     enum tag_types code;
+tag_name (enum tag_types code)
 {
   switch (code)
     {
@@ -12986,6 +12525,38 @@ tag_name (code)
     }
 }
 
+/* Name lookup in an elaborated-type-specifier (after the keyword
+   indicated by TAG_CODE) has found TYPE.  If the
+   elaborated-type-specifier is invalid, issue a diagnostic and return
+   error_mark_node; otherwise, return TYPE itself.  */
+
+static tree
+check_elaborated_type_specifier (enum tag_types tag_code,
+                                tree type)
+{
+  tree t;
+
+  t = follow_tag_typedef (type);
+
+  /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
+     template type-parameter, the elaborated-type-specifier is
+     ill-formed.  */
+  if (!t)
+    {
+      error ("using typedef-name `%D' after `%s'",
+            TYPE_NAME (type), tag_name (tag_code));
+      t = error_mark_node;
+    }
+  else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+    {
+      error ("using template type parameter `%T' after `%s'",
+            type, tag_name (tag_code));
+      t = error_mark_node;
+    }
+
+  return t;
+}
+
 /* Get the struct, enum or union (CODE says which) with tag NAME.
    Define the tag as a forward-reference if it is not defined.
 
@@ -13005,6 +12576,7 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
   struct cp_binding_level *b = current_binding_level;
   tree context = NULL_TREE;
 
+  timevar_push (TV_NAME_LOOKUP);
   switch (tag_code)
     {
     case record_type:
@@ -13071,20 +12643,9 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
     {
       if (t)
        {
-         ref = follow_tag_typedef (t);
-
-         /* [dcl.type.elab] If the identifier resolves to a
-            typedef-name or a template type-parameter, the
-            elaborated-type-specifier is ill-formed.  */
-         if (!ref)
-           {
-             pedwarn ("using typedef-name `%D' after `%s'",
-                      TYPE_NAME (t), tag_name (tag_code));
-             ref = t;
-           }
-         else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-           error ("using template type parameter `%T' after `%s'",
-                  t, tag_name (tag_code));
+         ref = check_elaborated_type_specifier (tag_code, t);
+         if (ref == error_mark_node)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
        }
       else
        ref = lookup_tag (code, name, b, 0);
@@ -13103,9 +12664,15 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
               template, so we want this type.  */
            ref = DECL_TEMPLATE_RESULT (ref);
 
-         if (ref && TREE_CODE (ref) == TYPE_DECL
-             && TREE_CODE (TREE_TYPE (ref)) == code)
-           ref = TREE_TYPE (ref);
+         if (ref && TREE_CODE (ref) == TYPE_DECL)
+           {
+             ref = check_elaborated_type_specifier (tag_code, 
+                                                    TREE_TYPE (ref));
+             if (ref == error_mark_node)
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+             if (ref && TREE_CODE (ref) != code)
+               ref = NULL_TREE;
+           }
          else
            ref = NULL_TREE;
        }
@@ -13207,13 +12774,11 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
 
   TYPE_ATTRIBUTES (ref) = attributes;
 
-  return ref;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref);
 }
 
 tree
-xref_tag_from_type (old, id, globalize)
-     tree old, id;
-     int globalize;
+xref_tag_from_type (tree old, tree id, int globalize)
 {
   enum tag_types tag_kind;
 
@@ -13229,22 +12794,20 @@ xref_tag_from_type (old, id, globalize)
 }
 
 /* REF is a type (named NAME), for which we have just seen some
-   baseclasses.  BINFO is a list of those baseclasses; the
+   baseclasses.  BASE_LIST is a list of those baseclasses; the
    TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of
-   the base-class.  CODE_TYPE_NODE indicates whether REF is a class,
+   the base-class.  TREE_VIA_VIRTUAL indicates virtual
+   inheritance. CODE_TYPE_NODE indicates whether REF is a class,
    struct, or union.  */
 
 void
-xref_basetypes (ref, binfo)
-     tree ref;
-     tree binfo;
+xref_basetypes (tree ref, tree base_list)
 {
   /* In the declaration `A : X, Y, ... Z' we mark all the types
      (A, X, Y, ..., Z) so we can check for duplicates.  */
-  tree binfos;
-  tree base;
+  tree *basep;
 
-  int i, len;
+  int i;
   enum tag_types tag_code;
 
   if (TREE_CODE (ref) == UNION_TYPE)
@@ -13255,61 +12818,58 @@ xref_basetypes (ref, binfo)
 
   tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
 
-  len = list_length (binfo);
-
   /* First, make sure that any templates in base-classes are
      instantiated.  This ensures that if we call ourselves recursively
      we do not get confused about which classes are marked and which
      are not.  */
-  for (base = binfo; base; base = TREE_CHAIN (base))
-    complete_type (TREE_VALUE (base));
+  basep = &base_list; 
+  while (*basep) 
+    {
+      tree basetype = TREE_VALUE (*basep);
+      if (!(processing_template_decl && uses_template_parms (basetype))
+         && !complete_type_or_else (basetype, NULL))
+       /* An incomplete type.  Remove it from the list.  */
+       *basep = TREE_CHAIN (*basep);
+      else
+       basep = &TREE_CHAIN (*basep);
+    }
 
   SET_CLASSTYPE_MARKED (ref);
-  BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len);
-
-  for (i = 0; binfo; binfo = TREE_CHAIN (binfo))
-    {
-      /* The base of a derived struct is public by default.  */
-      int via_public
-       = (TREE_PURPOSE (binfo) == access_public_node
-          || TREE_PURPOSE (binfo) == access_public_virtual_node
-          || (tag_code != class_type
-              && (TREE_PURPOSE (binfo) == access_default_node
-                  || TREE_PURPOSE (binfo) == access_default_virtual_node)));
-      int via_protected
-       = (TREE_PURPOSE (binfo) == access_protected_node
-          || TREE_PURPOSE (binfo) == access_protected_virtual_node);
-      int via_virtual
-       = (TREE_PURPOSE (binfo) == access_private_virtual_node
-          || TREE_PURPOSE (binfo) == access_protected_virtual_node
-          || TREE_PURPOSE (binfo) == access_public_virtual_node
-          || TREE_PURPOSE (binfo) == access_default_virtual_node);
-      tree basetype = TREE_VALUE (binfo);
-      tree base_binfo;
-
-      if (basetype && TREE_CODE (basetype) == TYPE_DECL)
-       basetype = TREE_TYPE (basetype);
-      if (!basetype
-         || (TREE_CODE (basetype) != RECORD_TYPE
-             && TREE_CODE (basetype) != TYPENAME_TYPE
-             && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
-             && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
-       {
-         error ("base type `%T' fails to be a struct or class type",
-                   TREE_VALUE (binfo));
-         continue;
-       }
-
-      /* This code replaces similar code in layout_basetypes.
-         We put the complete_type first for implicit `typename'.  */
-      if (!COMPLETE_TYPE_P (basetype)
-         && ! (current_template_parms && uses_template_parms (basetype)))
-       {
-         error ("base class `%T' has incomplete type", basetype);
-         continue;
-       }
-      else
+  i = list_length (base_list);
+  if (i)
+    {
+      tree binfo = TYPE_BINFO (ref);
+      tree binfos = make_tree_vec (i);
+      tree accesses = make_tree_vec (i);
+      
+      BINFO_BASETYPES (binfo) = binfos;
+      BINFO_BASEACCESSES (binfo) = accesses;
+  
+      for (i = 0; base_list; base_list = TREE_CHAIN (base_list))
        {
+         tree access = TREE_PURPOSE (base_list);
+         int via_virtual = TREE_VIA_VIRTUAL (base_list);
+         tree basetype = TREE_VALUE (base_list);
+         tree base_binfo;
+         
+         if (access == access_default_node)
+           /* The base of a derived struct is public by default.  */
+           access = (tag_code == class_type
+                     ? access_private_node : access_public_node);
+         
+         if (basetype && TREE_CODE (basetype) == TYPE_DECL)
+           basetype = TREE_TYPE (basetype);
+         if (!basetype
+             || (TREE_CODE (basetype) != RECORD_TYPE
+                 && TREE_CODE (basetype) != TYPENAME_TYPE
+                 && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
+                 && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
+           {
+             error ("base type `%T' fails to be a struct or class type",
+                    basetype);
+             continue;
+           }
+         
          if (CLASSTYPE_MARKED (basetype))
            {
              if (basetype == ref)
@@ -13318,48 +12878,41 @@ xref_basetypes (ref, binfo)
                error ("duplicate base type `%T' invalid", basetype);
              continue;
            }
-
+         
          if (TYPE_FOR_JAVA (basetype)
              && (current_lang_depth () == 0))
            TYPE_FOR_JAVA (ref) = 1;
-
-         /* Note that the BINFO records which describe individual
-            inheritances are *not* shared in the lattice!  They
-            cannot be shared because a given baseclass may be
-            inherited with different `accessibility' by different
-            derived classes.  (Each BINFO record describing an
-            individual inheritance contains flags which say what
-            the `accessibility' of that particular inheritance is.)  */
-
-         base_binfo
-           = make_binfo (size_zero_node, basetype,
-                         CLASS_TYPE_P (basetype)
-                         ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
-                         CLASS_TYPE_P (basetype)
-                         ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE);
-
+         
+         if (CLASS_TYPE_P (basetype))
+           {
+             base_binfo = TYPE_BINFO (basetype);
+             /* This flag will be in the binfo of the base type, we must
+                clear it after copying the base binfos.  */
+             BINFO_DEPENDENT_BASE_P (base_binfo)
+               = dependent_type_p (basetype);
+           }
+         else
+           base_binfo = make_binfo (size_zero_node, basetype,
+                                    NULL_TREE, NULL_TREE);
+         
          TREE_VEC_ELT (binfos, i) = base_binfo;
-         TREE_VIA_PUBLIC (base_binfo) = via_public;
-         TREE_VIA_PROTECTED (base_binfo) = via_protected;
+         TREE_VEC_ELT (accesses, i) = access;
+         /* This flag will be in the binfo of the base type, we must
+            clear it after copying the base binfos.  */
          TREE_VIA_VIRTUAL (base_binfo) = via_virtual;
-         BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref);
-
-         /* We need to unshare the binfos now so that lookups during class
-            definition work.  */
-         unshare_base_binfos (base_binfo);
-
+         
          SET_CLASSTYPE_MARKED (basetype);
-
+         
          /* We are free to modify these bits because they are meaningless
             at top level, and BASETYPE is a top-level type.  */
          if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype))
            {
              TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1;
              /* Converting to a virtual base class requires looking
-                up the offset of the virtual base.  */
+                up the offset of the virtual base.  */
              TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
            }
-
+         
          if (CLASS_TYPE_P (basetype))
            {
              TYPE_HAS_NEW_OPERATOR (ref)
@@ -13371,36 +12924,45 @@ xref_basetypes (ref, binfo)
              TYPE_USES_MULTIPLE_INHERITANCE (ref)
                |= TYPE_USES_MULTIPLE_INHERITANCE (basetype);
              /* Likewise, if converting to a base of the base may require
-                code, then we may need to generate code to convert to a
-                base as well.  */
+                code, then we may need to generate code to convert to a
+                base as well.  */
              TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref)
                |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype);
            }
-
-         i += 1;
+         i++;
+       }
+      if (i)
+       TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i;
+      else
+       BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE;
+      
+      if (i > 1)
+       {
+         TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
+         /* If there is more than one non-empty they cannot be at the same
+            address.  */
+         TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
        }
     }
-  if (i)
-    TREE_VEC_LENGTH (binfos) = i;
-  else
-    BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE;
-
-  if (i > 1)
+  
+  /* Copy the base binfos, collect the virtual bases and set the
+     inheritance order chain.  */
+  copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
+  CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref));
+  
+  /* Unmark all the types.  */
+  while (i--)
     {
-      TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
-      /* If there is more than one non-empty they cannot be at the same
-        address.  */
-      TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
+      tree basetype = BINFO_TYPE (BINFO_BASETYPE (TYPE_BINFO (ref), i));
+      
+      CLEAR_CLASSTYPE_MARKED (basetype);
+      if (CLASS_TYPE_P (basetype))
+       {
+         TREE_VIA_VIRTUAL (TYPE_BINFO (basetype)) = 0;
+         BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0;
+       }
     }
-
-  /* Unmark all the types.  */
-  while (--i >= 0)
-    CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
   CLEAR_CLASSTYPE_MARKED (ref);
-
-  /* Now that we know all the base-classes, set up the list of virtual
-     bases.  */
-  get_vbase_types (ref);
 }
 
 \f
@@ -13411,8 +12973,7 @@ xref_basetypes (ref, binfo)
    may be used to declare the individual values as they are read.  */
 
 tree
-start_enum (name)
-     tree name;
+start_enum (tree name)
 {
   register tree enumtype = NULL_TREE;
   struct cp_binding_level *b = current_binding_level;
@@ -13445,8 +13006,7 @@ start_enum (name)
    ENUMTYPE is the type object and VALUES a list of name-value pairs.  */
 
 void
-finish_enum (enumtype)
-     tree enumtype;
+finish_enum (tree enumtype)
 {
   tree pair;
   tree minnode;
@@ -13460,44 +13020,56 @@ finish_enum (enumtype)
   /* We built up the VALUES in reverse order.  */
   TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
 
-  /* [dcl.enum]
-
-     Following the closing brace of an enum-specifier, each
-     enumerator has the type of its enumeration.  Prior to the
-     closing brace, the type of each enumerator is the type of
-     its initializing value.  */
-  for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
-    TREE_TYPE (TREE_VALUE (pair)) = enumtype;
-  
-  /* For an enum defined in a template, all further processing is
-     postponed until the template is instantiated.  */
+  /* For an enum defined in a template, just set the type of the values;
+     all further processing is postponed until the template is
+     instantiated.  We need to set the type so that tsubst of a CONST_DECL
+     works.  */
   if (processing_template_decl)
     {
+      for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
+       TREE_TYPE (TREE_VALUE (pair)) = enumtype;
       if (at_function_scope_p ())
        add_stmt (build_min (TAG_DEFN, enumtype));
       return;
     }
 
-  /* Figure out what the minimum and maximum values of the enumerators
-     are.  */
   if (TYPE_VALUES (enumtype))
     {
       minnode = maxnode = NULL_TREE;
 
-      for (pair = TYPE_VALUES (enumtype);
-          pair;
-          pair = TREE_CHAIN (pair))
+      for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
        {
-         tree value;
+         tree decl = TREE_VALUE (pair);
+         tree value = DECL_INITIAL (decl);
 
-         value = DECL_INITIAL (TREE_VALUE (pair));
+         /* [dcl.enum]: Following the closing brace of an enum-specifier,
+            each enumerator has the type of its enumeration.  Prior to the
+            closing brace, the type of each enumerator is the type of its
+            initializing value.  */
+         TREE_TYPE (decl) = enumtype;
 
+         /* Figure out what the minimum and maximum values of the
+            enumerators are.  */
          if (!minnode)
            minnode = maxnode = value;
          else if (tree_int_cst_lt (maxnode, value))
            maxnode = value;
          else if (tree_int_cst_lt (value, minnode))
            minnode = value;
+
+         /* Set the TREE_TYPE for the values as well.  That's so that when
+            we call decl_constant_value we get an entity of the right type
+            (but with the constant value).  But first make a copy so we
+            don't clobber shared INTEGER_CSTs.  */
+         if (TREE_TYPE (value) != enumtype)
+           {
+             value = DECL_INITIAL (decl) = copy_node (value);
+             TREE_TYPE (value) = enumtype;
+           }
+
+         /* In addition, transform the TYPE_VALUES list to contain the
+            values, rather than the CONST_DECLs for them.  */
+         TREE_VALUE (pair) = value;
        }
     }
   else
@@ -13512,18 +13084,6 @@ finish_enum (enumtype)
   highprec = min_precision (maxnode, unsignedp);
   precision = MAX (lowprec, highprec);
 
-  /* Set the TREE_TYPE for the values as well.  That's so that when we
-     call decl_constant_value we get an entity of the right type (but
-     with the constant value).  In addition, transform the TYPE_VALUES
-     list to contain the values, rather than the CONST_DECLs for them.  */
-  for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
-    {
-      tree value = DECL_INITIAL (TREE_VALUE (pair));
-
-      TREE_TYPE (value) = enumtype;
-      TREE_VALUE (pair) = value;
-    }
-
   /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'.  */
   TYPE_SIZE (enumtype) = NULL_TREE;
   TYPE_PRECISION (enumtype) = precision;
@@ -13567,15 +13127,11 @@ finish_enum (enumtype)
    Assignment of sequential values by default is handled here.  */
 
 void
-build_enumerator (name, value, enumtype)
-     tree name;
-     tree value;
-     tree enumtype;
+build_enumerator (tree name, tree value, tree enumtype)
 {
   tree decl;
   tree context;
   tree type;
-  tree values;
 
   /* Remove no-op casts from the value.  */
   if (value)
@@ -13601,7 +13157,7 @@ build_enumerator (name, value, enumtype)
        }
 
       /* Default based on previous value.  */
-      if (value == NULL_TREE && ! processing_template_decl)
+      if (value == NULL_TREE)
        {
          tree prev_value;
 
@@ -13622,26 +13178,9 @@ build_enumerator (name, value, enumtype)
        }
 
       /* Remove no-op casts from the value.  */
-      if (value)
-       STRIP_TYPE_NOPS (value);
-#if 0
-      /* To fix MAX_VAL enum consts. (bkoz)  */
-      TREE_TYPE (value) = integer_type_node;
-#endif
+      STRIP_TYPE_NOPS (value);
     }
 
-  /* We always have to copy here; not all INTEGER_CSTs are unshared.
-     Even in other cases, we will later (in finish_enum) be setting
-     the type of VALUE.  But, we don't need to make a copy if this
-     VALUE is one of the enumeration constants for this same
-     enumeration type.  */
-  for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
-    if (TREE_VALUE (values) == value)
-      break;
-  /* If we didn't break out of the loop, then we do need a copy.  */
-  if (!values && value)
-    value = copy_node (value);
-
   /* C++ associates enums with global, function, or class declarations.  */
   context = current_scope ();
 
@@ -13670,8 +13209,8 @@ build_enumerator (name, value, enumtype)
     decl = build_decl (CONST_DECL, name, type);
 
   DECL_CONTEXT (decl) = FROB_CONTEXT (context);
+  TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
-  TREE_READONLY (decl) = 1;
 
   if (context && context == current_class_type)
     /* In something like `struct S { enum E { i = 7 }; };' we put `i'
@@ -13689,9 +13228,7 @@ build_enumerator (name, value, enumtype)
 /* We're defining DECL.  Make sure that it's type is OK.  */
 
 static void
-check_function_type (decl, current_function_parms)
-     tree decl;
-     tree current_function_parms;
+check_function_type (tree decl, tree current_function_parms)
 {
   tree fntype = TREE_TYPE (decl);
   tree return_type = complete_type (TREE_TYPE (fntype));
@@ -13748,9 +13285,7 @@ check_function_type (decl, current_function_parms)
    applied to it with the argument list [1, 2].  */
 
 int
-start_function (declspecs, declarator, attrs, flags)
-     tree declspecs, declarator, attrs;
-     int flags;
+start_function (tree declspecs, tree declarator, tree attrs, int flags)
 {
   tree decl1;
   tree ctype = NULL_TREE;
@@ -13844,8 +13379,8 @@ start_function (declspecs, declarator, attrs, flags)
 
   if (DECL_DECLARED_INLINE_P (decl1)
       && lookup_attribute ("noinline", attrs))
-    warning_with_decl (decl1,
-                      "inline function `%s' given attribute noinline");
+    warning ("%Hinline function '%D' given attribute noinline",
+             &DECL_SOURCE_LOCATION (decl1), decl1);
 
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
     /* This is a constructor, we must ensure that any default args
@@ -13872,9 +13407,9 @@ start_function (declspecs, declarator, attrs, flags)
   /* Set up current_class_type, and enter the scope of the class, if
      appropriate.  */
   if (ctype)
-    push_nested_class (ctype, 1);
+    push_nested_class (ctype);
   else if (DECL_STATIC_FUNCTION_P (decl1))
-    push_nested_class (DECL_CONTEXT (decl1), 2);
+    push_nested_class (DECL_CONTEXT (decl1));
 
   /* Now that we have entered the scope of the class, we must restore
      the bindings for any template parameters surrounding DECL1, if it
@@ -13952,6 +13487,9 @@ start_function (declspecs, declarator, attrs, flags)
   /* Start the statement-tree, start the tree now.  */
   begin_stmt_tree (&DECL_SAVED_TREE (decl1));
 
+  /* Don't double-count statements in templates.  */
+  DECL_NUM_STMTS (decl1) = 0;
+
   /* Let the user know we're compiling this function.  */
   announce_function (decl1);
 
@@ -14110,8 +13648,7 @@ start_function (declspecs, declarator, attrs, flags)
    Also install to binding contour return value identifier, if any.  */
 
 static void
-store_parm_decls (current_function_parms)
-     tree current_function_parms;
+store_parm_decls (tree current_function_parms)
 {
   register tree fndecl = current_function_decl;
   register tree parm;
@@ -14188,8 +13725,7 @@ store_parm_decls (current_function_parms)
    when we want to generate RTL later we know what to do.  */
 
 static void
-save_function_data (decl)
-     tree decl;
+save_function_data (tree decl)
 {
   struct language_function *f;
 
@@ -14229,7 +13765,7 @@ save_function_data (decl)
    fully-constructed bases and members.  */
 
 static void
-begin_constructor_body ()
+begin_constructor_body (void)
 {
 }
 
@@ -14238,7 +13774,7 @@ begin_constructor_body ()
    members.  */
 
 static void
-finish_constructor_body ()
+finish_constructor_body (void)
 {
 }
 
@@ -14246,7 +13782,7 @@ finish_constructor_body ()
    vtable pointers and cleanups for bases and members.  */
 
 static void
-begin_destructor_body ()
+begin_destructor_body (void)
 {
   tree if_stmt;
   tree compound_stmt;
@@ -14293,7 +13829,7 @@ begin_destructor_body ()
    necessary.  Do that now.  */
 
 static void
-finish_destructor_body ()
+finish_destructor_body (void)
 {
   tree exprstmt;
 
@@ -14335,7 +13871,7 @@ finish_destructor_body ()
    In other functions, this isn't necessary, but it doesn't hurt.  */
 
 tree
-begin_function_body ()
+begin_function_body (void)
 {
   tree stmt;
 
@@ -14370,8 +13906,7 @@ begin_function_body ()
    main() would also need to return 0.  */
 
 void
-finish_function_body (compstmt)
-     tree compstmt;
+finish_function_body (tree compstmt)
 {
   /* Close the block.  */
   finish_compound_stmt (0, compstmt);
@@ -14395,8 +13930,7 @@ finish_function_body (compstmt)
        after the class definition is complete.)  */
 
 tree
-finish_function (flags)
-     int flags;
+finish_function (int flags)
 {
   register tree fndecl = current_function_decl;
   tree fntype, ctype = NULL_TREE;
@@ -14408,6 +13942,15 @@ finish_function (flags)
   if (fndecl == NULL_TREE)
     return error_mark_node;
 
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+      && DECL_VIRTUAL_P (fndecl)
+      && !processing_template_decl)
+    {
+      tree fnclass = DECL_CONTEXT (fndecl);
+      if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
+       keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+    }
+
   nested = function_depth > 1;
   fntype = TREE_TYPE (fndecl);
 
@@ -14445,6 +13988,12 @@ finish_function (flags)
   /* If we're saving up tree structure, tie off the function now.  */
   finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
 
+  /* If this function can't throw any exceptions, remember that.  */
+  if (!processing_template_decl
+      && !cp_function_chain->can_throw
+      && !flag_non_call_exceptions)
+    TREE_NOTHROW (fndecl) = 1;
+
   /* This must come after expand_function_end because cleanups might
      have declarations (from inline functions) that need to go into
      this function's blocks.  */
@@ -14479,11 +14028,21 @@ finish_function (flags)
   if (current_function_return_value)
     {
       tree r = current_function_return_value;
-      /* This is only worth doing for fns that return in memory--and
-        simpler, since we don't have to worry about promoted modes.  */
+      tree outer;
+
       if (r != error_mark_node
-         && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
+         /* This is only worth doing for fns that return in memory--and
+            simpler, since we don't have to worry about promoted modes.  */
+         && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
+         /* Only allow this for variables declared in the outer scope of
+            the function so we know that their lifetime always ends with a
+            return; see g++.dg/opt/nrv6.C.  We could be more flexible if
+            we were to do this optimization in tree-ssa.  */
+         /* Skip the artificial function body block.  */
+         && (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))),
+             chain_member (r, BLOCK_VARS (outer))))
        {
+         
          DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
          walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
                                        nullify_returns_r, r);
@@ -14523,7 +14082,6 @@ finish_function (flags)
 
   /* Complain if there's just no return statement.  */
   if (warn_return_type
-      && !processing_template_decl
       && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
       && !current_function_returns_value && !current_function_returns_null
       /* Don't complain if we abort or throw.  */
@@ -14531,7 +14089,7 @@ finish_function (flags)
       && !DECL_NAME (DECL_RESULT (fndecl))
       /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
         inline function, as we might never be compiled separately.  */
-      && DECL_INLINE (fndecl))
+      && (DECL_INLINE (fndecl) || processing_template_decl))
     warning ("no return statement in function returning non-void");
     
   /* Clear out memory we no longer need.  */
@@ -14586,15 +14144,19 @@ finish_function (flags)
    CHANGES TO CODE IN `grokfield'.  */
 
 tree
-start_method (declspecs, declarator, attrlist)
-     tree declarator, declspecs, attrlist;
+start_method (tree declspecs, tree declarator, tree attrlist)
 {
   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
                                &attrlist);
 
-  /* Something too ugly to handle.  */
-  if (fndecl == NULL_TREE)
-    return NULL_TREE;
+  if (fndecl == error_mark_node)
+    return error_mark_node;
+
+  if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
+    {
+      error ("invalid member function declaration");
+      return error_mark_node;
+    }
 
   if (attrlist)
     cplus_decl_attributes (&fndecl, attrlist, 0);
@@ -14603,10 +14165,6 @@ start_method (declspecs, declarator, attrlist)
   if (fndecl == void_type_node)
     return fndecl;
 
-  if (TREE_CODE (fndecl) != FUNCTION_DECL)
-    /* Not a function, tell parser to report parse error.  */
-    return NULL_TREE;
-
   if (DECL_IN_AGGR_P (fndecl))
     {
       if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
@@ -14623,6 +14181,7 @@ start_method (declspecs, declarator, attrlist)
 
   DECL_DECLARED_INLINE_P (fndecl) = 1;
 
+  DID_INLINE_FUNC (fndecl) = 0;
   if (flag_default_inline)
     DECL_INLINE (fndecl) = 1;
 
@@ -14663,8 +14222,7 @@ start_method (declspecs, declarator, attrlist)
    DECL is the ..._DECL that `start_method' provided.  */
 
 tree
-finish_method (decl)
-     tree decl;
+finish_method (tree decl)
 {
   register tree fndecl = decl;
   tree old_initial;
@@ -14716,8 +14274,7 @@ finish_method (decl)
    we can lay it out later, when and if its type becomes complete.  */
 
 void
-maybe_register_incomplete_var (var)
-     tree var;
+maybe_register_incomplete_var (tree var)
 {
   my_friendly_assert (TREE_CODE (var) == VAR_DECL, 20020406);
 
@@ -14744,8 +14301,7 @@ maybe_register_incomplete_var (var)
    declaration, update them now.  */
 
 void
-complete_vars (type)
-     tree type;
+complete_vars (tree type)
 {
   tree *list = &incomplete_vars;
 
@@ -14770,8 +14326,7 @@ complete_vars (type)
    here.  */
 
 tree
-cxx_maybe_build_cleanup (decl)
-     tree decl;
+cxx_maybe_build_cleanup (tree decl)
 {
   tree type = TREE_TYPE (decl);
 
@@ -14809,7 +14364,7 @@ cxx_maybe_build_cleanup (decl)
 /* When a stmt has been parsed, this function is called.  */
 
 void
-finish_stmt ()
+finish_stmt (void)
 {
   /* Always assume this statement was not an expression statement.  If
      it actually was an expression statement, its our callers
@@ -14821,8 +14376,7 @@ finish_stmt ()
    but turned out to be static.  Update it accordingly.  */
 
 void
-revert_static_member_fn (decl)
-     tree decl;
+revert_static_member_fn (tree decl)
 {
   tree tmp;
   tree function = TREE_TYPE (decl);
@@ -14848,8 +14402,7 @@ revert_static_member_fn (decl)
    function.  */
 
 void
-cxx_push_function_context (f)
-     struct function *f;
+cxx_push_function_context (struct function * f)
 {
   struct language_function *p
     = ((struct language_function *)
@@ -14869,8 +14422,7 @@ cxx_push_function_context (f)
    compiling the function.  */
 
 void
-cxx_pop_function_context (f)
-     struct function *f;
+cxx_pop_function_context (struct function * f)
 {
   f->language = 0;
 }
@@ -14879,19 +14431,17 @@ cxx_pop_function_context (f)
    one of the language-independent trees.  */
 
 enum cp_tree_node_structure_enum
-cp_tree_node_structure (t)
-     union lang_tree_node *t;
+cp_tree_node_structure (union lang_tree_node * t)
 {
   switch (TREE_CODE (&t->generic))
     {
-    case DEFAULT_ARG:          return TS_CP_IDENTIFIER;
+    case DEFAULT_ARG:          return TS_CP_DEFAULT_ARG;
     case IDENTIFIER_NODE:      return TS_CP_IDENTIFIER;
-    case CPLUS_BINDING:                return TS_CP_BINDING;
     case OVERLOAD:             return TS_CP_OVERLOAD;
     case TEMPLATE_PARM_INDEX:  return TS_CP_TPI;
     case PTRMEM_CST:           return TS_CP_PTRMEM;
+    case BASELINK:              return TS_CP_BASELINK;
     case WRAPPER:              return TS_CP_WRAPPER;
-    case SRCLOC:               return TS_CP_SRCLOC;
     default:                   return TS_CP_GENERIC;
     }
 }
@@ -14900,15 +14450,14 @@ cp_tree_node_structure (t)
    the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
 
 tree
-identifier_global_value        (t)
-     tree t;
+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 ()
+build_void_list_node (void)
 {
   tree t = build_tree_list (NULL_TREE, void_type_node);
   TREE_PARMLIST (t) = 1;
@@ -14916,8 +14465,7 @@ build_void_list_node ()
 }
 
 static int
-cp_missing_noreturn_ok_p (decl)
-     tree decl;
+cp_missing_noreturn_ok_p (tree decl)
 {
   /* A missing noreturn is ok for the `main' function.  */
   return DECL_MAIN_P (decl);