OSDN Git Service

2012-04-15 Fabien ChĂȘne <fabien@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cp / name-lookup.c
index e499ede..fedf626 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for C++ name lookup routines.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
@@ -28,10 +28,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #include "name-lookup.h"
 #include "timevar.h"
-#include "toplev.h"
-#include "diagnostic.h"
+#include "diagnostic-core.h"
+#include "intl.h"
 #include "debug.h"
-#include "c-pragma.h"
+#include "c-family/c-pragma.h"
+#include "params.h"
+#include "pointer-set.h"
 
 /* The bindings for a particular name in a particular scope.  */
 
@@ -41,8 +43,8 @@ struct scope_binding {
 };
 #define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
 
-static cxx_scope *innermost_nonclass_level (void);
-static cxx_binding *binding_for_name (cxx_scope *, tree);
+static cp_binding_level *innermost_nonclass_level (void);
+static cxx_binding *binding_for_name (cp_binding_level *, tree);
 static tree push_overloaded_decl (tree, int, bool);
 static bool lookup_using_namespace (tree, struct scope_binding *, tree,
                                    tree, int);
@@ -50,7 +52,8 @@ static bool qualified_lookup_using_namespace (tree, tree,
                                              struct scope_binding *, int);
 static tree lookup_type_current_level (tree);
 static tree push_using_directive (tree);
-static cxx_binding* lookup_extern_c_fun_binding_in_all_ns (tree);
+static tree lookup_extern_c_fun_in_all_ns (tree);
+static void diagnose_name_conflict (tree, tree);
 
 /* The :: namespace.  */
 
@@ -63,18 +66,18 @@ static GTY(()) tree anonymous_namespace_name;
 /* Initialize anonymous_namespace_name if necessary, and return it.  */
 
 static tree
-get_anonymous_namespace_name(void)
+get_anonymous_namespace_name (void)
 {
   if (!anonymous_namespace_name)
     {
       /* The anonymous namespace has to have a unique name
         if typeinfo objects are being compared by name.  */
       if (! flag_weak || ! SUPPORTS_ONE_ONLY)
-       anonymous_namespace_name = get_file_function_name ("N");
+       anonymous_namespace_name = get_file_function_name ("N");
       else
-       /* The demangler expects anonymous namespaces to be called
-          something starting with '_GLOBAL__N_'.  */
-       anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
+       /* The demangler expects anonymous namespaces to be called
+          something starting with '_GLOBAL__N_'.  */
+       anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
     }
   return anonymous_namespace_name;
 }
@@ -102,7 +105,7 @@ binding_entry_make (tree name, tree type)
       free_binding_entry = entry->chain;
     }
   else
-    entry = GGC_NEW (struct binding_entry_s);
+    entry = ggc_alloc_binding_entry_s ();
 
   entry->name = name;
   entry->type = type;
@@ -144,7 +147,7 @@ binding_table_construct (binding_table table, size_t chain_count)
 {
   table->chain_count = chain_count;
   table->entry_count = 0;
-  table->chain = GGC_CNEWVEC (binding_entry, table->chain_count);
+  table->chain = ggc_alloc_cleared_vec_binding_entry (table->chain_count);
 }
 
 /* Make TABLE's entries ready for reuse.  */
@@ -178,7 +181,7 @@ binding_table_free (binding_table table)
 static inline binding_table
 binding_table_new (size_t chain_count)
 {
-  binding_table table = GGC_NEW (struct binding_table_s);
+  binding_table table = ggc_alloc_binding_table_s ();
   table->chain = NULL;
   binding_table_construct (table, chain_count);
   return table;
@@ -292,7 +295,7 @@ cxx_binding_make (tree value, tree type)
       free_bindings = binding->previous;
     }
   else
-    binding = GGC_NEW (cxx_binding);
+    binding = ggc_alloc_cxx_binding ();
 
   cxx_binding_init (binding, value, type);
 
@@ -313,40 +316,16 @@ cxx_binding_free (cxx_binding *binding)
    bindings) in the class scope indicated by SCOPE.  */
 
 static cxx_binding *
-new_class_binding (tree name, tree value, tree type, cxx_scope *scope)
+new_class_binding (tree name, tree value, tree type, cp_binding_level *scope)
 {
   cp_class_binding *cb;
   cxx_binding *binding;
 
-  if (VEC_length (cp_class_binding, scope->class_shadowed))
-    {
-      cp_class_binding *old_base;
-      old_base = VEC_index (cp_class_binding, scope->class_shadowed, 0);
-      if (VEC_reserve (cp_class_binding, gc, scope->class_shadowed, 1))
-       {
-         /* Fixup the current bindings, as they might have moved.  */
-         size_t i;
-
-         for (i = 0;
-              VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb);
-              i++)
-           {
-             cxx_binding **b;
-             b = &IDENTIFIER_BINDING (cb->identifier);
-             while (*b != &old_base[i].base)
-               b = &((*b)->previous);
-             *b = &cb->base;
-           }
-       }
-      cb = VEC_quick_push (cp_class_binding, scope->class_shadowed, NULL);
-    }
-  else
     cb = VEC_safe_push (cp_class_binding, gc, scope->class_shadowed, NULL);
 
   cb->identifier = name;
-  binding = &cb->base;
+  cb->base = binding = cxx_binding_make (value, type);
   binding->scope = scope;
-  cxx_binding_init (binding, value, type);
   return binding;
 }
 
@@ -354,7 +333,7 @@ new_class_binding (tree name, tree value, tree type, cxx_scope *scope)
    level at which this declaration is being bound.  */
 
 static void
-push_binding (tree id, tree decl, cxx_scope* level)
+push_binding (tree id, tree decl, cp_binding_level* level)
 {
   cxx_binding *binding;
 
@@ -416,6 +395,19 @@ pop_binding (tree id, tree decl)
     }
 }
 
+/* Strip non dependent using declarations.  */
+
+tree
+strip_using_decl (tree decl)
+{
+  if (decl == NULL_TREE)
+    return NULL_TREE;
+
+  while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
+    decl = USING_DECL_DECLS (decl);
+  return decl;
+}
+
 /* BINDING records an existing declaration for a name in the current scope.
    But, DECL is another declaration for that same identifier in the
    same scope.  This is the `struct stat' hack whereby a non-typedef
@@ -435,32 +427,50 @@ pop_binding (tree id, tree decl)
    was successful.  */
 
 static bool
-supplement_binding (cxx_binding *binding, tree decl)
+supplement_binding_1 (cxx_binding *binding, tree decl)
 {
   tree bval = binding->value;
   bool ok = true;
-
-  timevar_push (TV_NAME_LOOKUP);
-  if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
+  tree target_bval = strip_using_decl (bval);
+  tree target_decl = strip_using_decl (decl);
+
+  if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)
+      && target_decl != target_bval
+      && (TREE_CODE (target_bval) != TYPE_DECL
+         /* We allow pushing an enum multiple times in a class
+            template in order to handle late matching of underlying
+            type on an opaque-enum-declaration followed by an
+            enum-specifier.  */
+         || (TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
+             && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
+             && (dependent_type_p (ENUM_UNDERLYING_TYPE
+                                   (TREE_TYPE (target_decl)))
+                 || dependent_type_p (ENUM_UNDERLYING_TYPE
+                                      (TREE_TYPE (target_bval)))))))
     /* The new name is the type name.  */
     binding->type = decl;
-  else if (/* BVAL is null when push_class_level_binding moves an
-             inherited type-binding out of the way to make room for a
-             new value binding.  */
-          !bval
-          /* BVAL is error_mark_node when DECL's name has been used
-             in a non-class scope prior declaration.  In that case,
-             we should have already issued a diagnostic; for graceful
-             error recovery purpose, pretend this was the intended
-             declaration for that name.  */
-          || bval == error_mark_node
-          /* If BVAL is anticipated but has not yet been declared,
-             pretend it is not there at all.  */
-          || (TREE_CODE (bval) == FUNCTION_DECL
-              && DECL_ANTICIPATED (bval)
-              && !DECL_HIDDEN_FRIEND_P (bval)))
+  else if (/* TARGET_BVAL is null when push_class_level_binding moves
+             an inherited type-binding out of the way to make room
+             for a new value binding.  */
+          !target_bval
+          /* TARGET_BVAL is error_mark_node when TARGET_DECL's name
+             has been used in a non-class scope prior declaration.
+             In that case, we should have already issued a
+             diagnostic; for graceful error recovery purpose, pretend
+             this was the intended declaration for that name.  */
+          || target_bval == error_mark_node
+          /* If TARGET_BVAL is anticipated but has not yet been
+             declared, pretend it is not there at all.  */
+          || (TREE_CODE (target_bval) == FUNCTION_DECL
+              && DECL_ANTICIPATED (target_bval)
+              && !DECL_HIDDEN_FRIEND_P (target_bval)))
     binding->value = decl;
-  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
+  else if (TREE_CODE (target_bval) == TYPE_DECL
+          && DECL_ARTIFICIAL (target_bval)
+          && target_decl != target_bval
+          && (TREE_CODE (target_decl) != TYPE_DECL
+              || same_type_p (TREE_TYPE (target_decl),
+                              TREE_TYPE (target_bval))))
     {
       /* The old binding was a type name.  It was placed in
         VALUE field because it was thought, at the point it was
@@ -471,15 +481,15 @@ supplement_binding (cxx_binding *binding, tree decl)
       binding->value = decl;
       binding->value_is_inherited = false;
     }
-  else if (TREE_CODE (bval) == TYPE_DECL
-          && TREE_CODE (decl) == TYPE_DECL
-          && DECL_NAME (decl) == DECL_NAME (bval)
+  else if (TREE_CODE (target_bval) == TYPE_DECL
+          && TREE_CODE (target_decl) == TYPE_DECL
+          && DECL_NAME (target_decl) == DECL_NAME (target_bval)
           && binding->scope->kind != sk_class
-          && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
+          && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))
               /* If either type involves template parameters, we must
                  wait until instantiation.  */
-              || uses_template_parms (TREE_TYPE (decl))
-              || uses_template_parms (TREE_TYPE (bval))))
+              || uses_template_parms (TREE_TYPE (target_decl))
+              || uses_template_parms (TREE_TYPE (target_bval))))
     /* We have two typedef-names, both naming the same type to have
        the same name.  In general, this is OK because of:
 
@@ -501,9 +511,10 @@ supplement_binding (cxx_binding *binding, tree decl)
 
        A member shall not be declared twice in the
        member-specification.  */
-  else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
-          && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
-          && !DECL_CLASS_SCOPE_P (decl))
+  else if (TREE_CODE (target_decl) == VAR_DECL
+          && TREE_CODE (target_bval) == VAR_DECL
+          && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
+          && !DECL_CLASS_SCOPE_P (target_decl))
     {
       duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
       ok = false;
@@ -522,18 +533,46 @@ supplement_binding (cxx_binding *binding, tree decl)
     ok = false;
   else
     {
-      error ("declaration of %q#D", decl);
-      error ("conflicts with previous declaration %q+#D", bval);
+      diagnose_name_conflict (decl, bval);
       ok = false;
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
+  return ok;
+}
+
+/* Diagnose a name conflict between DECL and BVAL.  */
+
+static void
+diagnose_name_conflict (tree decl, tree bval)
+{
+  if (TREE_CODE (decl) == TREE_CODE (bval)
+      && (TREE_CODE (decl) != TYPE_DECL
+         || (DECL_ARTIFICIAL (decl) && DECL_ARTIFICIAL (bval))
+         || (!DECL_ARTIFICIAL (decl) && !DECL_ARTIFICIAL (bval)))
+      && !is_overloaded_fn (decl))
+    error ("redeclaration of %q#D", decl);
+  else
+    error ("%q#D conflicts with a previous declaration", decl);
+
+  inform (input_location, "previous declaration %q+#D", bval);
+}
+
+/* Wrapper for supplement_binding_1.  */
+
+static bool
+supplement_binding (cxx_binding *binding, tree decl)
+{
+  bool ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = supplement_binding_1 (binding, decl);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 /* Add DECL to the list of things declared in B.  */
 
 static void
-add_decl_to_level (tree decl, cxx_scope *b)
+add_decl_to_level (tree decl, cp_binding_level *b)
 {
   /* We used to record virtual tables as if they were ordinary
      variables, but no longer do so.  */
@@ -542,7 +581,7 @@ add_decl_to_level (tree decl, cxx_scope *b)
   if (TREE_CODE (decl) == NAMESPACE_DECL
       && !DECL_NAMESPACE_ALIAS (decl))
     {
-      TREE_CHAIN (decl) = b->namespaces;
+      DECL_CHAIN (decl) = b->namespaces;
       b->namespaces = decl;
     }
   else
@@ -551,7 +590,6 @@ add_decl_to_level (tree decl, cxx_scope *b)
         necessary.  */
       TREE_CHAIN (decl) = b->names;
       b->names = decl;
-      b->names_size++;
 
       /* If appropriate, add decl to separate list of statics.  We
         include extern variables because they might turn out to be
@@ -575,17 +613,15 @@ add_decl_to_level (tree decl, cxx_scope *b)
    If an old decl is returned, it may have been smashed
    to agree with what X says.  */
 
-tree
-pushdecl_maybe_friend (tree x, bool is_friend)
+static tree
+pushdecl_maybe_friend_1 (tree x, bool is_friend)
 {
   tree t;
   tree name;
   int need_new_binding;
 
-  timevar_push (TV_NAME_LOOKUP);
-
   if (x == error_mark_node)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+    return error_mark_node;
 
   need_new_binding = 1;
 
@@ -707,7 +743,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                      = htab_create_ggc (20, cxx_int_tree_map_hash,
                                         cxx_int_tree_map_eq, NULL);
 
-                 h = GGC_NEW (struct cxx_int_tree_map);
+                 h = ggc_alloc_cxx_int_tree_map ();
                  h->uid = DECL_UID (x);
                  h->to = t;
                  loc = htab_find_slot_with_hash
@@ -721,7 +757,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
              /* Check for duplicate params.  */
              tree d = duplicate_decls (x, t, is_friend);
              if (d)
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, d);
+               return d;
            }
          else if ((DECL_EXTERN_C_FUNCTION_P (x)
                    || DECL_FUNCTION_TEMPLATE_P (x))
@@ -734,7 +770,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                         TREE_TYPE (x));
              
              /* Throw away the redeclaration.  */
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+             return t;
            }
          else
            {
@@ -743,14 +779,14 @@ pushdecl_maybe_friend (tree x, bool is_friend)
              /* If the redeclaration failed, we can stop at this
                 point.  */
              if (olddecl == error_mark_node)
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+               return error_mark_node;
 
              if (olddecl)
                {
                  if (TREE_CODE (t) == TYPE_DECL)
                    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
 
-                 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+                 return t;
                }
              else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
                {
@@ -764,7 +800,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                  error ("as %qD", x);
                  /* We don't try to push this declaration since that
                     causes a crash.  */
-                 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+                 return x;
                }
            }
        }
@@ -780,18 +816,12 @@ pushdecl_maybe_friend (tree x, bool is_friend)
          && !DECL_ARTIFICIAL (x)
          && !DECL_IN_SYSTEM_HEADER (x))
        {
-         cxx_binding *function_binding =
-             lookup_extern_c_fun_binding_in_all_ns (x);
-         tree previous = (function_binding
-                          ? function_binding->value
-                          : NULL_TREE);
+         tree previous = lookup_extern_c_fun_in_all_ns (x);
          if (previous
              && !DECL_ARTIFICIAL (previous)
               && !DECL_IN_SYSTEM_HEADER (previous)
              && DECL_CONTEXT (previous) != DECL_CONTEXT (x))
            {
-             tree previous = function_binding->value;
-
              /* In case either x or previous is declared to throw an exception,
                 make sure both exception specifications are equal.  */
              if (decls_match (x, previous))
@@ -805,15 +835,21 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                                TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous));
                  if (!comp_except_specs (previous_exception_spec,
                                          x_exception_spec,
-                                         true))
+                                         ce_normal))
                    {
-                     pedwarn (input_location, 0, "declaration of %q#D with C language linkage",
+                     pedwarn (input_location, 0,
+                               "declaration of %q#D with C language linkage",
                               x);
-                     pedwarn (input_location, 0, "conflicts with previous declaration %q+#D",
+                     pedwarn (input_location, 0,
+                               "conflicts with previous declaration %q+#D",
                               previous);
-                     pedwarn (input_location, 0, "due to different exception specifications");
-                     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+                     pedwarn (input_location, 0,
+                               "due to different exception specifications");
+                     return error_mark_node;
                    }
+                 if (DECL_ASSEMBLER_NAME_SET_P (previous))
+                   SET_DECL_ASSEMBLER_NAME (x,
+                                            DECL_ASSEMBLER_NAME (previous));
                }
              else
                {
@@ -853,11 +889,11 @@ pushdecl_maybe_friend (tree x, bool is_friend)
            add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
        }
 
-      if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
-       check_default_args (x);
+      if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+       check_default_args (t);
 
       if (t != x || DECL_FUNCTION_TEMPLATE_P (t))
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+       return t;
 
       /* If declaring a type as a typedef, copy the type (unless we're
         at line 0), and install this TYPE_DECL as the new type's typedef
@@ -880,6 +916,13 @@ pushdecl_maybe_friend (tree x, bool is_friend)
              && TYPE_NAME (type)
              && TYPE_IDENTIFIER (type))
            set_identifier_type_value (DECL_NAME (x), x);
+
+         /* If this is a locally defined typedef in a function that
+            is not a template instantation, record it to implement
+            -Wunused-local-typedefs.  */
+         if (current_instantiation () == NULL
+             || (current_instantiation ()->decl != current_function_decl))
+         record_locally_defined_typedef (x);
        }
 
       /* Multiple external decls of the same identifier ought to match.
@@ -946,8 +989,15 @@ pushdecl_maybe_friend (tree x, bool is_friend)
       else
        {
          /* Here to install a non-global value.  */
-         tree oldlocal = innermost_non_namespace_value (name);
          tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
+         tree oldlocal = NULL_TREE;
+         cp_binding_level *oldscope = NULL;
+         cxx_binding *oldbinding = outer_binding (name, NULL, true);
+         if (oldbinding)
+           {
+             oldlocal = oldbinding->value;
+             oldscope = oldbinding->scope;
+           }
 
          if (need_new_binding)
            {
@@ -994,7 +1044,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                /* OK */;
              else
                {
-                 warning (0, "extern declaration of %q#D doesn't match", x);
+                 warning (0, "extern declaration of %q#D doesn%'t match", x);
                  warning (0, "global declaration %q+#D", oldglobal);
                }
            }
@@ -1016,19 +1066,29 @@ pushdecl_maybe_friend (tree x, bool is_friend)
          else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
                   /* Inline decls shadow nothing.  */
                   && !DECL_FROM_INLINE (x)
-                  && TREE_CODE (oldlocal) == PARM_DECL
-                  /* Don't check the `this' parameter.  */
-                  && !DECL_ARTIFICIAL (oldlocal))
+                  && (TREE_CODE (oldlocal) == PARM_DECL
+                      || TREE_CODE (oldlocal) == VAR_DECL
+                       /* If the old decl is a type decl, only warn if the
+                          old decl is an explicit typedef or if both the old
+                          and new decls are type decls.  */
+                       || (TREE_CODE (oldlocal) == TYPE_DECL
+                           && (!DECL_ARTIFICIAL (oldlocal)
+                               || TREE_CODE (x) == TYPE_DECL)))
+                   /* Don't check for internally generated vars unless
+                      it's an implicit typedef (see create_implicit_typedef
+                      in decl.c).  */
+                  && (!DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x)))
            {
-             bool err = false;
+             bool nowarn = false;
 
              /* Don't complain if it's from an enclosing function.  */
              if (DECL_CONTEXT (oldlocal) == current_function_decl
-                 && TREE_CODE (x) != PARM_DECL)
+                 && TREE_CODE (x) != PARM_DECL
+                 && TREE_CODE (oldlocal) == PARM_DECL)
                {
                  /* Go to where the parms should be and see if we find
                     them there.  */
-                 struct cp_binding_level *b = current_binding_level->level_chain;
+                 cp_binding_level *b = current_binding_level->level_chain;
 
                  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
                    /* Skip the ctor/dtor cleanup level.  */
@@ -1038,23 +1098,70 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                  if (b->kind == sk_function_parms)
                    {
                      error ("declaration of %q#D shadows a parameter", x);
-                     err = true;
+                     nowarn = true;
                    }
                }
 
-             if (warn_shadow && !err)
+             /* The local structure or class can't use parameters of
+                the containing function anyway.  */
+             if (DECL_CONTEXT (oldlocal) != current_function_decl)
+               {
+                 cp_binding_level *scope = current_binding_level;
+                 tree context = DECL_CONTEXT (oldlocal);
+                 for (; scope; scope = scope->level_chain)
+                  {
+                    if (scope->kind == sk_function_parms
+                        && scope->this_entity == context)
+                     break;
+                    if (scope->kind == sk_class
+                        && !LAMBDA_TYPE_P (scope->this_entity))
+                      {
+                        nowarn = true;
+                        break;
+                      }
+                  }
+               }
+             /* Error if redeclaring a local declared in a
+                for-init-statement or in the condition of an if or
+                switch statement when the new declaration is in the
+                outermost block of the controlled statement.
+                Redeclaring a variable from a for or while condition is
+                detected elsewhere.  */
+             else if (TREE_CODE (oldlocal) == VAR_DECL
+                      && oldscope == current_binding_level->level_chain
+                      && (oldscope->kind == sk_cond
+                          || oldscope->kind == sk_for))
+               {
+                 error ("redeclaration of %q#D", x);
+                 error ("%q+#D previously declared here", oldlocal);
+               }
+
+             if (warn_shadow && !nowarn)
                {
-                 warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x);
-                 warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
+                 if (TREE_CODE (oldlocal) == PARM_DECL)
+                   warning_at (input_location, OPT_Wshadow,
+                               "declaration of %q#D shadows a parameter", x);
+                 else if (is_capture_proxy (oldlocal))
+                   warning_at (input_location, OPT_Wshadow,
+                               "declaration of %qD shadows a lambda capture",
+                               x);
+                 else
+                   warning_at (input_location, OPT_Wshadow,
+                               "declaration of %qD shadows a previous local",
+                               x);
+                  warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow,
+                              "shadowed declaration is here");
                }
            }
 
          /* Maybe warn if shadowing something else.  */
          else if (warn_shadow && !DECL_EXTERNAL (x)
-             /* No shadow warnings for internally generated vars.  */
-             && ! DECL_ARTIFICIAL (x)
-             /* No shadow warnings for vars made for inlining.  */
-             && ! DECL_FROM_INLINE (x))
+                   /* No shadow warnings for internally generated vars unless
+                      it's an implicit typedef (see create_implicit_typedef
+                      in decl.c).  */
+                   && (! DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x))
+                   /* No shadow warnings for vars made for inlining.  */
+                   && ! DECL_FROM_INLINE (x))
            {
              tree member;
 
@@ -1062,7 +1169,8 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                member = lookup_member (current_class_type,
                                        name,
                                        /*protect=*/0,
-                                       /*want_type=*/false);
+                                       /*want_type=*/false,
+                                       tf_warning_or_error);
              else
                member = NULL_TREE;
 
@@ -1072,19 +1180,20 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                  warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
                           x);
                }
-             else if (oldlocal != NULL_TREE
-                      && TREE_CODE (oldlocal) == VAR_DECL)
-               {
-                 warning (OPT_Wshadow, "declaration of %qD shadows a previous local", x);
-                 warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
-               }
              else if (oldglobal != NULL_TREE
-                      && TREE_CODE (oldglobal) == VAR_DECL)
+                      && (TREE_CODE (oldglobal) == VAR_DECL
+                           /* If the old decl is a type decl, only warn if the
+                              old decl is an explicit typedef or if both the
+                              old and new decls are type decls.  */
+                           || (TREE_CODE (oldglobal) == TYPE_DECL
+                               && (!DECL_ARTIFICIAL (oldglobal)
+                                   || TREE_CODE (x) == TYPE_DECL))))
                /* XXX shadow warnings in outer-more namespaces */
                {
-                 warning (OPT_Wshadow, "declaration of %qD shadows a global declaration",
-                          x);
-                 warning (OPT_Wshadow, "%Jshadowed declaration is here", oldglobal);
+                 warning_at (input_location, OPT_Wshadow,
+                             "declaration of %qD shadows a global declaration", x);
+                 warning_at (DECL_SOURCE_LOCATION (oldglobal), OPT_Wshadow,
+                             "shadowed declaration is here");
                }
            }
        }
@@ -1099,7 +1208,19 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
                       : current_binding_level);
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+  return x;
+}
+
+/* Wrapper for pushdecl_maybe_friend_1.  */
+
+tree
+pushdecl_maybe_friend (tree x, bool is_friend)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = pushdecl_maybe_friend_1 (x, is_friend);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 /* Record a decl-node X as belonging to the current lexical scope.  */
@@ -1126,9 +1247,9 @@ maybe_push_decl (tree decl)
          && DECL_CONTEXT (decl) != NULL_TREE
          /* Definitions of namespace members outside their namespace are
             possible.  */
-         && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+         && !DECL_NAMESPACE_SCOPE_P (decl))
       || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
-      || TREE_CODE (type) == UNKNOWN_TYPE
+      || type == unknown_type_node
       /* The declaration of a template specialization does not affect
         the functions available for overload resolution, so we do not
         call pushdecl.  */
@@ -1147,7 +1268,7 @@ maybe_push_decl (tree decl)
 void
 push_local_binding (tree id, tree decl, int flags)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
 
   /* Skip over any local classes.  This makes sense if we call
      push_local_binding with a friend decl of a local class.  */
@@ -1257,7 +1378,6 @@ check_for_out_of_scope_variable (tree decl)
 static bool keep_next_level_flag;
 
 static int binding_depth = 0;
-static int is_class_level = 0;
 
 static void
 indent (int depth)
@@ -1270,7 +1390,7 @@ indent (int depth)
 
 /* Return a string describing the kind of SCOPE we have.  */
 static const char *
-cxx_scope_descriptor (cxx_scope *scope)
+cp_binding_level_descriptor (cp_binding_level *scope)
 {
   /* The order of this table must match the "scope_kind"
      enumerators.  */
@@ -1295,9 +1415,9 @@ cxx_scope_descriptor (cxx_scope *scope)
 /* Output a debugging information about SCOPE when performing
    ACTION at LINE.  */
 static void
-cxx_scope_debug (cxx_scope *scope, int line, const char *action)
+cp_binding_level_debug (cp_binding_level *scope, int line, const char *action)
 {
-  const char *desc = cxx_scope_descriptor (scope);
+  const char *desc = cp_binding_level_descriptor (scope);
   if (scope->this_entity)
     verbatim ("%s %s(%E) %p %d\n", action, desc,
              scope->this_entity, (void *) scope, line);
@@ -1322,12 +1442,12 @@ namespace_scope_ht_size (tree ns)
 
 /* A chain of binding_level structures awaiting reuse.  */
 
-static GTY((deletable)) struct cp_binding_level *free_binding_level;
+static GTY((deletable)) cp_binding_level *free_binding_level;
 
 /* Insert SCOPE as the innermost binding level.  */
 
 void
-push_binding_level (struct cp_binding_level *scope)
+push_binding_level (cp_binding_level *scope)
 {
   /* Add it to the front of currently active scopes stack.  */
   scope->level_chain = current_binding_level;
@@ -1338,8 +1458,7 @@ push_binding_level (struct cp_binding_level *scope)
     {
       scope->binding_depth = binding_depth;
       indent (binding_depth);
-      cxx_scope_debug (scope, input_line, "push");
-      is_class_level = 0;
+      cp_binding_level_debug (scope, input_line, "push");
       binding_depth++;
     }
 }
@@ -1348,20 +1467,20 @@ push_binding_level (struct cp_binding_level *scope)
    ENTITY is the scope of the associated C++ entity (namespace, class,
    function, C++0x enumeration); it is NULL otherwise.  */
 
-cxx_scope *
+cp_binding_level *
 begin_scope (scope_kind kind, tree entity)
 {
-  cxx_scope *scope;
+  cp_binding_level *scope;
 
   /* Reuse or create a struct for this binding level.  */
   if (!ENABLE_SCOPE_CHECKING && free_binding_level)
     {
       scope = free_binding_level;
-      memset (scope, 0, sizeof (cxx_scope));
+      memset (scope, 0, sizeof (cp_binding_level));
       free_binding_level = scope->level_chain;
     }
   else
-    scope = GGC_CNEW (cxx_scope);
+    scope = ggc_alloc_cleared_cp_binding_level ();
 
   scope->this_entity = entity;
   scope->more_cleanups_ok = true;
@@ -1380,6 +1499,7 @@ begin_scope (scope_kind kind, tree entity)
     case sk_try:
     case sk_catch:
     case sk_for:
+    case sk_cond:
     case sk_class:
     case sk_scoped_enum:
     case sk_function_parms:
@@ -1411,10 +1531,10 @@ begin_scope (scope_kind kind, tree entity)
 /* We're about to leave current scope.  Pop the top of the stack of
    currently active scopes.  Return the enclosing scope, now active.  */
 
-cxx_scope *
+cp_binding_level *
 leave_scope (void)
 {
-  cxx_scope *scope = current_binding_level;
+  cp_binding_level *scope = current_binding_level;
 
   if (scope->kind == sk_namespace && class_binding_level)
     current_binding_level = class_binding_level;
@@ -1426,13 +1546,7 @@ leave_scope (void)
   if (ENABLE_SCOPE_CHECKING)
     {
       indent (--binding_depth);
-      cxx_scope_debug (scope, input_line, "leave");
-      if (is_class_level != (scope == class_binding_level))
-       {
-         indent (binding_depth);
-         verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
-       }
-      is_class_level = 0;
+      cp_binding_level_debug (scope, input_line, "leave");
     }
 
   /* Move one nesting level up.  */
@@ -1469,7 +1583,7 @@ leave_scope (void)
 }
 
 static void
-resume_scope (struct cp_binding_level* b)
+resume_scope (cp_binding_level* b)
 {
   /* Resuming binding levels is meant only for namespaces,
      and those cannot nest into classes.  */
@@ -1481,18 +1595,17 @@ resume_scope (struct cp_binding_level* b)
     {
       b->binding_depth = binding_depth;
       indent (binding_depth);
-      cxx_scope_debug (b, input_line, "resume");
-      is_class_level = 0;
+      cp_binding_level_debug (b, input_line, "resume");
       binding_depth++;
     }
 }
 
 /* Return the innermost binding level that is not for a class scope.  */
 
-static cxx_scope *
+static cp_binding_level *
 innermost_nonclass_level (void)
 {
-  cxx_scope *b;
+  cp_binding_level *b;
 
   b = current_binding_level;
   while (b->kind == sk_class)
@@ -1517,9 +1630,9 @@ maybe_push_cleanup_level (tree type)
     }
 }
 
-/* Nonzero if we are currently in the global binding level.  */
+/* Return true if we are in the global binding level.  */
 
-int
+bool
 global_bindings_p (void)
 {
   return global_scope_p (current_binding_level);
@@ -1534,7 +1647,7 @@ global_bindings_p (void)
 bool
 toplevel_bindings_p (void)
 {
-  struct cp_binding_level *b = innermost_nonclass_level ();
+  cp_binding_level *b = innermost_nonclass_level ();
 
   return b->kind == sk_namespace || b->kind == sk_template_parms;
 }
@@ -1546,11 +1659,20 @@ toplevel_bindings_p (void)
 bool
 namespace_bindings_p (void)
 {
-  struct cp_binding_level *b = innermost_nonclass_level ();
+  cp_binding_level *b = innermost_nonclass_level ();
 
   return b->kind == sk_namespace;
 }
 
+/* True if the innermost non-class scope is a block scope.  */
+
+bool
+local_bindings_p (void)
+{
+  cp_binding_level *b = innermost_nonclass_level ();
+  return b->kind < sk_function_parms || b->kind == sk_omp;
+}
+
 /* True if the current level needs to have a BLOCK made.  */
 
 bool
@@ -1600,12 +1722,28 @@ getdecls (void)
   return current_binding_level->names;
 }
 
+/* Return how many function prototypes we are currently nested inside.  */
+
+int
+function_parm_depth (void)
+{
+  int level = 0;
+  cp_binding_level *b;
+
+  for (b = current_binding_level;
+       b->kind == sk_function_parms;
+       b = b->level_chain)
+    ++level;
+
+  return level;
+}
+
 /* For debugging.  */
 static int no_print_functions = 0;
 static int no_print_builtins = 0;
 
 static void
-print_binding_level (struct cp_binding_level* lvl)
+print_binding_level (cp_binding_level* lvl)
 {
   tree t;
   int i = 0, len;
@@ -1651,9 +1789,7 @@ print_binding_level (struct cp_binding_level* lvl)
       size_t i;
       cp_class_binding *b;
       fprintf (stderr, " class-shadowed:");
-      for (i = 0;
-          VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b);
-          ++i)
+      FOR_EACH_VEC_ELT (cp_class_binding, lvl->class_shadowed, i, b)
        fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
       fprintf (stderr, "\n");
     }
@@ -1669,9 +1805,9 @@ print_binding_level (struct cp_binding_level* lvl)
 }
 
 void
-print_other_binding_stack (struct cp_binding_level *stack)
+print_other_binding_stack (cp_binding_level *stack)
 {
-  struct cp_binding_level *level;
+  cp_binding_level *level;
   for (level = stack; !global_scope_p (level); level = level->level_chain)
     {
       fprintf (stderr, "binding level %p\n", (void *) level);
@@ -1682,7 +1818,7 @@ print_other_binding_stack (struct cp_binding_level *stack)
 void
 print_binding_stack (void)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   fprintf (stderr, "current_binding_level=%p\n"
           "class_binding_level=%p\n"
           "NAMESPACE_LEVEL (global_namespace)=%p\n",
@@ -1705,26 +1841,38 @@ print_binding_stack (void)
   print_binding_level (NAMESPACE_LEVEL (global_namespace));
 }
 \f
-/* Return the type associated with id.  */
+/* Return the type associated with ID.  */
 
-tree
-identifier_type_value (tree id)
+static tree
+identifier_type_value_1 (tree id)
 {
-  timevar_push (TV_NAME_LOOKUP);
   /* There is no type with that name, anywhere.  */
   if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+    return NULL_TREE;
   /* This is not the type marker, but the real thing.  */
   if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
+    return 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, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
   if (id)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+    return TREE_TYPE (id);
+  return NULL_TREE;
+}
+
+/* Wrapper for identifier_type_value_1.  */
+
+tree
+identifier_type_value (tree id)
+{
+  tree ret;
+  timevar_start (TV_NAME_LOOKUP);
+  ret = identifier_type_value_1 (id);
+  timevar_stop (TV_NAME_LOOKUP);
+  return ret;
 }
 
+
 /* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
    the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
 
@@ -1739,7 +1887,7 @@ identifier_global_value   (tree t)
    the tag ID is not already defined.  */
 
 static void
-set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b)
+set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b)
 {
   tree type;
 
@@ -1843,24 +1991,39 @@ make_anon_name (void)
   return get_identifier (buf);
 }
 
+/* This code is practically identical to that for creating
+   anonymous names, but is just used for lambdas instead.  This is necessary
+   because anonymous names are recognized and cannot be passed to template
+   functions.  */
+/* FIXME is this still necessary? */
+
+static GTY(()) int lambda_cnt = 0;
+
+tree
+make_lambda_name (void)
+{
+  char buf[32];
+
+  sprintf (buf, LAMBDANAME_FORMAT, lambda_cnt++);
+  return get_identifier (buf);
+}
+
 /* Return (from the stack of) the BINDING, if any, established at SCOPE.  */
 
 static inline cxx_binding *
-find_binding (cxx_scope *scope, cxx_binding *binding)
+find_binding (cp_binding_level *scope, cxx_binding *binding)
 {
-  timevar_push (TV_NAME_LOOKUP);
-
   for (; binding != NULL; binding = binding->previous)
     if (binding->scope == scope)
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding);
+      return binding;
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0);
+  return (cxx_binding *)0;
 }
 
 /* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
 
 static inline cxx_binding *
-cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
+cp_binding_level_find_binding_for_name (cp_binding_level *scope, tree name)
 {
   cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
   if (b)
@@ -1877,11 +2040,11 @@ cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
    found, make a new one.  */
 
 static cxx_binding *
-binding_for_name (cxx_scope *scope, tree name)
+binding_for_name (cp_binding_level *scope, tree name)
 {
   cxx_binding *result;
 
-  result = cxx_scope_find_binding_for_name (scope, name);
+  result = cp_binding_level_find_binding_for_name (scope, name);
   if (result)
     return result;
   /* Not found, make a new one.  */
@@ -1895,14 +2058,14 @@ binding_for_name (cxx_scope *scope, tree name)
 }
 
 /* Walk through the bindings associated to the name of FUNCTION,
-   and return the first binding that declares a function with a
+   and return the first declaration of a function with a
    "C" linkage specification, a.k.a 'extern "C"'.
    This function looks for the binding, regardless of which scope it
    has been defined in. It basically looks in all the known scopes.
    Note that this function does not lookup for bindings of builtin functions
    or for functions declared in system headers.  */
-static cxx_binding*
-lookup_extern_c_fun_binding_in_all_ns (tree function)
+static tree
+lookup_extern_c_fun_in_all_ns (tree function)
 {
   tree name;
   cxx_binding *iter;
@@ -1916,53 +2079,102 @@ lookup_extern_c_fun_binding_in_all_ns (tree function)
        iter;
        iter = iter->previous)
     {
-      if (iter->value
-         && TREE_CODE (iter->value) == FUNCTION_DECL
-         && DECL_EXTERN_C_P (iter->value)
-         && !DECL_ARTIFICIAL (iter->value))
+      tree ovl;
+      for (ovl = iter->value; ovl; ovl = OVL_NEXT (ovl))
        {
-         return iter;
+         tree decl = OVL_CURRENT (ovl);
+         if (decl
+             && TREE_CODE (decl) == FUNCTION_DECL
+             && DECL_EXTERN_C_P (decl)
+             && !DECL_ARTIFICIAL (decl))
+           {
+             return decl;
+           }
        }
     }
   return NULL;
 }
 
+/* Returns a list of C-linkage decls with the name NAME.  */
+
+tree
+c_linkage_bindings (tree name)
+{
+  tree decls = NULL_TREE;
+  cxx_binding *iter;
+
+  for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name);
+       iter;
+       iter = iter->previous)
+    {
+      tree ovl;
+      for (ovl = iter->value; ovl; ovl = OVL_NEXT (ovl))
+       {
+         tree decl = OVL_CURRENT (ovl);
+         if (decl
+             && DECL_EXTERN_C_P (decl)
+             && !DECL_ARTIFICIAL (decl))
+           {
+             if (decls == NULL_TREE)
+               decls = decl;
+             else
+               decls = tree_cons (NULL_TREE, decl, decls);
+           }
+       }
+    }
+  return decls;
+}
+
 /* Insert another USING_DECL into the current binding level, returning
    this declaration. If this is a redeclaration, do nothing, and
    return NULL_TREE if this not in namespace scope (in namespace
    scope, a using decl might extend any previous bindings).  */
 
 static tree
-push_using_decl (tree scope, tree name)
+push_using_decl_1 (tree scope, tree name)
 {
   tree decl;
 
-  timevar_push (TV_NAME_LOOKUP);
   gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
-  for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
+  for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl))
     if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
       break;
   if (decl)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                           namespace_bindings_p () ? decl : NULL_TREE);
+    return namespace_bindings_p () ? decl : NULL_TREE;
   decl = build_lang_decl (USING_DECL, name, NULL_TREE);
   USING_DECL_SCOPE (decl) = scope;
-  TREE_CHAIN (decl) = current_binding_level->usings;
+  DECL_CHAIN (decl) = current_binding_level->usings;
   current_binding_level->usings = decl;
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+  return decl;
+}
+
+/* Wrapper for push_using_decl_1.  */
+
+static tree
+push_using_decl (tree scope, tree name)
+{
+  tree ret;
+  timevar_start (TV_NAME_LOOKUP);
+  ret = push_using_decl_1 (scope, name);
+  timevar_stop (TV_NAME_LOOKUP);
+  return ret;
 }
 
 /* Same as pushdecl, but define X in binding-level LEVEL.  We rely on the
-   caller to set DECL_CONTEXT properly.  */
+   caller to set DECL_CONTEXT properly.
 
-tree
-pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
+   Note that this must only be used when X will be the new innermost
+   binding for its name, as we tack it onto the front of IDENTIFIER_BINDING
+   without checking to see if the current IDENTIFIER_BINDING comes from a
+   closer binding level than LEVEL.  */
+
+static tree
+pushdecl_with_scope_1 (tree x, cp_binding_level *level, bool is_friend)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   tree function_decl = current_function_decl;
 
-  timevar_push (TV_NAME_LOOKUP);
   current_function_decl = NULL_TREE;
   if (level->kind == sk_class)
     {
@@ -1979,8 +2191,21 @@ pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
       current_binding_level = b;
     }
   current_function_decl = function_decl;
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+  return x;
 }
+/* Wrapper for pushdecl_with_scope_1.  */
+
+tree
+pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = pushdecl_with_scope_1 (x, level, is_friend);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
+}
+
 
 /* DECL is a FUNCTION_DECL for a non-member function, which may have
    other definitions already in place.  We get around this by making
@@ -2004,14 +2229,13 @@ pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
    it's always DECL (and never something that's not a _DECL).  */
 
 static tree
-push_overloaded_decl (tree decl, int flags, bool is_friend)
+push_overloaded_decl_1 (tree decl, int flags, bool is_friend)
 {
   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
@@ -2049,7 +2273,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend)
              /* If DECL was a redeclaration of FN -- even an invalid
                 one -- pass that information along to our caller.  */
              if (dup == fn || dup == error_mark_node)
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup);
+               return dup;
            }
 
          /* We don't overload implicit built-ins.  duplicate_decls()
@@ -2067,7 +2291,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend)
        {
          error ("previous non-function declaration %q+#D", old);
          error ("conflicts with function declaration %q#D", decl);
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+         return decl;
        }
     }
 
@@ -2119,7 +2343,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend)
 
                /* And update the cxx_binding node.  */
                IDENTIFIER_BINDING (name)->value = new_binding;
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+               return decl;
              }
 
          /* We should always find a previous binding in this case.  */
@@ -2130,7 +2354,19 @@ push_overloaded_decl (tree decl, int flags, bool is_friend)
       push_local_binding (name, new_binding, flags);
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+  return decl;
+}
+
+/* Wrapper for push_overloaded_decl_1.  */
+
+static tree
+push_overloaded_decl (tree decl, int flags, bool is_friend)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = push_overloaded_decl_1 (decl, flags, is_friend);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 /* Check a non-member using-declaration. Return the name and scope
@@ -2342,7 +2578,7 @@ do_local_using_decl (tree decl, tree scope, tree name)
   if (decl == NULL_TREE)
     return;
 
-  if (building_stmt_tree ()
+  if (building_stmt_list_p ()
       && at_function_scope_p ())
     add_decl_expr (decl);
 
@@ -2447,6 +2683,8 @@ push_scope (tree t)
 void
 pop_scope (tree t)
 {
+  if (t == NULL_TREE)
+    return;
   if (TREE_CODE (t) == NAMESPACE_DECL)
     pop_decl_namespace ();
   else if CLASS_TYPE_P (t)
@@ -2469,12 +2707,12 @@ push_inner_scope_r (tree outer, tree inner)
     push_inner_scope_r (outer, prev);
   if (TREE_CODE (inner) == NAMESPACE_DECL)
     {
-      struct cp_binding_level *save_template_parm = 0;
+      cp_binding_level *save_template_parm = 0;
       /* Temporary take out template parameter scopes.  They are saved
         in reversed order in save_template_parm.  */
       while (current_binding_level->kind == sk_template_parms)
        {
-         struct cp_binding_level *b = current_binding_level;
+         cp_binding_level *b = current_binding_level;
          current_binding_level = b->level_chain;
          b->level_chain = save_template_parm;
          save_template_parm = b;
@@ -2486,7 +2724,7 @@ push_inner_scope_r (tree outer, tree inner)
       /* Restore template parameter scopes.  */
       while (save_template_parm)
        {
-         struct cp_binding_level *b = save_template_parm;
+         cp_binding_level *b = save_template_parm;
          save_template_parm = b->level_chain;
          b->level_chain = current_binding_level;
          current_binding_level = b;
@@ -2528,12 +2766,12 @@ pop_inner_scope (tree outer, tree inner)
     {
       if (TREE_CODE (inner) == NAMESPACE_DECL)
        {
-         struct cp_binding_level *save_template_parm = 0;
+         cp_binding_level *save_template_parm = 0;
          /* Temporary take out template parameter scopes.  They are saved
             in reversed order in save_template_parm.  */
          while (current_binding_level->kind == sk_template_parms)
            {
-             struct cp_binding_level *b = current_binding_level;
+             cp_binding_level *b = current_binding_level;
              current_binding_level = b->level_chain;
              b->level_chain = save_template_parm;
              save_template_parm = b;
@@ -2544,7 +2782,7 @@ pop_inner_scope (tree outer, tree inner)
          /* Restore template parameter scopes.  */
          while (save_template_parm)
            {
-             struct cp_binding_level *b = save_template_parm;
+             cp_binding_level *b = save_template_parm;
              save_template_parm = b->level_chain;
              b->level_chain = current_binding_level;
              current_binding_level = b;
@@ -2562,9 +2800,6 @@ pop_inner_scope (tree outer, tree inner)
 void
 pushlevel_class (void)
 {
-  if (ENABLE_SCOPE_CHECKING)
-    is_class_level = 1;
-
   class_binding_level = begin_scope (sk_class, current_class_type);
 }
 
@@ -2573,12 +2808,12 @@ pushlevel_class (void)
 void
 poplevel_class (void)
 {
-  struct cp_binding_level *level = class_binding_level;
+  cp_binding_level *level = class_binding_level;
   cp_class_binding *cb;
   size_t i;
   tree shadowed;
 
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   gcc_assert (level != 0);
 
   /* If we're leaving a toplevel class, cache its binding level.  */
@@ -2592,21 +2827,20 @@ poplevel_class (void)
   /* Remove the bindings for all of the class-level declarations.  */
   if (level->class_shadowed)
     {
-      for (i = 0;
-          VEC_iterate (cp_class_binding, level->class_shadowed, i, cb);
-          ++i)
-       IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
+      FOR_EACH_VEC_ELT (cp_class_binding, level->class_shadowed, i, cb)
+       {
+         IDENTIFIER_BINDING (cb->identifier) = cb->base->previous;
+         cxx_binding_free (cb->base);
+       }
       ggc_free (level->class_shadowed);
       level->class_shadowed = NULL;
     }
 
   /* Now, pop out of the binding level which we created up in the
      `pushlevel_class' routine.  */
-  if (ENABLE_SCOPE_CHECKING)
-    is_class_level = 1;
-
+  gcc_assert (current_binding_level == level);
   leave_scope ();
-  timevar_pop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as
@@ -2622,7 +2856,7 @@ set_inherited_value_binding_p (cxx_binding *binding, tree decl,
       tree context;
 
       if (TREE_CODE (decl) == OVERLOAD)
-       context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
+       context = ovl_scope (decl);
       else
        {
          gcc_assert (DECL_P (decl));
@@ -2650,8 +2884,14 @@ pushdecl_class_level (tree x)
 {
   tree name;
   bool is_valid = true;
+  bool subtime;
+
+  /* Do nothing if we're adding to an outer lambda closure type,
+     outer_binding will add it later if it's needed.  */
+  if (current_class_type != class_binding_level->this_entity)
+    return true;
 
-  timevar_push (TV_NAME_LOOKUP);
+  subtime = timevar_cond_start (TV_NAME_LOOKUP);
   /* Get the name of X.  */
   if (TREE_CODE (x) == OVERLOAD)
     name = DECL_NAME (get_first_fn (x));
@@ -2671,7 +2911,7 @@ pushdecl_class_level (tree x)
         aggregate, for naming purposes.  */
       tree f;
 
-      for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
+      for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = DECL_CHAIN (f))
        {
          location_t save_location = input_location;
          input_location = DECL_SOURCE_LOCATION (f);
@@ -2680,7 +2920,8 @@ pushdecl_class_level (tree x)
          input_location = save_location;
        }
     }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return is_valid;
 }
 
 /* Return the BINDING (if any) for NAME in SCOPE, which is a class
@@ -2688,7 +2929,7 @@ pushdecl_class_level (tree x)
    is not set, callers must set the PREVIOUS field explicitly.  */
 
 static cxx_binding *
-get_class_binding (tree name, cxx_scope *scope)
+get_class_binding (tree name, cp_binding_level *scope)
 {
   tree class_type;
   tree type_binding;
@@ -2699,10 +2940,12 @@ get_class_binding (tree name, cxx_scope *scope)
 
   /* Get the type binding.  */
   type_binding = lookup_member (class_type, name,
-                               /*protect=*/2, /*want_type=*/true);
+                               /*protect=*/2, /*want_type=*/true,
+                               tf_warning_or_error);
   /* Get the value binding.  */
   value_binding = lookup_member (class_type, name,
-                                /*protect=*/2, /*want_type=*/false);
+                                /*protect=*/2, /*want_type=*/false,
+                                tf_warning_or_error);
 
   if (value_binding
       && (TREE_CODE (value_binding) == TYPE_DECL
@@ -2747,24 +2990,26 @@ get_class_binding (tree name, cxx_scope *scope)
 /* Make the declaration(s) of X appear in CLASS scope under the name
    NAME.  Returns true if the binding is valid.  */
 
-bool
-push_class_level_binding (tree name, tree x)
+static bool
+push_class_level_binding_1 (tree name, tree x)
 {
   cxx_binding *binding;
   tree decl = x;
   bool ok;
 
-  timevar_push (TV_NAME_LOOKUP);
   /* The class_binding_level will be NULL if x is a template
      parameter name in a member template.  */
   if (!class_binding_level)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+    return true;
 
   if (name == error_mark_node)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+    return false;
 
   /* Check for invalid member names.  */
   gcc_assert (TYPE_BEING_DEFINED (current_class_type));
+  /* Check that we're pushing into the right binding level.  */
+  gcc_assert (current_class_type == class_binding_level->this_entity);
+
   /* We could have been passed a tree list if this is an ambiguous
      declaration. If so, pull the declaration out because
      check_template_shadow will not handle a TREE_LIST.  */
@@ -2773,7 +3018,7 @@ push_class_level_binding (tree name, tree x)
     decl = TREE_VALUE (decl);
 
   if (!check_template_shadow (decl))
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+    return false;
 
   /* [class.mem]
 
@@ -2807,7 +3052,7 @@ push_class_level_binding (tree name, tree x)
          error ("%qD has the same name as the class in which it is "
                 "declared",
                 x);
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+         return false;
        }
     }
 
@@ -2831,6 +3076,8 @@ push_class_level_binding (tree name, tree x)
     {
       tree bval = binding->value;
       tree old_decl = NULL_TREE;
+      tree target_decl = strip_using_decl (decl);
+      tree target_bval = strip_using_decl (bval);
 
       if (INHERITED_VALUE_BINDING_P (binding))
        {
@@ -2838,8 +3085,10 @@ push_class_level_binding (tree name, tree x)
             tag name, slide it over to make room for the new binding.
             The old binding is still visible if explicitly qualified
             with a class-key.  */
-         if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
-             && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
+         if (TREE_CODE (target_bval) == TYPE_DECL
+             && DECL_ARTIFICIAL (target_bval)
+             && !(TREE_CODE (target_decl) == TYPE_DECL
+                  && DECL_ARTIFICIAL (target_decl)))
            {
              old_decl = binding->type;
              binding->type = bval;
@@ -2851,18 +3100,32 @@ push_class_level_binding (tree name, tree x)
              old_decl = bval;
              /* Any inherited type declaration is hidden by the type
                 declaration in the derived class.  */
-             if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
+             if (TREE_CODE (target_decl) == TYPE_DECL
+                 && DECL_ARTIFICIAL (target_decl))
                binding->type = NULL_TREE;
            }
        }
-      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
+      else if (TREE_CODE (target_decl) == OVERLOAD
+              && is_overloaded_fn (target_bval))
        old_decl = bval;
-      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
+      else if (TREE_CODE (decl) == USING_DECL
+              && TREE_CODE (bval) == USING_DECL
+              && same_type_p (USING_DECL_SCOPE (decl),
+                              USING_DECL_SCOPE (bval)))
+       /* This is a using redeclaration that will be diagnosed later
+          in supplement_binding */
+       ;
+      else if (TREE_CODE (decl) == USING_DECL
+              && TREE_CODE (bval) == USING_DECL
+              && DECL_DEPENDENT_P (decl)
+              && DECL_DEPENDENT_P (bval))
+       return true;
+      else if (TREE_CODE (decl) == USING_DECL
+              && is_overloaded_fn (target_bval))
        old_decl = bval;
-      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+      else if (TREE_CODE (bval) == USING_DECL
+              && is_overloaded_fn (target_decl))
+       return true;
 
       if (old_decl && binding->scope == class_binding_level)
        {
@@ -2871,7 +3134,7 @@ push_class_level_binding (tree name, tree x)
             here.  This function is only used to register bindings
             from with the class definition itself.  */
          INHERITED_VALUE_BINDING_P (binding) = 0;
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+         return true;
        }
     }
 
@@ -2893,7 +3156,19 @@ push_class_level_binding (tree name, tree x)
       ok = true;
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
+  return ok;
+}
+
+/* Wrapper for push_class_level_binding_1.  */
+
+bool
+push_class_level_binding (tree name, tree x)
+{
+  bool ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = push_class_level_binding_1 (name, x);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 /* Process "using SCOPE::NAME" in a class scope.  Return the
@@ -2945,7 +3220,7 @@ do_class_using_decl (tree scope, tree name)
       return NULL_TREE;
     }
 
-  scope_dependent_p = dependent_type_p (scope);
+  scope_dependent_p = dependent_scope_p (scope);
   name_dependent_p = (scope_dependent_p
                      || (IDENTIFIER_TYPENAME_P (name)
                          && dependent_type_p (TREE_TYPE (name))));
@@ -2970,9 +3245,9 @@ do_class_using_decl (tree scope, tree name)
 
      In general, we cannot check this constraint in a template because
      we do not know the entire set of base classes of the current
-     class type.  However, if all of the base classes are
-     non-dependent, then we can avoid delaying the check until
-     instantiation.  */
+     class type. Morover, if SCOPE is dependent, it might match a
+     non-dependent base.  */
+
   if (!scope_dependent_p)
     {
       base_kind b_kind;
@@ -2987,7 +3262,7 @@ do_class_using_decl (tree scope, tree name)
        }
       else if (!name_dependent_p)
        {
-         decl = lookup_member (binfo, name, 0, false);
+         decl = lookup_member (binfo, name, 0, false, tf_warning_or_error);
          if (!decl)
            {
              error ("no members matching %<%T::%D%> in %q#T", scope, name,
@@ -2998,7 +3273,7 @@ do_class_using_decl (tree scope, tree name)
          if (BASELINK_P (decl))
            decl = BASELINK_FUNCTIONS (decl);
        }
-   }
+    }
 
   value = build_lang_decl (USING_DECL, name, NULL_TREE);
   USING_DECL_DECLS (value) = decl;
@@ -3011,30 +3286,40 @@ do_class_using_decl (tree scope, tree name)
 \f
 /* Return the binding value for name in scope.  */
 
-tree
-namespace_binding (tree name, tree scope)
+
+static tree
+namespace_binding_1 (tree name, tree scope)
 {
   cxx_binding *binding;
 
-  if (scope == NULL)
+  if (SCOPE_FILE_SCOPE_P (scope))
     scope = global_namespace;
   else
     /* Unnecessary for the global namespace because it can't be an alias. */
     scope = ORIGINAL_NAMESPACE (scope);
 
-  binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+  binding = cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
   return binding ? binding->value : NULL_TREE;
 }
 
+tree
+namespace_binding (tree name, tree scope)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = namespace_binding_1 (name, scope);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
+}
+
 /* Set the binding value for name in scope.  */
 
-void
-set_namespace_binding (tree name, tree scope, tree val)
+static void
+set_namespace_binding_1 (tree name, tree scope, tree val)
 {
   cxx_binding *b;
 
-  timevar_push (TV_NAME_LOOKUP);
   if (scope == NULL_TREE)
     scope = global_namespace;
   b = binding_for_name (NAMESPACE_LEVEL (scope), name);
@@ -3042,7 +3327,16 @@ set_namespace_binding (tree name, tree scope, tree val)
     b->value = val;
   else
     supplement_binding (b, val);
-  timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Wrapper for set_namespace_binding_1.  */
+
+void
+set_namespace_binding (tree name, tree scope, tree val)
+{
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  set_namespace_binding_1 (name, scope, val);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* Set the context of a declaration to scope. Complain if we are not
@@ -3051,7 +3345,7 @@ set_namespace_binding (tree name, tree scope, tree val)
 void
 set_decl_namespace (tree decl, tree scope, bool friendp)
 {
-  tree old, fn;
+  tree old;
 
   /* Get rid of namespace aliases.  */
   scope = ORIGINAL_NAMESPACE (scope);
@@ -3076,17 +3370,26 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
   if (old == error_mark_node)
     /* No old declaration at all.  */
     goto complain;
+  /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
+  if (TREE_CODE (old) == TREE_LIST)
+    {
+      error ("reference to %qD is ambiguous", decl);
+      print_candidates (old);
+      return;
+    }
   if (!is_overloaded_fn (decl))
-    /* Don't compare non-function decls with decls_match here, since
-       it can't check for the correct constness at this
-       point. pushdecl will find those errors later.  */
-    return;
+    {
+      /* We might have found OLD in an inline namespace inside SCOPE.  */
+      if (TREE_CODE (decl) == TREE_CODE (old))
+       DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+      /* Don't compare non-function decls with decls_match here, since
+        it can't check for the correct constness at this
+        point. pushdecl will find those errors later.  */
+      return;
+    }
   /* Since decl is a function, old should contain a function decl.  */
   if (!is_overloaded_fn (old))
     goto complain;
-  fn = OVL_CURRENT (old);
-  if (!is_associated_namespace (scope, CP_DECL_CONTEXT (fn)))
-    goto complain;
   /* A template can be explicitly specialized in any namespace.  */
   if (processing_explicit_instantiation)
     return;
@@ -3102,25 +3405,56 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
     return;
   if (is_overloaded_fn (old))
     {
-      for (; old; old = OVL_NEXT (old))
-       if (decls_match (decl, OVL_CURRENT (old)))
+      tree found = NULL_TREE;
+      tree elt = old;
+      for (; elt; elt = OVL_NEXT (elt))
+       {
+         tree ofn = OVL_CURRENT (elt);
+         /* Adjust DECL_CONTEXT first so decls_match will return true
+            if DECL will match a declaration in an inline namespace.  */
+         DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
+         if (decls_match (decl, ofn))
+           {
+             if (found && !decls_match (found, ofn))
+               {
+                 DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+                 error ("reference to %qD is ambiguous", decl);
+                 print_candidates (old);
+                 return;
+               }
+             found = ofn;
+           }
+       }
+      if (found)
+       {
+         if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found)))
+           goto complain;
+         DECL_CONTEXT (decl) = DECL_CONTEXT (found);
          return;
+       }
     }
-  else if (decls_match (decl, old))
-      return;
+  else
+    {
+      DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+      if (decls_match (decl, old))
+       return;
+    }
+
+  /* It didn't work, go back to the explicit scope.  */
+  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
  complain:
   error ("%qD should have been declared inside %qD", decl, scope);
 }
 
 /* Return the namespace where the current declaration is declared.  */
 
-static tree
+tree
 current_decl_namespace (void)
 {
   tree result;
   /* If we have been pushed into a different namespace, use it.  */
-  if (decl_namespace_list)
-    return TREE_PURPOSE (decl_namespace_list);
+  if (!VEC_empty (tree, decl_namespace_list))
+    return VEC_last (tree, decl_namespace_list);
 
   if (current_class_type)
     result = decl_namespace_context (current_class_type);
@@ -3147,7 +3481,6 @@ handle_namespace_attrs (tree ns, tree attributes)
       tree name = TREE_PURPOSE (d);
       tree args = TREE_VALUE (d);
 
-#ifdef HANDLE_PRAGMA_VISIBILITY
       if (is_attribute_p ("visibility", name))
        {
          tree x = args ? TREE_VALUE (args) : NULL_TREE;
@@ -3164,11 +3497,10 @@ handle_namespace_attrs (tree ns, tree attributes)
                     "%qD attribute is meaningless since members of the "
                     "anonymous namespace get local symbols", name);
 
-         push_visibility (TREE_STRING_POINTER (x));
+         push_visibility (TREE_STRING_POINTER (x), 1);
          saw_vis = true;
        }
       else
-#endif
        {
          warning (OPT_Wattributes, "%qD attribute directive ignored",
                   name);
@@ -3190,7 +3522,7 @@ push_namespace (tree name)
   int implicit_use = 0;
   bool anon = !name;
 
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
 
   /* We should not get here if the global_namespace is not yet constructed
      nor if NAME designates the global namespace:  The global scope is
@@ -3250,7 +3582,7 @@ push_namespace (tree name)
   /* Enter the name space.  */
   current_namespace = d;
 
-  timevar_pop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* Pop from the scope of the current namespace.  */
@@ -3285,7 +3617,8 @@ push_nested_namespace (tree ns)
 void
 pop_nested_namespace (tree ns)
 {
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  gcc_assert (current_namespace == ns);
   while (ns != global_namespace)
     {
       pop_namespace ();
@@ -3293,7 +3626,7 @@ pop_nested_namespace (tree ns)
     }
 
   pop_from_top_level ();
-  timevar_pop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* Temporarily set the namespace for the current declaration.  */
@@ -3303,8 +3636,7 @@ push_decl_namespace (tree decl)
 {
   if (TREE_CODE (decl) != NAMESPACE_DECL)
     decl = decl_namespace_context (decl);
-  decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
-                                  NULL_TREE, decl_namespace_list);
+  VEC_safe_push (tree, gc, decl_namespace_list, ORIGINAL_NAMESPACE (decl));
 }
 
 /* [namespace.memdef]/2 */
@@ -3312,20 +3644,33 @@ push_decl_namespace (tree decl)
 void
 pop_decl_namespace (void)
 {
-  decl_namespace_list = TREE_CHAIN (decl_namespace_list);
+  VEC_pop (tree, decl_namespace_list);
 }
 
 /* Return the namespace that is the common ancestor
    of two given namespaces.  */
 
 static tree
-namespace_ancestor (tree ns1, tree ns2)
+namespace_ancestor_1 (tree ns1, tree ns2)
 {
-  timevar_push (TV_NAME_LOOKUP);
+  tree nsr;
   if (is_ancestor (ns1, ns2))
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                         namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
+    nsr = ns1;
+  else
+    nsr = namespace_ancestor_1 (CP_DECL_CONTEXT (ns1), ns2);
+  return nsr;
+}
+
+/* Wrapper for namespace_ancestor_1.  */
+
+static tree
+namespace_ancestor (tree ns1, tree ns2)
+{
+  tree nsr;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  nsr = namespace_ancestor_1 (ns1, ns2);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return nsr;
 }
 
 /* Process a namespace-alias declaration.  */
@@ -3348,7 +3693,7 @@ do_namespace_alias (tree alias, tree name_space)
   pushdecl (alias);
 
   /* Emit debug info for namespace alias.  */
-  if (!building_stmt_tree ())
+  if (!building_stmt_list_p ())
     (*debug_hooks->global_decl) (alias);
 }
 
@@ -3358,10 +3703,10 @@ do_namespace_alias (tree alias, tree name_space)
 tree
 pushdecl_namespace_level (tree x, bool is_friend)
 {
-  struct cp_binding_level *b = current_binding_level;
+  cp_binding_level *b = current_binding_level;
   tree t;
 
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend);
 
   /* Now, the type_shadowed stack may screw us.  Munge it so it does
@@ -3395,23 +3740,21 @@ pushdecl_namespace_level (tree x, bool is_friend)
          *ptr = newval;
        }
     }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return t;
 }
 
 /* Insert USED into the using list of USER. Set INDIRECT_flag if this
    directive is not directly from the source. Also find the common
    ancestor and let our users know about the new namespace */
+
 static void
-add_using_namespace (tree user, tree used, bool indirect)
+add_using_namespace_1 (tree user, tree used, bool indirect)
 {
   tree t;
-  timevar_push (TV_NAME_LOOKUP);
   /* Using oneself is a no-op.  */
   if (user == used)
-    {
-      timevar_pop (TV_NAME_LOOKUP);
-      return;
-    }
+    return;
   gcc_assert (TREE_CODE (user) == NAMESPACE_DECL);
   gcc_assert (TREE_CODE (used) == NAMESPACE_DECL);
   /* Check if we already have this.  */
@@ -3421,7 +3764,6 @@ add_using_namespace (tree user, tree used, bool indirect)
       if (!indirect)
        /* Promote to direct usage.  */
        TREE_INDIRECT_USING (t) = 0;
-      timevar_pop (TV_NAME_LOOKUP);
       return;
     }
 
@@ -3439,12 +3781,21 @@ add_using_namespace (tree user, tree used, bool indirect)
   /* Recursively add all namespaces used.  */
   for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
     /* indirect usage */
-    add_using_namespace (user, TREE_PURPOSE (t), 1);
+    add_using_namespace_1 (user, TREE_PURPOSE (t), 1);
 
   /* Tell everyone using us about the new used namespaces.  */
   for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
-    add_using_namespace (TREE_PURPOSE (t), used, 1);
-  timevar_pop (TV_NAME_LOOKUP);
+    add_using_namespace_1 (TREE_PURPOSE (t), used, 1);
+}
+
+/* Wrapper for add_using_namespace_1.  */
+
+static void
+add_using_namespace (tree user, tree used, bool indirect)
+{
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  add_using_namespace_1 (user, used, indirect);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* Process a using-declaration not appearing in class or local scope.  */
@@ -3490,8 +3841,8 @@ do_using_directive (tree name_space)
 
   gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
 
-  if (building_stmt_tree ())
-    add_stmt (build_stmt (USING_STMT, name_space));
+  if (building_stmt_list_p ())
+    add_stmt (build_stmt (input_location, USING_STMT, name_space));
   name_space = ORIGINAL_NAMESPACE (name_space);
 
   if (!toplevel_bindings_p ())
@@ -3551,13 +3902,14 @@ parse_using_directive (tree name_space, tree attribs)
 static tree
 pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
 {
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   push_to_top_level ();
   x = pushdecl_namespace_level (x, is_friend);
   if (init)
-    finish_decl (x, *init, NULL_TREE, NULL_TREE);
+    cp_finish_decl (x, *init, false, NULL_TREE, 0);
   pop_from_top_level ();
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return x;
 }
 
 /* Like pushdecl, only it places X in the global scope if appropriate.  */
@@ -3621,6 +3973,31 @@ merge_functions (tree s1, tree s2)
   return s1;
 }
 
+/* Returns TRUE iff OLD and NEW are the same entity.
+
+   3 [basic]/3: An entity is a value, object, reference, function,
+   enumerator, type, class member, template, template specialization,
+   namespace, parameter pack, or this.
+
+   7.3.4 [namespace.udir]/4: If name lookup finds a declaration for a name
+   in two different namespaces, and the declarations do not declare the
+   same entity and do not declare functions, the use of the name is
+   ill-formed.  */
+
+static bool
+same_entity_p (tree one, tree two)
+{
+  if (one == two)
+    return true;
+  if (!one || !two)
+    return false;
+  if (TREE_CODE (one) == TYPE_DECL
+      && TREE_CODE (two) == TYPE_DECL
+      && same_type_p (TREE_TYPE (one), TREE_TYPE (two)))
+    return true;
+  return false;
+}
+
 /* This should return an error not all definitions define functions.
    It is not an error if we find two functions with exactly the
    same signature, only if these are selected in overload resolution.
@@ -3686,7 +4063,7 @@ ambiguous_decl (struct scope_binding *old, cxx_binding *new_binding, int flags)
 
   if (!old->value)
     old->value = val;
-  else if (val && val != old->value)
+  else if (val && !same_entity_p (val, old->value))
     {
       if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
        old->value = merge_functions (old->value, val);
@@ -3741,11 +4118,18 @@ qualify_lookup (tree val, int flags)
     return false;
   if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
     return true;
-  if ((flags & LOOKUP_PREFER_TYPES)
-      && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
-    return true;
+  if (flags & LOOKUP_PREFER_TYPES)
+    {
+      tree target_val = strip_using_decl (val);
+      if (TREE_CODE (target_val) == TYPE_DECL
+         || TREE_CODE (target_val) == TEMPLATE_DECL)
+       return true;
+    }
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
     return false;
+  /* Look through lambda things that we shouldn't be able to see.  */
+  if (is_lambda_ignored_entity (val))
+    return false;
   return true;
 }
 
@@ -3794,25 +4178,85 @@ remove_hidden_names (tree fns)
   return fns;
 }
 
+/* Suggest alternatives for NAME, an IDENTIFIER_NODE for which name
+   lookup failed.  Search through all available namespaces and print out
+   possible candidates.  */
+
+void
+suggest_alternatives_for (location_t location, tree name)
+{
+  VEC(tree,heap) *candidates = NULL;
+  VEC(tree,heap) *namespaces_to_search = NULL;
+  int max_to_search = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);
+  int n_searched = 0;
+  tree t;
+  unsigned ix;
+
+  VEC_safe_push (tree, heap, namespaces_to_search, global_namespace);
+
+  while (!VEC_empty (tree, namespaces_to_search)
+        && n_searched < max_to_search)
+    {
+      tree scope = VEC_pop (tree, namespaces_to_search);
+      struct scope_binding binding = EMPTY_SCOPE_BINDING;
+      cp_binding_level *level = NAMESPACE_LEVEL (scope);
+
+      /* Look in this namespace.  */
+      qualified_lookup_using_namespace (name, scope, &binding, 0);
+
+      n_searched++;
+
+      if (binding.value)
+       VEC_safe_push (tree, heap, candidates, binding.value);
+
+      /* Add child namespaces.  */
+      for (t = level->namespaces; t; t = DECL_CHAIN (t))
+       VEC_safe_push (tree, heap, namespaces_to_search, t);
+    }
+
+  /* If we stopped before we could examine all namespaces, inform the
+     user.  Do this even if we don't have any candidates, since there
+     might be more candidates further down that we weren't able to
+     find.  */
+  if (n_searched >= max_to_search
+      && !VEC_empty (tree, namespaces_to_search))
+    inform (location,
+           "maximum limit of %d namespaces searched for %qE",
+           max_to_search, name);
+
+  VEC_free (tree, heap, namespaces_to_search);
+
+  /* Nothing useful to report.  */
+  if (VEC_empty (tree, candidates))
+    return;
+
+  inform_n (location, VEC_length (tree, candidates),
+           "suggested alternative:",
+           "suggested alternatives:");
+
+  FOR_EACH_VEC_ELT (tree, candidates, ix, t)
+    inform (location_of (t), "  %qE", t);
+
+  VEC_free (tree, heap, candidates);
+}
+
 /* Unscoped lookup of a global: iterate over current namespaces,
    considering using-directives.  */
 
 static tree
-unqualified_namespace_lookup (tree name, int flags)
+unqualified_namespace_lookup_1 (tree name, int flags)
 {
   tree initial = current_decl_namespace ();
   tree scope = initial;
   tree siter;
-  struct cp_binding_level *level;
+  cp_binding_level *level;
   tree val = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
-
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
       struct scope_binding binding = EMPTY_SCOPE_BINDING;
       cxx_binding *b =
-        cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+        cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
       if (b)
        ambiguous_decl (&binding, b, flags);
@@ -3824,7 +4268,7 @@ unqualified_namespace_lookup (tree name, int flags)
        if (!lookup_using_namespace (name, &binding, level->using_directives,
                                     scope, flags))
          /* Give up because of error.  */
-         POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+         return error_mark_node;
 
       /* Add all _DECLs seen through global using-directives.  */
       /* XXX local and global using lists should work equally.  */
@@ -3835,7 +4279,7 @@ unqualified_namespace_lookup (tree name, int flags)
                                       DECL_NAMESPACE_USING (siter),
                                       scope, flags))
            /* Give up because of error.  */
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+           return error_mark_node;
          if (siter == scope) break;
          siter = CP_DECL_CONTEXT (siter);
        }
@@ -3844,7 +4288,19 @@ unqualified_namespace_lookup (tree name, int flags)
       if (scope == global_namespace)
        break;
     }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+  return val;
+}
+
+/* Wrapper for unqualified_namespace_lookup_1.  */
+
+static tree
+unqualified_namespace_lookup (tree name, int flags)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = unqualified_namespace_lookup_1 (name, flags);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 /* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
@@ -3875,7 +4331,7 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
   else if (cxx_dialect != cxx98 && TREE_CODE (scope) == ENUMERAL_TYPE)
     t = lookup_enumerator (scope, name);
   else if (is_class_type (scope, complain))
-    t = lookup_member (scope, name, 2, is_type_p);
+    t = lookup_member (scope, name, 2, is_type_p, tf_warning_or_error);
 
   if (!t)
     return error_mark_node;
@@ -3894,7 +4350,7 @@ lookup_using_namespace (tree name, struct scope_binding *val,
                        tree usings, tree scope, int flags)
 {
   tree iter;
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   /* Iterate over all used namespaces in current, searching for using
      directives of scope.  */
   for (iter = usings; iter; iter = TREE_CHAIN (iter))
@@ -3902,12 +4358,26 @@ lookup_using_namespace (tree name, struct scope_binding *val,
       {
        tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
        cxx_binding *val1 =
-         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+         cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (used), name);
        /* Resolve ambiguities.  */
        if (val1)
          ambiguous_decl (val, val1, flags);
       }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return val->value != error_mark_node;
+}
+
+/* Returns true iff VEC contains TARGET.  */
+
+static bool
+tree_vec_contains (VEC(tree,gc)* vec, tree target)
+{
+  unsigned int i;
+  tree elt;
+  FOR_EACH_VEC_ELT (tree,vec,i,elt)
+    if (elt == target)
+      return true;
+  return false;
 }
 
 /* [namespace.qual]
@@ -3920,72 +4390,88 @@ qualified_lookup_using_namespace (tree name, tree scope,
                                  struct scope_binding *result, int flags)
 {
   /* Maintain a list of namespaces visited...  */
-  tree seen = NULL_TREE;
+  VEC(tree,gc) *seen = NULL;
+  VEC(tree,gc) *seen_inline = NULL;
   /* ... and a list of namespace yet to see.  */
-  tree todo = NULL_TREE;
-  tree todo_maybe = NULL_TREE;
+  VEC(tree,gc) *todo = NULL;
+  VEC(tree,gc) *todo_maybe = NULL;
+  VEC(tree,gc) *todo_inline = NULL;
   tree usings;
-  timevar_push (TV_NAME_LOOKUP);
+  timevar_start (TV_NAME_LOOKUP);
   /* Look through namespace aliases.  */
   scope = ORIGINAL_NAMESPACE (scope);
-  while (scope && result->value != error_mark_node)
+
+  /* Algorithm: Starting with SCOPE, walk through the set of used
+     namespaces.  For each used namespace, look through its inline
+     namespace set for any bindings and usings.  If no bindings are
+     found, add any usings seen to the set of used namespaces.  */
+  VEC_safe_push (tree, gc, todo, scope);
+
+  while (VEC_length (tree, todo))
     {
-      cxx_binding *binding =
-       cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
-      seen = tree_cons (scope, NULL_TREE, seen);
-      if (binding)
-       ambiguous_decl (result, binding, flags);
-
-      /* Consider strong using directives always, and non-strong ones
-        if we haven't found a binding yet.  ??? Shouldn't we consider
-        non-strong ones if the initial RESULT is non-NULL, but the
-        binding in the given namespace is?  */
-      for (usings = DECL_NAMESPACE_USING (scope); usings;
-          usings = TREE_CHAIN (usings))
-       /* If this was a real directive, and we have not seen it.  */
-       if (!TREE_INDIRECT_USING (usings))
-         {
-           /* Try to avoid queuing the same namespace more than once,
-              the exception being when a namespace was already
-              enqueued for todo_maybe and then a strong using is
-              found for it.  We could try to remove it from
-              todo_maybe, but it's probably not worth the effort.  */
-           if (is_associated_namespace (scope, TREE_PURPOSE (usings))
-               && !purpose_member (TREE_PURPOSE (usings), seen)
-               && !purpose_member (TREE_PURPOSE (usings), todo))
-             todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
-           else if ((!result->value && !result->type)
-                    && !purpose_member (TREE_PURPOSE (usings), seen)
-                    && !purpose_member (TREE_PURPOSE (usings), todo)
-                    && !purpose_member (TREE_PURPOSE (usings), todo_maybe))
-             todo_maybe = tree_cons (TREE_PURPOSE (usings), NULL_TREE,
-                                     todo_maybe);
-         }
-      if (todo)
-       {
-         scope = TREE_PURPOSE (todo);
-         todo = TREE_CHAIN (todo);
-       }
-      else if (todo_maybe
-              && (!result->value && !result->type))
+      bool found_here;
+      scope = VEC_pop (tree, todo);
+      if (tree_vec_contains (seen, scope))
+       continue;
+      VEC_safe_push (tree, gc, seen, scope);
+      VEC_safe_push (tree, gc, todo_inline, scope);
+
+      found_here = false;
+      while (VEC_length (tree, todo_inline))
        {
-         scope = TREE_PURPOSE (todo_maybe);
-         todo = TREE_CHAIN (todo_maybe);
-         todo_maybe = NULL_TREE;
+         cxx_binding *binding;
+
+         scope = VEC_pop (tree, todo_inline);
+         if (tree_vec_contains (seen_inline, scope))
+           continue;
+         VEC_safe_push (tree, gc, seen_inline, scope);
+
+         binding =
+           cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+         if (binding)
+           {
+             found_here = true;
+             ambiguous_decl (result, binding, flags);
+           }
+
+         for (usings = DECL_NAMESPACE_USING (scope); usings;
+              usings = TREE_CHAIN (usings))
+           if (!TREE_INDIRECT_USING (usings))
+             {
+               if (is_associated_namespace (scope, TREE_PURPOSE (usings)))
+                 VEC_safe_push (tree, gc, todo_inline, TREE_PURPOSE (usings));
+               else
+                 VEC_safe_push (tree, gc, todo_maybe, TREE_PURPOSE (usings));
+             }
        }
+
+      if (found_here)
+       VEC_truncate (tree, todo_maybe, 0);
       else
-       scope = NULL_TREE; /* If there never was a todo list.  */
+       while (VEC_length (tree, todo_maybe))
+         VEC_safe_push (tree, gc, todo, VEC_pop (tree, todo_maybe));
     }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
+  VEC_free (tree,gc,todo);
+  VEC_free (tree,gc,todo_maybe);
+  VEC_free (tree,gc,todo_inline);
+  VEC_free (tree,gc,seen);
+  VEC_free (tree,gc,seen_inline);
+  timevar_stop (TV_NAME_LOOKUP);
+  return result->value != error_mark_node;
 }
 
 /* Subroutine of outer_binding.
-   Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
-   FALSE otherwise.  */
+
+   Returns TRUE if BINDING is a binding to a template parameter of
+   SCOPE.  In that case SCOPE is the scope of a primary template
+   parameter -- in the sense of G++, i.e, a template that has its own
+   template header.
+
+   Returns FALSE otherwise.  */
 
 static bool
 binding_to_template_parms_of_scope_p (cxx_binding *binding,
-                                     cxx_scope *scope)
+                                     cp_binding_level *scope)
 {
   tree binding_value;
 
@@ -3997,6 +4483,8 @@ binding_to_template_parms_of_scope_p (cxx_binding *binding,
   return (scope
          && scope->this_entity
          && get_template_info (scope->this_entity)
+         && PRIMARY_TEMPLATE_P (TI_TEMPLATE
+                                (get_template_info (scope->this_entity)))
          && parameter_of_template_p (binding_value,
                                      TI_TEMPLATE (get_template_info \
                                                    (scope->this_entity))));
@@ -4014,8 +4502,8 @@ outer_binding (tree name,
               bool class_p)
 {
   cxx_binding *outer;
-  cxx_scope *scope;
-  cxx_scope *outer_scope;
+  cp_binding_level *scope;
+  cp_binding_level *outer_scope;
 
   if (binding)
     {
@@ -4096,20 +4584,19 @@ innermost_non_namespace_value (tree name)
    If NONCLASS is nonzero, bindings in class scopes are ignored.  If
    BLOCK_P is false, bindings in block scopes are ignored.  */
 
-tree
-lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
-                 int namespaces_only, int flags)
+static tree
+lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
+                   int namespaces_only, int flags)
 {
   cxx_binding *iter;
   tree val = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
   /* Conversion operators are handled specially because ordinary
      unqualified name lookup will not find template conversion
      operators.  */
   if (IDENTIFIER_TYPENAME_P (name))
     {
-      struct cp_binding_level *level;
+      cp_binding_level *level;
 
       for (level = current_binding_level;
           level && level->kind != sk_namespace;
@@ -4127,10 +4614,10 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
          class_type = level->this_entity;
          operators = lookup_fnfields (class_type, name, /*protect=*/0);
          if (operators)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
+           return operators;
        }
 
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+      return NULL_TREE;
     }
 
   flags |= lookup_flags (prefer_type, namespaces_only);
@@ -4225,7 +4712,21 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
   if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
     val = OVL_FUNCTION (val);
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+  return val;
+}
+
+/* Wrapper for lookup_name_real_1.  */
+
+tree
+lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
+                 int namespaces_only, int flags)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = lookup_name_real_1 (name, prefer_type, nonclass, block_p,
+                           namespaces_only, flags);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
 tree
@@ -4235,13 +4736,13 @@ lookup_name_nonclass (tree name)
 }
 
 tree
-lookup_function_nonclass (tree name, tree args, bool block_p)
+lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
 {
   return
     lookup_arg_dependent (name,
                          lookup_name_real (name, 0, 1, block_p, 0,
                                            LOOKUP_COMPLAIN),
-                         args);
+                         args, false);
 }
 
 tree
@@ -4272,14 +4773,12 @@ lookup_name_prefer_type (tree name, int prefer_type)
    A TYPE_DECL best matching the NAME is returned.  Catching error
    and issuing diagnostics are caller's responsibility.  */
 
-tree
-lookup_type_scope (tree name, tag_scope scope)
+static tree
+lookup_type_scope_1 (tree name, tag_scope scope)
 {
   cxx_binding *iter = NULL;
   tree val = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
-
   /* Look in non-namespace scope first.  */
   if (current_binding_level->kind != sk_namespace)
     iter = outer_binding (name, NULL, /*class_p=*/ true);
@@ -4312,7 +4811,7 @@ lookup_type_scope (tree name, tag_scope scope)
   /* Look in namespace scope.  */
   if (!val)
     {
-      iter = cxx_scope_find_binding_for_name
+      iter = cp_binding_level_find_binding_for_name
               (NAMESPACE_LEVEL (current_decl_namespace ()), name);
 
       if (iter)
@@ -4330,11 +4829,11 @@ lookup_type_scope (tree name, tag_scope scope)
      and template parameter scopes.  */
   if (val)
     {
-      struct cp_binding_level *b = current_binding_level;
+      cp_binding_level *b = current_binding_level;
       while (b)
        {
          if (iter->scope == b)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+           return val;
 
          if (b->kind == sk_cleanup || b->kind == sk_template_parms
              || b->kind == sk_function_parms)
@@ -4347,19 +4846,31 @@ lookup_type_scope (tree name, tag_scope scope)
        }
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+  return NULL_TREE;
+}
+/* Wrapper for lookup_type_scope_1.  */
+
+tree
+lookup_type_scope (tree name, tag_scope scope)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = lookup_type_scope_1 (name, scope);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 
+
 /* Similar to `lookup_name' but look only in the innermost non-class
    binding level.  */
 
-tree
-lookup_name_innermost_nonclass_level (tree name)
+static tree
+lookup_name_innermost_nonclass_level_1 (tree name)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   tree t = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
   b = innermost_nonclass_level ();
 
   if (b->kind == sk_namespace)
@@ -4380,7 +4891,7 @@ lookup_name_innermost_nonclass_level (tree name)
          if (binding->scope == b
              && !(TREE_CODE (binding->value) == VAR_DECL
                   && DECL_DEAD_FOR_LOCAL (binding->value)))
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding->value);
+           return binding->value;
 
          if (b->kind == sk_cleanup)
            b = b->level_chain;
@@ -4389,7 +4900,48 @@ lookup_name_innermost_nonclass_level (tree name)
        }
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+  return t;
+}
+
+/* Wrapper for lookup_name_innermost_nonclass_level_1.  */
+
+tree
+lookup_name_innermost_nonclass_level (tree name)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = lookup_name_innermost_nonclass_level_1 (name);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
+}
+
+
+/* Returns true iff DECL is a block-scope extern declaration of a function
+   or variable.  */
+
+bool
+is_local_extern (tree decl)
+{
+  cxx_binding *binding;
+
+  /* For functions, this is easy.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    return DECL_LOCAL_FUNCTION_P (decl);
+
+  if (TREE_CODE (decl) != VAR_DECL)
+    return false;
+  if (!current_function_decl)
+    return false;
+
+  /* For variables, this is not easy.  We need to look at the binding stack
+     for the identifier to see whether the decl we have is a local.  */
+  for (binding = IDENTIFIER_BINDING (DECL_NAME (decl));
+       binding && binding->scope->kind != sk_namespace;
+       binding = binding->previous)
+    if (binding->value == decl)
+      return LOCAL_BINDING_P (binding);
+
+  return false;
 }
 
 /* Like lookup_name_innermost_nonclass_level, but for types.  */
@@ -4399,18 +4951,20 @@ lookup_type_current_level (tree name)
 {
   tree t = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
+  timevar_start (TV_NAME_LOOKUP);
   gcc_assert (current_binding_level->kind != sk_namespace);
 
   if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
       && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
     {
-      struct cp_binding_level *b = current_binding_level;
+      cp_binding_level *b = current_binding_level;
       while (1)
        {
          if (purpose_member (name, b->type_shadowed))
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                                   REAL_IDENTIFIER_TYPE_VALUE (name));
+           {
+             t = REAL_IDENTIFIER_TYPE_VALUE (name);
+             break;
+           }
          if (b->kind == sk_cleanup)
            b = b->level_chain;
          else
@@ -4418,7 +4972,8 @@ lookup_type_current_level (tree name)
        }
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+  timevar_stop (TV_NAME_LOOKUP);
+  return t;
 }
 
 /* [basic.lookup.koenig] */
@@ -4427,17 +4982,21 @@ lookup_type_current_level (tree name)
 struct arg_lookup
 {
   tree name;
-  tree args;
-  tree namespaces;
-  tree classes;
+  VEC(tree,gc) *args;
+  VEC(tree,gc) *namespaces;
+  VEC(tree,gc) *classes;
   tree functions;
+  struct pointer_set_t *fn_set;
 };
 
 static bool arg_assoc (struct arg_lookup*, tree);
 static bool arg_assoc_args (struct arg_lookup*, tree);
+static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
 static bool arg_assoc_type (struct arg_lookup*, tree);
 static bool add_function (struct arg_lookup *, tree);
 static bool arg_assoc_namespace (struct arg_lookup *, tree);
+static bool arg_assoc_class_only (struct arg_lookup *, tree);
+static bool arg_assoc_bases (struct arg_lookup *, tree);
 static bool arg_assoc_class (struct arg_lookup *, tree);
 static bool arg_assoc_template_arg (struct arg_lookup*, tree);
 
@@ -4447,32 +5006,20 @@ static bool arg_assoc_template_arg (struct arg_lookup*, tree);
 static bool
 add_function (struct arg_lookup *k, tree fn)
 {
-  /* We used to check here to see if the function was already in the list,
-     but that's O(n^2), which is just too expensive for function lookup.
-     Now we deal with the occasional duplicate in joust.  In doing this, we
-     assume that the number of duplicates will be small compared to the
-     total number of functions being compared, which should usually be the
-     case.  */
-
-  /* We must find only functions, or exactly one non-function.  */
-  if (!k->functions)
+  if (!is_overloaded_fn (fn))
+    /* All names except those of (possibly overloaded) functions and
+       function templates are ignored.  */;
+  else if (k->fn_set && pointer_set_insert (k->fn_set, fn))
+    /* It's already in the list.  */;
+  else if (!k->functions)
     k->functions = fn;
   else if (fn == k->functions)
     ;
-  else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
-    k->functions = build_overload (fn, k->functions);
   else
     {
-      tree f1 = OVL_CURRENT (k->functions);
-      tree f2 = fn;
-      if (is_overloaded_fn (f1))
-       {
-         fn = f1; f1 = f2; f2 = fn;
-       }
-      error ("%q+D is not a function,", f1);
-      error ("  conflict with %q+D", f2);
-      error ("  in call to %qD", k->name);
-      return true;
+      k->functions = build_overload (fn, k->functions);
+      if (TREE_CODE (k->functions) == OVERLOAD)
+       OVL_ARG_DEPENDENT (k->functions) = true;
     }
 
   return false;
@@ -4485,72 +5032,38 @@ add_function (struct arg_lookup *k, tree fn)
 bool
 is_associated_namespace (tree current, tree scope)
 {
-  tree seen = NULL_TREE;
-  tree todo = NULL_TREE;
+  VEC(tree,gc) *seen = make_tree_vector ();
+  VEC(tree,gc) *todo = make_tree_vector ();
   tree t;
+  bool ret;
+
   while (1)
     {
       if (scope == current)
-       return true;
-      seen = tree_cons (scope, NULL_TREE, seen);
+       {
+         ret = true;
+         break;
+       }
+      VEC_safe_push (tree, gc, seen, scope);
       for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
-       if (!purpose_member (TREE_PURPOSE (t), seen))
-         todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo);
-      if (todo)
+       if (!vec_member (TREE_PURPOSE (t), seen))
+         VEC_safe_push (tree, gc, todo, TREE_PURPOSE (t));
+      if (!VEC_empty (tree, todo))
        {
-         scope = TREE_PURPOSE (todo);
-         todo = TREE_CHAIN (todo);
+         scope = VEC_last (tree, todo);
+         VEC_pop (tree, todo);
        }
       else
-       return false;
-    }
-}
-
-/* Return whether FN is a friend of an associated class of ARG.  */
-
-static bool
-friend_of_associated_class_p (tree arg, tree fn)
-{
-  tree type;
-
-  if (TYPE_P (arg))
-    type = arg;
-  else if (type_unknown_p (arg))
-    return false;
-  else
-    type = TREE_TYPE (arg);
-
-  /* If TYPE is a class, the class itself and all base classes are
-     associated classes.  */
-  if (CLASS_TYPE_P (type))
-    {
-      if (is_friend (type, fn))
-       return true;
-
-      if (TYPE_BINFO (type))
        {
-         tree binfo, base_binfo;
-         int i;
-
-         for (binfo = TYPE_BINFO (type), i = 0;
-              BINFO_BASE_ITERATE (binfo, i, base_binfo);
-              i++)
-           if (is_friend (BINFO_TYPE (base_binfo), fn))
-             return true;
+         ret = false;
+         break;
        }
     }
 
-  /* If TYPE is a class member, the class of which it is a member is
-     an associated class.  */
-  if ((CLASS_TYPE_P (type)
-       || TREE_CODE (type) == UNION_TYPE
-       || TREE_CODE (type) == ENUMERAL_TYPE)
-      && TYPE_CONTEXT (type)
-      && CLASS_TYPE_P (TYPE_CONTEXT (type))
-      && is_friend (TYPE_CONTEXT (type), fn))
-    return true;
+  release_tree_vector (seen);
+  release_tree_vector (todo);
 
-  return false;
+  return ret;
 }
 
 /* Add functions of a namespace to the lookup structure.
@@ -4561,9 +5074,9 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
 {
   tree value;
 
-  if (purpose_member (scope, k->namespaces))
-    return 0;
-  k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
+  if (vec_member (scope, k->namespaces))
+    return false;
+  VEC_safe_push (tree, gc, k->namespaces, scope);
 
   /* Check out our super-users.  */
   for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
@@ -4586,18 +5099,9 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
     {
       /* We don't want to find arbitrary hidden functions via argument
         dependent lookup.  We only want to find friends of associated
-        classes.  */
+        classes, which we'll do via arg_assoc_class.  */
       if (hidden_name_p (OVL_CURRENT (value)))
-       {
-         tree args;
-
-         for (args = k->args; args; args = TREE_CHAIN (args))
-           if (friend_of_associated_class_p (TREE_VALUE (args),
-                                             OVL_CURRENT (value)))
-             break;
-         if (!args)
-           continue;
-       }
+       continue;
 
       if (add_function (k, OVL_CURRENT (value)))
        return true;
@@ -4636,7 +5140,7 @@ arg_assoc_template_arg (struct arg_lookup *k, tree arg)
        return arg_assoc_namespace (k, ctx);
       /* Otherwise, it must be member template.  */
       else
-       return arg_assoc_class (k, ctx);
+       return arg_assoc_class_only (k, ctx);
     }
   /* It's an argument pack; handle it recursively.  */
   else if (ARGUMENT_PACK_P (arg))
@@ -4658,38 +5162,24 @@ arg_assoc_template_arg (struct arg_lookup *k, tree arg)
     return false;
 }
 
-/* Adds everything associated with class to the lookup structure.
+/* Adds the class and its friends to the lookup structure.
    Returns true on error.  */
 
 static bool
-arg_assoc_class (struct arg_lookup *k, tree type)
+arg_assoc_class_only (struct arg_lookup *k, tree type)
 {
   tree list, friends, context;
-  int i;
 
-  /* Backend build structures, such as __builtin_va_list, aren't
+  /* Backend-built structures, such as __builtin_va_list, aren't
      affected by all this.  */
   if (!CLASS_TYPE_P (type))
     return false;
 
-  if (purpose_member (type, k->classes))
-    return false;
-  k->classes = tree_cons (type, NULL_TREE, k->classes);
-
   context = decl_namespace_context (type);
   if (arg_assoc_namespace (k, context))
     return true;
 
-  if (TYPE_BINFO (type))
-    {
-      /* Process baseclasses.  */
-      tree binfo, base_binfo;
-
-      for (binfo = TYPE_BINFO (type), i = 0;
-          BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-       if (arg_assoc_class (k, BINFO_TYPE (base_binfo)))
-         return true;
-    }
+  complete_type (type);
 
   /* Process friends.  */
   for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
@@ -4713,13 +5203,79 @@ arg_assoc_class (struct arg_lookup *k, tree type)
            return true;
        }
 
+  return false;
+}
+
+/* Adds the class and its bases to the lookup structure.
+   Returns true on error.  */
+
+static bool
+arg_assoc_bases (struct arg_lookup *k, tree type)
+{
+  if (arg_assoc_class_only (k, type))
+    return true;
+
+  if (TYPE_BINFO (type))
+    {
+      /* Process baseclasses.  */
+      tree binfo, base_binfo;
+      int i;
+
+      for (binfo = TYPE_BINFO (type), i = 0;
+          BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+       if (arg_assoc_bases (k, BINFO_TYPE (base_binfo)))
+         return true;
+    }
+
+  return false;
+}
+
+/* Adds everything associated with a class argument type to the lookup
+   structure.  Returns true on error.
+
+   If T is a class type (including unions), its associated classes are: the
+   class itself; the class of which it is a member, if any; and its direct
+   and indirect base classes. Its associated namespaces are the namespaces
+   of which its associated classes are members. Furthermore, if T is a
+   class template specialization, its associated namespaces and classes
+   also include: the namespaces and classes associated with the types of
+   the template arguments provided for template type parameters (excluding
+   template template parameters); the namespaces of which any template
+   template arguments are members; and the classes of which any member
+   templates used as template template arguments are members. [ Note:
+   non-type template arguments do not contribute to the set of associated
+   namespaces.  --end note] */
+
+static bool
+arg_assoc_class (struct arg_lookup *k, tree type)
+{
+  tree list;
+  int i;
+
+  /* Backend build structures, such as __builtin_va_list, aren't
+     affected by all this.  */
+  if (!CLASS_TYPE_P (type))
+    return false;
+
+  if (vec_member (type, k->classes))
+    return false;
+  VEC_safe_push (tree, gc, k->classes, type);
+
+  if (TYPE_CLASS_SCOPE_P (type)
+      && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
+    return true;
+
+  if (arg_assoc_bases (k, type))
+    return true;
+
   /* Process template arguments.  */
   if (CLASSTYPE_TEMPLATE_INFO (type)
       && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
     {
       list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
       for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
-       arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
+       if (arg_assoc_template_arg (k, TREE_VEC_ELT (list, i)))
+         return true;
     }
 
   return false;
@@ -4755,17 +5311,21 @@ arg_assoc_type (struct arg_lookup *k, tree type)
     case BOOLEAN_TYPE:
     case FIXED_POINT_TYPE:
     case DECLTYPE_TYPE:
+    case NULLPTR_TYPE:
       return false;
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (type))
        return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
+    case UNION_TYPE:
       return arg_assoc_class (k, type);
     case POINTER_TYPE:
     case REFERENCE_TYPE:
     case ARRAY_TYPE:
       return arg_assoc_type (k, TREE_TYPE (type));
-    case UNION_TYPE:
     case ENUMERAL_TYPE:
+      if (TYPE_CLASS_SCOPE_P (type)
+         && arg_assoc_class_only (k, TYPE_CONTEXT (type)))
+       return true;
       return arg_assoc_namespace (k, decl_namespace_context (type));
     case METHOD_TYPE:
       /* The basetype is referenced in the first arg type, so just
@@ -4805,6 +5365,21 @@ arg_assoc_args (struct arg_lookup *k, tree args)
   return false;
 }
 
+/* Adds everything associated with an argument vector.  Returns true
+   on error.  */
+
+static bool
+arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
+{
+  unsigned int ix;
+  tree arg;
+
+  FOR_EACH_VEC_ELT (tree, args, ix, arg)
+    if (arg_assoc (k, arg))
+      return true;
+  return false;
+}
+
 /* Adds everything associated with a given tree_node.  Returns 1 on error.  */
 
 static bool
@@ -4827,41 +5402,24 @@ arg_assoc (struct arg_lookup *k, tree n)
     n = TREE_OPERAND (n, 1);
   while (TREE_CODE (n) == TREE_LIST)
     n = TREE_VALUE (n);
-  if (TREE_CODE (n) == BASELINK)
+  if (BASELINK_P (n))
     n = BASELINK_FUNCTIONS (n);
 
   if (TREE_CODE (n) == FUNCTION_DECL)
     return arg_assoc_type (k, TREE_TYPE (n));
   if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
     {
-      /* [basic.lookup.koenig]
-
-        If T is a template-id, its associated namespaces and classes
-        are the namespace in which the template is defined; for
-        member templates, the member template's class...  */
+      /* The working paper doesn't currently say how to handle template-id
+        arguments.  The sensible thing would seem to be to handle the list
+        of template candidates like a normal overload set, and handle the
+        template arguments like we do for class template
+        specializations.  */
       tree templ = TREE_OPERAND (n, 0);
       tree args = TREE_OPERAND (n, 1);
-      tree ctx;
       int ix;
 
-      if (TREE_CODE (templ) == COMPONENT_REF)
-       templ = TREE_OPERAND (templ, 1);
-
-      /* First, the template.  There may actually be more than one if
-        this is an overloaded function template.  But, in that case,
-        we only need the first; all the functions will be in the same
-        namespace.  */
-      templ = OVL_CURRENT (templ);
-
-      ctx = CP_DECL_CONTEXT (templ);
-
-      if (TREE_CODE (ctx) == NAMESPACE_DECL)
-       {
-         if (arg_assoc_namespace (k, ctx) == 1)
-           return true;
-       }
-      /* It must be a member template.  */
-      else if (arg_assoc_class (k, ctx) == 1)
+      /* First the templates.  */
+      if (arg_assoc (k, templ))
        return true;
 
       /* Now the arguments.  */
@@ -4872,8 +5430,8 @@ arg_assoc (struct arg_lookup *k, tree n)
     }
   else if (TREE_CODE (n) == OVERLOAD)
     {
-      for (; n; n = OVL_CHAIN (n))
-       if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
+      for (; n; n = OVL_NEXT (n))
+       if (arg_assoc_type (k, TREE_TYPE (OVL_CURRENT (n))))
          return true;
     }
 
@@ -4883,13 +5441,12 @@ arg_assoc (struct arg_lookup *k, tree n)
 /* Performs Koenig lookup depending on arguments, where fns
    are the functions found in normal lookup.  */
 
-tree
-lookup_arg_dependent (tree name, tree fns, tree args)
+static tree
+lookup_arg_dependent_1 (tree name, tree fns, VEC(tree,gc) *args,
+                       bool include_std)
 {
   struct arg_lookup k;
 
-  timevar_push (TV_NAME_LOOKUP);
-
   /* Remove any hidden friend functions from the list of functions
      found so far.  They will be added back by arg_assoc_class as
      appropriate.  */
@@ -4898,16 +5455,35 @@ lookup_arg_dependent (tree name, tree fns, tree args)
   k.name = name;
   k.args = args;
   k.functions = fns;
-  k.classes = NULL_TREE;
+  k.classes = make_tree_vector ();
 
   /* We previously performed an optimization here by setting
      NAMESPACES to the current namespace when it was safe. However, DR
      164 says that namespaces that were already searched in the first
      stage of template processing are searched again (potentially
      picking up later definitions) in the second stage. */
-  k.namespaces = NULL_TREE;
+  k.namespaces = make_tree_vector ();
+
+  /* We used to allow duplicates and let joust discard them, but
+     since the above change for DR 164 we end up with duplicates of
+     all the functions found by unqualified lookup.  So keep track
+     of which ones we've seen.  */
+  if (fns)
+    {
+      tree ovl;
+      /* We shouldn't be here if lookup found something other than
+        namespace-scope functions.  */
+      gcc_assert (DECL_NAMESPACE_SCOPE_P (OVL_CURRENT (fns)));
+      k.fn_set = pointer_set_create ();
+      for (ovl = fns; ovl; ovl = OVL_NEXT (ovl))
+       pointer_set_insert (k.fn_set, OVL_CURRENT (ovl));
+    }
+  else
+    k.fn_set = NULL;
 
-  arg_assoc_args (&k, args);
+  if (include_std)
+    arg_assoc_namespace (&k, std_node);
+  arg_assoc_args_vec (&k, args);
 
   fns = k.functions;
   
@@ -4919,24 +5495,43 @@ lookup_arg_dependent (tree name, tree fns, tree args)
       error ("  in call to %qD", name);
       fns = error_mark_node;
     }
+
+  release_tree_vector (k.classes);
+  release_tree_vector (k.namespaces);
+  if (k.fn_set)
+    pointer_set_destroy (k.fn_set);
     
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
+  return fns;
 }
 
+/* Wrapper for lookup_arg_dependent_1.  */
+
+tree
+lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args,
+                      bool include_std)
+{
+  tree ret;
+  bool subtime;
+  subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = lookup_arg_dependent_1 (name, fns, args, include_std);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
+}
+
+
 /* Add namespace to using_directives. Return NULL_TREE if nothing was
    changed (i.e. there was already a directive), or the fresh
    TREE_LIST otherwise.  */
 
 static tree
-push_using_directive (tree used)
+push_using_directive_1 (tree used)
 {
   tree ud = current_binding_level->using_directives;
   tree iter, ancestor;
 
-  timevar_push (TV_NAME_LOOKUP);
   /* Check if we already have this.  */
   if (purpose_member (used, ud) != NULL_TREE)
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+    return NULL_TREE;
 
   ancestor = namespace_ancestor (current_decl_namespace (), used);
   ud = current_binding_level->using_directives;
@@ -4947,7 +5542,19 @@ push_using_directive (tree 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);
+  return ud;
+}
+
+/* Wrapper for push_using_directive_1.  */
+
+static tree
+push_using_directive (tree used)
+{
+  tree ret;
+  timevar_start (TV_NAME_LOOKUP);
+  ret = push_using_directive_1 (used);
+  timevar_stop (TV_NAME_LOOKUP);
+  return ret;
 }
 
 /* The type TYPE is being declared.  If it is a class template, or a
@@ -4961,7 +5568,7 @@ push_using_directive (tree used)
 
 static tree
 maybe_process_template_type_declaration (tree type, int is_friend,
-                                        cxx_scope *b)
+                                        cp_binding_level *b)
 {
   tree decl = TYPE_NAME (type);
 
@@ -5040,13 +5647,12 @@ maybe_process_template_type_declaration (tree type, int is_friend,
 
    Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
 
-tree
-pushtag (tree name, tree type, tag_scope scope)
+static tree
+pushtag_1 (tree name, tree type, tag_scope scope)
 {
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   tree decl;
 
-  timevar_push (TV_NAME_LOOKUP);
   b = current_binding_level;
   while (/* Cleanup scopes are not scopes from the point of view of
            the language.  */
@@ -5071,7 +5677,7 @@ pushtag (tree name, tree type, tag_scope scope)
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
   /* Do C++ gratuitous typedefing.  */
-  if (IDENTIFIER_TYPE_VALUE (name) != type)
+  if (identifier_type_value_1 (name) != type)
     {
       tree tdef;
       int in_class = 0;
@@ -5081,7 +5687,8 @@ pushtag (tree name, tree type, tag_scope scope)
        {
          tree cs = current_scope ();
 
-         if (scope == ts_current)
+         if (scope == ts_current
+             || (cs && TREE_CODE (cs) == FUNCTION_DECL))
            context = cs;
          else if (cs != NULL_TREE && TYPE_P (cs))
            /* When declaring a friend class of a local class, we want
@@ -5116,12 +5723,12 @@ pushtag (tree name, tree type, tag_scope scope)
       decl = maybe_process_template_type_declaration
        (type, scope == ts_within_enclosing_non_class, b);
       if (decl == error_mark_node)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+       return decl;
 
       if (b->kind == sk_class)
        {
          if (!TYPE_BEING_DEFINED (current_class_type))
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+           return error_mark_node;
 
          if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
            /* Put this TYPE_DECL on the TYPE_FIELDS list for the
@@ -5134,9 +5741,9 @@ pushtag (tree name, tree type, tag_scope scope)
        }
       else if (b->kind != sk_template_parms)
        {
-         decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
+         decl = pushdecl_with_scope_1 (decl, b, /*is_friend=*/false);
          if (decl == error_mark_node)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+           return decl;
        }
 
       if (! in_class)
@@ -5170,13 +5777,24 @@ pushtag (tree name, tree type, tag_scope scope)
 
   decl = TYPE_NAME (type);
   gcc_assert (TREE_CODE (decl) == TYPE_DECL);
-  TYPE_STUB_DECL (type) = decl;
 
   /* Set type visibility now if this is a forward declaration.  */
   TREE_PUBLIC (decl) = 1;
   determine_visibility (decl);
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
+  return type;
+}
+
+/* Wrapper for pushtag_1.  */
+
+tree
+pushtag (tree name, tree type, tag_scope scope)
+{
+  tree ret;
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  ret = pushtag_1 (name, type, scope);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+  return ret;
 }
 \f
 /* Subroutines for reverting temporarily to top-level for instantiation
@@ -5214,7 +5832,7 @@ store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings)
 {
   tree t;
 
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   for (t = names; t; t = TREE_CHAIN (t))
     {
       tree id;
@@ -5226,7 +5844,7 @@ store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings)
 
       store_binding (id, old_bindings);
     }
-  timevar_pop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* Like store_bindings, but NAMES is a vector of cp_class_binding
@@ -5239,23 +5857,23 @@ store_class_bindings (VEC(cp_class_binding,gc) *names,
   size_t i;
   cp_class_binding *cb;
 
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   for (i = 0; VEC_iterate(cp_class_binding, names, i, cb); ++i)
     store_binding (cb->identifier, old_bindings);
-  timevar_pop (TV_NAME_LOOKUP);
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 void
 push_to_top_level (void)
 {
   struct saved_scope *s;
-  struct cp_binding_level *b;
+  cp_binding_level *b;
   cxx_saved_binding *sb;
   size_t i;
   bool need_pop;
 
-  timevar_push (TV_NAME_LOOKUP);
-  s = GGC_CNEW (struct saved_scope);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  s = ggc_alloc_cleared_saved_scope ();
 
   b = scope_chain ? current_binding_level : 0;
 
@@ -5296,14 +5914,16 @@ push_to_top_level (void)
        SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
     }
 
-  for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, sb); ++i)
+  FOR_EACH_VEC_ELT (cxx_saved_binding, s->old_bindings, i, sb)
     IDENTIFIER_MARKED (sb->identifier) = 0;
 
   s->prev = scope_chain;
   s->bindings = b;
   s->need_pop_function_context = need_pop;
   s->function_decl = current_function_decl;
-  s->skip_evaluation = skip_evaluation;
+  s->unevaluated_operand = cp_unevaluated_operand;
+  s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+  s->x_stmt_tree.stmts_are_full_exprs_p = true;
 
   scope_chain = s;
   current_function_decl = NULL_TREE;
@@ -5311,18 +5931,18 @@ push_to_top_level (void)
   current_lang_name = lang_name_cplusplus;
   current_namespace = global_namespace;
   push_class_stack ();
-  skip_evaluation = 0;
-  timevar_pop (TV_NAME_LOOKUP);
+  cp_unevaluated_operand = 0;
+  c_inhibit_evaluation_warnings = 0;
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
-void
-pop_from_top_level (void)
+static void
+pop_from_top_level_1 (void)
 {
   struct saved_scope *s = scope_chain;
   cxx_saved_binding *saved;
   size_t i;
 
-  timevar_push (TV_NAME_LOOKUP);
   /* Clear out class-level bindings cache.  */
   if (previous_class_level)
     invalidate_class_lookup_cache ();
@@ -5331,7 +5951,7 @@ pop_from_top_level (void)
   current_lang_base = 0;
 
   scope_chain = s->prev;
-  for (i = 0; VEC_iterate (cxx_saved_binding, s->old_bindings, i, saved); ++i)
+  FOR_EACH_VEC_ELT (cxx_saved_binding, s->old_bindings, i, saved)
     {
       tree id = saved->identifier;
 
@@ -5344,10 +5964,21 @@ pop_from_top_level (void)
   if (s->need_pop_function_context)
     pop_function_context ();
   current_function_decl = s->function_decl;
-  skip_evaluation = s->skip_evaluation;
-  timevar_pop (TV_NAME_LOOKUP);
+  cp_unevaluated_operand = s->unevaluated_operand;
+  c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
 }
 
+/* Wrapper for pop_from_top_level_1.  */
+
+void
+pop_from_top_level (void)
+{
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  pop_from_top_level_1 ();
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
+}
+
+
 /* Pop off extraneous binding levels left over due to syntax errors.
 
    We don't pop past namespaces, as they might be valid.  */
@@ -5376,7 +6007,7 @@ void
 cp_emit_debug_info_for_using (tree t, tree context)
 {
   /* Don't try to emit any debug information if we have errors.  */
-  if (sorrycount || errorcount)
+  if (seen_error ())
     return;
 
   /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
@@ -5398,8 +6029,8 @@ cp_emit_debug_info_for_using (tree t, tree context)
   for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
     if (TREE_CODE (t) != TEMPLATE_DECL)
       {
-       if (building_stmt_tree ())
-         add_stmt (build_stmt (USING_STMT, t));
+       if (building_stmt_list_p ())
+         add_stmt (build_stmt (input_location, USING_STMT, t));
        else
          (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
       }