OSDN Git Service

PR c++/49663
[pf3gnuchains/gcc-fork.git] / gcc / cp / name-lookup.c
index e980cb6..06726da 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for C++ name lookup routines.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    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-core.h"
+#include "intl.h"
 #include "debug.h"
 #include "c-family/c-pragma.h"
+#include "params.h"
+#include "pointer-set.h"
 
 /* The bindings for a particular name in a particular scope.  */
 
@@ -318,33 +320,11 @@ new_class_binding (tree name, tree value, tree type, cxx_scope *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_EACH_VEC_ELT (cp_class_binding, scope->class_shadowed, i, cb)
-           {
-             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;
 }
 
@@ -433,12 +413,11 @@ 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))
     /* The new name is the type name.  */
     binding->type = decl;
@@ -458,7 +437,9 @@ supplement_binding (cxx_binding *binding, tree decl)
               && DECL_ANTICIPATED (bval)
               && !DECL_HIDDEN_FRIEND_P (bval)))
     binding->value = decl;
-  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
+  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
+          && (TREE_CODE (decl) != TYPE_DECL
+              || same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))))
     {
       /* The old binding was a type name.  It was placed in
         VALUE field because it was thought, at the point it was
@@ -525,7 +506,19 @@ supplement_binding (cxx_binding *binding, tree decl)
       ok = false;
     }
 
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
+  return ok;
+}
+
+/* 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.  */
@@ -549,7 +542,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
@@ -573,17 +565,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;
 
@@ -719,7 +709,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))
@@ -732,7 +722,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
            {
@@ -741,14 +731,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)
                {
@@ -762,7 +752,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;
                }
            }
        }
@@ -805,12 +795,15 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                                          x_exception_spec,
                                          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;
                    }
                }
              else
@@ -855,7 +848,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
        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
@@ -872,7 +865,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                     inlining.  */
                  && (!TYPE_NAME (type)
                      || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
-           cp_set_underlying_type (x);
+           set_underlying_type (x);
 
          if (type != error_mark_node
              && TYPE_NAME (type)
@@ -944,8 +937,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;
+         cxx_scope *oldscope = NULL;
+         cxx_binding *oldbinding = outer_binding (name, NULL, true);
+         if (oldbinding)
+           {
+             oldlocal = oldbinding->value;
+             oldscope = oldbinding->scope;
+           }
 
          if (need_new_binding)
            {
@@ -992,7 +992,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);
                }
            }
@@ -1022,11 +1022,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                        || (TREE_CODE (oldlocal) == TYPE_DECL
                            && (!DECL_ARTIFICIAL (oldlocal)
                                || TREE_CODE (x) == TYPE_DECL)))
-                  /* Don't check the `this' parameter or internally generated
-                      vars unless it's an implicit typedef (see
-                      create_implicit_typedef in decl.c).  */
-                  && (!DECL_ARTIFICIAL (oldlocal)
-                       || DECL_IMPLICIT_TYPEDEF_P (oldlocal))
                    /* Don't check for internally generated vars unless
                       it's an implicit typedef (see create_implicit_typedef
                       in decl.c).  */
@@ -1074,12 +1069,30 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                       }
                   }
                }
+             /* 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)
                {
                  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",
@@ -1142,7 +1155,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.  */
@@ -1421,6 +1446,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:
@@ -1551,9 +1577,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);
@@ -1634,6 +1660,22 @@ 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;
+  struct 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;
@@ -1737,26 +1779,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++.  */
 
@@ -1897,13 +1951,11 @@ make_lambda_name (void)
 static inline cxx_binding *
 find_binding (cxx_scope *scope, cxx_binding *binding)
 {
-  timevar_push (TV_NAME_LOOKUP);
-
   for (; binding != NULL; binding = binding->previous)
     if (binding->scope == 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.  */
@@ -1982,36 +2034,50 @@ lookup_extern_c_fun_binding_in_all_ns (tree function)
    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 = 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;
   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, cxx_scope *level, bool is_friend)
 {
   struct cp_binding_level *b;
   tree function_decl = current_function_decl;
 
-  timevar_push (TV_NAME_LOOKUP);
   current_function_decl = NULL_TREE;
   if (level->kind == sk_class)
     {
@@ -2028,8 +2094,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, cxx_scope *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
@@ -2053,14 +2132,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
@@ -2098,7 +2176,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()
@@ -2116,7 +2194,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;
        }
     }
 
@@ -2168,7 +2246,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.  */
@@ -2179,7 +2257,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
@@ -2391,7 +2481,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);
 
@@ -2626,7 +2716,7 @@ poplevel_class (void)
   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.  */
@@ -2641,7 +2731,10 @@ poplevel_class (void)
   if (level->class_shadowed)
     {
       FOR_EACH_VEC_ELT (cp_class_binding, level->class_shadowed, i, cb)
-       IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
+       {
+         IDENTIFIER_BINDING (cb->identifier) = cb->base->previous;
+         cxx_binding_free (cb->base);
+       }
       ggc_free (level->class_shadowed);
       level->class_shadowed = NULL;
     }
@@ -2650,7 +2743,7 @@ poplevel_class (void)
      `pushlevel_class' routine.  */
   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
@@ -2694,13 +2787,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));
@@ -2729,7 +2823,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
@@ -2796,21 +2891,20 @@ 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));
@@ -2825,7 +2919,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]
 
@@ -2859,7 +2953,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;
        }
     }
 
@@ -2910,11 +3004,11 @@ push_class_level_binding (tree name, tree x)
       else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
        old_decl = bval;
       else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+       return true;
       else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
        old_decl = bval;
       else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+       return true;
 
       if (old_decl && binding->scope == class_binding_level)
        {
@@ -2923,7 +3017,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;
        }
     }
 
@@ -2945,7 +3039,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
@@ -3063,8 +3169,9 @@ 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;
 
@@ -3079,14 +3186,23 @@ namespace_binding (tree name, tree scope)
   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);
@@ -3094,7 +3210,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
@@ -3239,7 +3364,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;
@@ -3260,7 +3384,6 @@ handle_namespace_attrs (tree ns, tree attributes)
          saw_vis = true;
        }
       else
-#endif
        {
          warning (OPT_Wattributes, "%qD attribute directive ignored",
                   name);
@@ -3282,7 +3405,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
@@ -3342,7 +3465,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.  */
@@ -3377,7 +3500,7 @@ 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)
     {
@@ -3386,7 +3509,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.  */
@@ -3411,13 +3534,26 @@ pop_decl_namespace (void)
    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.  */
@@ -3440,7 +3576,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);
 }
 
@@ -3453,7 +3589,7 @@ pushdecl_namespace_level (tree x, bool is_friend)
   struct 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
@@ -3487,23 +3623,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.  */
@@ -3513,7 +3647,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;
     }
 
@@ -3531,12 +3664,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.  */
@@ -3582,7 +3724,7 @@ do_using_directive (tree name_space)
 
   gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
 
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     add_stmt (build_stmt (input_location, USING_STMT, name_space));
   name_space = ORIGINAL_NAMESPACE (name_space);
 
@@ -3643,13 +3785,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)
     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.  */
@@ -3863,13 +4006,8 @@ qualify_lookup (tree val, int flags)
     return true;
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
     return false;
-  /* In unevaluated context, look past normal capture fields.  */
-  if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL
-      && DECL_NORMAL_CAPTURE_P (val))
-    return false;
-  /* None of the lookups that use qualify_lookup want the op() from the
-     lambda; they want the one from the enclosing class.  */
-  if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val))
+  /* Look through lambda things that we shouldn't be able to see.  */
+  if (is_lambda_ignored_entity (val))
     return false;
   return true;
 }
@@ -3919,11 +4057,73 @@ 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;
+      struct 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;
@@ -3931,8 +4131,6 @@ unqualified_namespace_lookup (tree name, int flags)
   struct 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;
@@ -3949,7 +4147,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.  */
@@ -3960,7 +4158,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);
        }
@@ -3969,7 +4167,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
@@ -4019,7 +4229,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))
@@ -4032,7 +4242,8 @@ lookup_using_namespace (tree name, struct scope_binding *val,
        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.  */
@@ -4065,14 +4276,14 @@ qualified_lookup_using_namespace (tree name, tree scope,
   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);
 
-  /* Algorithm: Starting with SCOPE, walk through the the set of used
+  /* 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.  */
+     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))
@@ -4124,12 +4335,18 @@ qualified_lookup_using_namespace (tree name, tree scope,
   VEC_free (tree,gc,todo_inline);
   VEC_free (tree,gc,seen);
   VEC_free (tree,gc,seen_inline);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
+  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,
@@ -4145,6 +4362,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))));
@@ -4244,14 +4463,13 @@ 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.  */
@@ -4275,10 +4493,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);
@@ -4373,7 +4591,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
@@ -4420,14 +4652,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);
@@ -4482,7 +4712,7 @@ lookup_type_scope (tree name, tag_scope scope)
       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)
@@ -4495,19 +4725,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;
   tree t = NULL_TREE;
 
-  timevar_push (TV_NAME_LOOKUP);
   b = innermost_nonclass_level ();
 
   if (b->kind == sk_namespace)
@@ -4528,7 +4770,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;
@@ -4537,9 +4779,22 @@ 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.  */
 
@@ -4575,7 +4830,7 @@ 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
@@ -4585,8 +4840,10 @@ lookup_type_current_level (tree name)
       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
@@ -4594,7 +4851,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] */
@@ -4607,6 +4865,7 @@ struct arg_lookup
   VEC(tree,gc) *namespaces;
   VEC(tree,gc) *classes;
   tree functions;
+  struct pointer_set_t *fn_set;
 };
 
 static bool arg_assoc (struct arg_lookup*, tree);
@@ -4626,22 +4885,21 @@ 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.  */
-
   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
-    k->functions = build_overload (fn, k->functions);
+    {
+      k->functions = build_overload (fn, k->functions);
+      if (TREE_CODE (k->functions) == OVERLOAD)
+       OVL_ARG_DEPENDENT (k->functions) = true;
+    }
 
   return false;
 }
@@ -4932,6 +5190,7 @@ 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))
@@ -4963,7 +5222,6 @@ arg_assoc_type (struct arg_lookup *k, tree type)
       return false;
     case LANG_TYPE:
       gcc_assert (type == unknown_type_node
-                 || NULLPTR_TYPE_P (type)
                  || type == init_list_type_node);
       return false;
     case TYPE_PACK_EXPANSION:
@@ -5051,8 +5309,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;
     }
 
@@ -5062,14 +5320,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, VEC(tree,gc) *args,
-                     bool include_std)
+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.  */
@@ -5087,6 +5343,23 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args,
      picking up later definitions) in the second stage. */
   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;
+
   if (include_std)
     arg_assoc_namespace (&k, std_node);
   arg_assoc_args_vec (&k, args);
@@ -5104,24 +5377,39 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args,
 
   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;
+  timevar_start (TV_NAME_LOOKUP);
+  ret = lookup_arg_dependent_1 (name, fns, args, include_std);
+  timevar_stop (TV_NAME_LOOKUP);
+  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;
@@ -5132,7 +5420,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
@@ -5225,13 +5525,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;
   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.  */
@@ -5256,7 +5555,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;
@@ -5302,12 +5601,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
@@ -5320,9 +5619,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)
@@ -5361,7 +5660,19 @@ pushtag (tree name, tree type, tag_scope scope)
   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
@@ -5399,7 +5710,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;
@@ -5411,7 +5722,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
@@ -5424,10 +5735,10 @@ 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
@@ -5439,7 +5750,7 @@ push_to_top_level (void)
   size_t i;
   bool need_pop;
 
-  timevar_push (TV_NAME_LOOKUP);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   s = ggc_alloc_cleared_saved_scope ();
 
   b = scope_chain ? current_binding_level : 0;
@@ -5499,17 +5810,16 @@ push_to_top_level (void)
   push_class_stack ();
   cp_unevaluated_operand = 0;
   c_inhibit_evaluation_warnings = 0;
-  timevar_pop (TV_NAME_LOOKUP);
+  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 ();
@@ -5533,9 +5843,19 @@ pop_from_top_level (void)
   current_function_decl = s->function_decl;
   cp_unevaluated_operand = s->unevaluated_operand;
   c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
-  timevar_pop (TV_NAME_LOOKUP);
 }
 
+/* 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.  */
@@ -5586,7 +5906,7 @@ 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 ())
+       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);