OSDN Git Service

* configure: Regenerate.
[pf3gnuchains/gcc-fork.git] / gcc / cp / name-lookup.c
index d196606..ded1d2e 100644 (file)
@@ -1,12 +1,13 @@
 /* Definitions for C++ name lookup routines.
-   Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +16,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -31,6 +31,7 @@ Boston, MA 02110-1301, USA.  */
 #include "toplev.h"
 #include "diagnostic.h"
 #include "debug.h"
+#include "c-pragma.h"
 
 /* The bindings for a particular name in a particular scope.  */
 
@@ -41,10 +42,8 @@ struct scope_binding {
 #define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
 
 static cxx_scope *innermost_nonclass_level (void);
-static tree select_decl (const struct scope_binding *, int);
 static cxx_binding *binding_for_name (cxx_scope *, tree);
-static tree lookup_name_innermost_nonclass_level (tree);
-static tree push_overloaded_decl (tree, int);
+static tree push_overloaded_decl (tree, int, bool);
 static bool lookup_using_namespace (tree, struct scope_binding *, tree,
                                    tree, int);
 static bool qualified_lookup_using_namespace (tree, tree,
@@ -60,6 +59,24 @@ tree global_namespace;
    unit.  */
 static GTY(()) tree anonymous_namespace_name;
 
+/* Initialize anonymous_namespace_name if necessary, and return it.  */
+
+static tree
+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");
+      else
+       /* 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;
+}
 
 /* Compute the chain index of a binding_entry given the HASH value of its
    name and the total COUNT of chains.  COUNT is assumed to be a power
@@ -399,7 +416,7 @@ pop_binding (tree id, tree decl)
     }
 }
 
-/* BINDING records an existing declaration for a namein the current scope.
+/* 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
    class name or enum-name can be bound at the same level as some other
@@ -437,10 +454,11 @@ supplement_binding (cxx_binding *binding, tree decl)
              error recovery purpose, pretend this was the intended
              declaration for that name.  */
           || bval == error_mark_node
-          /* If BVAL is a built-in that has not yet been declared,
+          /* 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_ANTICIPATED (bval)
+              && !DECL_HIDDEN_FRIEND_P (bval)))
     binding->value = decl;
   else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
     {
@@ -487,7 +505,7 @@ supplement_binding (cxx_binding *binding, tree decl)
           && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
           && !DECL_CLASS_SCOPE_P (decl))
     {
-      duplicate_decls (decl, binding->value);
+      duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
       ok = false;
     }
   else if (TREE_CODE (decl) == NAMESPACE_DECL
@@ -517,17 +535,16 @@ supplement_binding (cxx_binding *binding, tree decl)
 static void
 add_decl_to_level (tree decl, cxx_scope *b)
 {
+  /* We used to record virtual tables as if they were ordinary
+     variables, but no longer do so.  */
+  gcc_assert (!(TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)));
+
   if (TREE_CODE (decl) == NAMESPACE_DECL
       && !DECL_NAMESPACE_ALIAS (decl))
     {
       TREE_CHAIN (decl) = b->namespaces;
       b->namespaces = decl;
     }
-  else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
-    {
-      TREE_CHAIN (decl) = b->vtables;
-      b->vtables = decl;
-    }
   else
     {
       /* We build up the list in reverse order, and reverse it later if
@@ -551,14 +568,15 @@ add_decl_to_level (tree decl, cxx_scope *b)
 
 /* Record a decl-node X as belonging to the current lexical scope.
    Check for errors (such as an incompatible declaration for the same
-   name already seen in the same scope).
+   name already seen in the same scope).  IS_FRIEND is true if X is
+   declared as a friend.
 
    Returns either X or an old decl for the same name.
    If an old decl is returned, it may have been smashed
    to agree with what X says.  */
 
 tree
-pushdecl (tree x)
+pushdecl_maybe_friend (tree x, bool is_friend)
 {
   tree t;
   tree name;
@@ -566,6 +584,9 @@ pushdecl (tree x)
 
   timevar_push (TV_NAME_LOOKUP);
 
+  if (x == error_mark_node)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
   need_new_binding = 1;
 
   if (DECL_TEMPLATE_PARM_P (x))
@@ -664,14 +685,28 @@ pushdecl (tree x)
              if (decls_match (x, t))
                /* The standard only says that the local extern
                   inherits linkage from the previous decl; in
-                  particular, default args are not shared.  We must
-                  also tell cgraph to treat these decls as the same,
-                  or we may neglect to emit an "unused" static - we
-                  do this by making the DECL_UIDs equal, which should
-                  be viewed as a kludge.  FIXME.  */
+                  particular, default args are not shared.  Add
+                  the decl into a hash table to make sure only
+                  the previous decl in this case is seen by the
+                  middle end.  */
                {
+                 struct cxx_int_tree_map *h;
+                 void **loc;
+
                  TREE_PUBLIC (x) = TREE_PUBLIC (t);
-                 DECL_UID (x) = DECL_UID (t);
+
+                 if (cp_function_chain->extern_decl_map == NULL)
+                   cp_function_chain->extern_decl_map
+                     = htab_create_ggc (20, cxx_int_tree_map_hash,
+                                        cxx_int_tree_map_eq, NULL);
+
+                 h = GGC_NEW (struct cxx_int_tree_map);
+                 h->uid = DECL_UID (x);
+                 h->to = t;
+                 loc = htab_find_slot_with_hash
+                         (cp_function_chain->extern_decl_map, h,
+                          h->uid, INSERT);
+                 *(struct cxx_int_tree_map **) loc = h;
                }
            }
          else if (TREE_CODE (t) == PARM_DECL)
@@ -679,7 +714,7 @@ pushdecl (tree x)
              gcc_assert (DECL_CONTEXT (t));
 
              /* Check for duplicate params.  */
-             if (duplicate_decls (x, t))
+             if (duplicate_decls (x, t, is_friend))
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
          else if ((DECL_EXTERN_C_FUNCTION_P (x)
@@ -697,7 +732,7 @@ pushdecl (tree x)
            }
          else
            {
-             tree olddecl = duplicate_decls (x, t);
+             tree olddecl = duplicate_decls (x, t, is_friend);
 
              /* If the redeclaration failed, we can stop at this
                 point.  */
@@ -708,8 +743,6 @@ pushdecl (tree x)
                {
                  if (TREE_CODE (t) == TYPE_DECL)
                    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
-                 else if (TREE_CODE (t) == FUNCTION_DECL)
-                   check_default_args (t);
 
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
                }
@@ -730,9 +763,12 @@ pushdecl (tree x)
            }
        }
 
+      if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
+       check_default_args (x);
+
       check_template_shadow (x);
 
-      /* If this is a function conjured up by the backend, massage it
+      /* If this is a function conjured up by the back end, massage it
         so it looks friendly.  */
       if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
        {
@@ -742,7 +778,7 @@ pushdecl (tree x)
 
       if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
        {
-         t = push_overloaded_decl (x, PUSH_LOCAL);
+         t = push_overloaded_decl (x, PUSH_LOCAL, is_friend);
          if (t != x)
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
          if (!namespace_bindings_p ())
@@ -753,7 +789,7 @@ pushdecl (tree x)
        }
       else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
        {
-         t = push_overloaded_decl (x, PUSH_GLOBAL);
+         t = push_overloaded_decl (x, PUSH_GLOBAL, is_friend);
          if (t == x)
            add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
@@ -815,6 +851,16 @@ pushdecl (tree x)
            }
        }
 
+      if (TREE_CODE (x) == FUNCTION_DECL
+         && is_friend
+         && !flag_friend_injection)
+       {
+         /* This is a new declaration of a friend function, so hide
+            it from ordinary function lookup.  */
+         DECL_ANTICIPATED (x) = 1;
+         DECL_HIDDEN_FRIEND_P (x) = 1;
+       }
+
       /* This name is new in its binding level.
         Install the new declaration and return it.  */
       if (namespace_bindings_p ())
@@ -831,7 +877,6 @@ pushdecl (tree x)
                && t != NULL_TREE)
              && (TREE_CODE (x) == TYPE_DECL
                  || TREE_CODE (x) == VAR_DECL
-                 || TREE_CODE (x) == ALIAS_DECL
                  || TREE_CODE (x) == NAMESPACE_DECL
                  || TREE_CODE (x) == CONST_DECL
                  || TREE_CODE (x) == TEMPLATE_DECL))
@@ -924,8 +969,9 @@ pushdecl (tree x)
                     them there.  */
                  struct cp_binding_level *b = current_binding_level->level_chain;
 
-                 /* Skip the ctor/dtor cleanup level.  */
-                 b = b->level_chain;
+                 if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+                   /* Skip the ctor/dtor cleanup level.  */
+                   b = b->level_chain;
 
                  /* ARM $8.3 */
                  if (b->kind == sk_function_parms)
@@ -937,8 +983,8 @@ pushdecl (tree x)
 
              if (warn_shadow && !err)
                {
-                 warning (0, "declaration of %q#D shadows a parameter", x);
-                 warning (0, "%Jshadowed declaration is here", oldlocal);
+                 warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x);
+                 warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
                }
            }
 
@@ -962,29 +1008,26 @@ pushdecl (tree x)
              if (member && !TREE_STATIC (member))
                {
                  /* Location of previous decl is not useful in this case.  */
-                 warning (0, "declaration of %qD shadows a member of 'this'",
+                 warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'",
                           x);
                }
              else if (oldlocal != NULL_TREE
                       && TREE_CODE (oldlocal) == VAR_DECL)
                {
-                 warning (0, "declaration of %qD shadows a previous local", x);
-                 warning (0, "%Jshadowed declaration is here", oldlocal);
+                 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)
                /* XXX shadow warnings in outer-more namespaces */
                {
-                 warning (0, "declaration of %qD shadows a global declaration",
+                 warning (OPT_Wshadow, "declaration of %qD shadows a global declaration",
                           x);
-                 warning (0, "%Jshadowed declaration is here", oldglobal);
+                 warning (OPT_Wshadow, "%Jshadowed declaration is here", oldglobal);
                }
            }
        }
 
-      if (TREE_CODE (x) == FUNCTION_DECL)
-       check_default_args (x);
-
       if (TREE_CODE (x) == VAR_DECL)
        maybe_register_incomplete_var (x);
     }
@@ -998,6 +1041,14 @@ pushdecl (tree x)
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
 
+/* Record a decl-node X as belonging to the current lexical scope.  */
+
+tree
+pushdecl (tree x)
+{
+  return pushdecl_maybe_friend (x, false);
+}
+
 /* Enter DECL into the symbol table, if that's appropriate.  Returns
    DECL, or a modified version thereof.  */
 
@@ -1081,11 +1132,11 @@ check_for_out_of_scope_variable (tree decl)
   if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
     return decl;
 
-  shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (decl) 
+  shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (decl)
     ? DECL_SHADOWED_FOR_VAR (decl) : NULL_TREE ;
   while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
         && DECL_DEAD_FOR_LOCAL (shadowed))
-    shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed) 
+    shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
       ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
   if (!shadowed)
     shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
@@ -1235,11 +1286,11 @@ begin_scope (scope_kind kind, tree entity)
   if (!ENABLE_SCOPE_CHECKING && free_binding_level)
     {
       scope = free_binding_level;
+      memset (scope, 0, sizeof (cxx_scope));
       free_binding_level = scope->level_chain;
     }
   else
-    scope = GGC_NEW (cxx_scope);
-  memset (scope, 0, sizeof (cxx_scope));
+    scope = GGC_CNEW (cxx_scope);
 
   scope->this_entity = entity;
   scope->more_cleanups_ok = true;
@@ -1260,6 +1311,7 @@ begin_scope (scope_kind kind, tree entity)
     case sk_for:
     case sk_class:
     case sk_function_parms:
+    case sk_omp:
       scope->keep = keep_next_level_flag;
       break;
 
@@ -1315,7 +1367,7 @@ leave_scope (void)
   current_binding_level = scope->level_chain;
 
   /* Namespace-scopes are left most probably temporarily, not
-     completely; they can be reopen later, e.g. in namespace-extension
+     completely; they can be reopened later, e.g. in namespace-extension
      or any name binding activity that requires us to resume a
      namespace.  For classes, we cache some binding levels.  For other
      scopes, we just make the structure available for reuse.  */
@@ -1484,7 +1536,7 @@ print_binding_level (struct cp_binding_level* lvl)
 {
   tree t;
   int i = 0, len;
-  fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
+  fprintf (stderr, " blocks=%p", (void *) lvl->blocks);
   if (lvl->more_cleanups_ok)
     fprintf (stderr, " more-cleanups-ok");
   if (lvl->have_cleanups)
@@ -1549,7 +1601,7 @@ print_other_binding_stack (struct cp_binding_level *stack)
   struct cp_binding_level *level;
   for (level = stack; !global_scope_p (level); level = level->level_chain)
     {
-      fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level);
+      fprintf (stderr, "binding level %p\n", (void *) level);
       print_binding_level (level);
     }
 }
@@ -1558,9 +1610,9 @@ void
 print_binding_stack (void)
 {
   struct cp_binding_level *b;
-  fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF
-          "\nclass_binding_level=" HOST_PTR_PRINTF
-          "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n",
+  fprintf (stderr, "current_binding_level=%p\n"
+          "class_binding_level=%p\n"
+          "NAMESPACE_LEVEL (global_namespace)=%p\n",
           (void *) current_binding_level, (void *) class_binding_level,
           (void *) NAMESPACE_LEVEL (global_namespace));
   if (class_binding_level)
@@ -1677,13 +1729,16 @@ constructor_name (tree type)
   return name;
 }
 
-/* Returns TRUE if NAME is the name for the constructor for TYPE.  */
+/* Returns TRUE if NAME is the name for the constructor for TYPE,
+   which must be a class type.  */
 
 bool
 constructor_name_p (tree name, tree type)
 {
   tree ctor_name;
 
+  gcc_assert (IS_AGGR_TYPE (type));
+
   if (!name)
     return false;
 
@@ -1771,7 +1826,7 @@ binding_for_name (cxx_scope *scope, tree name)
    return NULL_TREE if this not in namespace scope (in namespace
    scope, a using decl might extend any previous bindings).  */
 
-tree
+static tree
 push_using_decl (tree scope, tree name)
 {
   tree decl;
@@ -1796,7 +1851,7 @@ push_using_decl (tree scope, tree name)
    caller to set DECL_CONTEXT properly.  */
 
 tree
-pushdecl_with_scope (tree x, cxx_scope *level)
+pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend)
 {
   struct cp_binding_level *b;
   tree function_decl = current_function_decl;
@@ -1814,7 +1869,7 @@ pushdecl_with_scope (tree x, cxx_scope *level)
     {
       b = current_binding_level;
       current_binding_level = level;
-      x = pushdecl (x);
+      x = pushdecl_maybe_friend (x, is_friend);
       current_binding_level = b;
     }
   current_function_decl = function_decl;
@@ -1836,12 +1891,14 @@ pushdecl_with_scope (tree x, cxx_scope *level)
      PUSH_USING: DECL is being pushed as the result of a using
                 declaration.
 
+   IS_FRIEND is true if this is a friend declaration.
+
    The value returned may be a previous declaration if we guessed wrong
    about what language DECL should belong to (C or C++).  Otherwise,
    it's always DECL (and never something that's not a _DECL).  */
 
 static tree
-push_overloaded_decl (tree decl, int flags)
+push_overloaded_decl (tree decl, int flags, bool is_friend)
 {
   tree name = DECL_NAME (decl);
   tree old;
@@ -1872,6 +1929,7 @@ push_overloaded_decl (tree decl, int flags)
          for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
            {
              tree fn = OVL_CURRENT (tmp);
+             tree dup;
 
              if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
                  && !(flags & PUSH_USING)
@@ -1881,15 +1939,19 @@ push_overloaded_decl (tree decl, int flags)
                error ("%q#D conflicts with previous using declaration %q#D",
                       decl, fn);
 
-             if (duplicate_decls (decl, fn) == fn)
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
+             dup = duplicate_decls (decl, fn, 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);
            }
 
          /* We don't overload implicit built-ins.  duplicate_decls()
             may fail to merge the decls if the new decl is e.g. a
             template function.  */
          if (TREE_CODE (old) == FUNCTION_DECL
-             && DECL_ANTICIPATED (old))
+             && DECL_ANTICIPATED (old)
+             && !DECL_HIDDEN_FRIEND_P (old))
            old = NULL;
        }
       else if (old == error_mark_node)
@@ -2033,102 +2095,133 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
       return;
     }
 
+  /* Shift the old and new bindings around so we're comparing class and
+     enumeration names to each other.  */
+  if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
+    {
+      oldtype = oldval;
+      oldval = NULL_TREE;
+    }
+
+  if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
+    {
+      decls.type = decls.value;
+      decls.value = NULL_TREE;
+    }
+
   /* It is impossible to overload a built-in function; any explicit
      declaration eliminates the built-in declaration.  So, if OLDVAL
      is a built-in, then we can just pretend it isn't there.  */
   if (oldval
       && TREE_CODE (oldval) == FUNCTION_DECL
-      && DECL_ANTICIPATED (oldval))
+      && DECL_ANTICIPATED (oldval)
+      && !DECL_HIDDEN_FRIEND_P (oldval))
     oldval = NULL_TREE;
 
-  /* Check for using functions.  */
-  if (decls.value && is_overloaded_fn (decls.value))
+  if (decls.value)
     {
-      tree tmp, tmp1;
-
-      if (oldval && !is_overloaded_fn (oldval))
-       {
-         if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
-           error ("%qD is already declared in this scope", name);
-         oldval = NULL_TREE;
-       }
-
-      *newval = oldval;
-      for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
+      /* Check for using functions.  */
+      if (is_overloaded_fn (decls.value))
        {
-         tree new_fn = OVL_CURRENT (tmp);
+         tree tmp, tmp1;
 
-         /* [namespace.udecl]
+         if (oldval && !is_overloaded_fn (oldval))
+           {
+             error ("%qD is already declared in this scope", name);
+             oldval = NULL_TREE;
+           }
 
-            If a function declaration in namespace scope or block
-            scope has the same name and the same parameter types as a
-            function introduced by a using declaration the program is
-            ill-formed.  */
-         for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+         *newval = oldval;
+         for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
            {
-             tree old_fn = OVL_CURRENT (tmp1);
-
-             if (new_fn == old_fn)
-               /* The function already exists in the current namespace.  */
-               break;
-             else if (OVL_USED (tmp1))
-               continue; /* this is a using decl */
-             else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
-                                 TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+             tree new_fn = OVL_CURRENT (tmp);
+
+             /* [namespace.udecl]
+
+                If a function declaration in namespace scope or block
+                scope has the same name and the same parameter types as a
+                function introduced by a using declaration the program is
+                ill-formed.  */
+             for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
                {
-                 gcc_assert (!DECL_ANTICIPATED (old_fn));
+                 tree old_fn = OVL_CURRENT (tmp1);
 
-                 /* There was already a non-using declaration in
-                    this scope with the same parameter types. If both
-                    are the same extern "C" functions, that's ok.  */
-                 if (decls_match (new_fn, old_fn))
+                 if (new_fn == old_fn)
+                   /* The function already exists in the current namespace.  */
                    break;
-                 else
+                 else if (OVL_USED (tmp1))
+                   continue; /* this is a using decl */
+                 else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+                                     TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
                    {
-                     error ("%qD is already declared in this scope", name);
-                     break;
+                     gcc_assert (!DECL_ANTICIPATED (old_fn)
+                                 || DECL_HIDDEN_FRIEND_P (old_fn));
+
+                     /* There was already a non-using declaration in
+                        this scope with the same parameter types. If both
+                        are the same extern "C" functions, that's ok.  */
+                     if (decls_match (new_fn, old_fn))
+                       break;
+                     else
+                       {
+                         error ("%qD is already declared in this scope", name);
+                         break;
+                       }
                    }
                }
-           }
-
-         /* If we broke out of the loop, there's no reason to add
-            this function to the using declarations for this
-            scope.  */
-         if (tmp1)
-           continue;
 
-         /* If we are adding to an existing OVERLOAD, then we no
-            longer know the type of the set of functions.  */
-         if (*newval && TREE_CODE (*newval) == OVERLOAD)
-           TREE_TYPE (*newval) = unknown_type_node;
-         /* Add this new function to the set.  */
-         *newval = build_overload (OVL_CURRENT (tmp), *newval);
-         /* If there is only one function, then we use its type.  (A
-            using-declaration naming a single function can be used in
-            contexts where overload resolution cannot be
-            performed.)  */
-         if (TREE_CODE (*newval) != OVERLOAD)
-           {
-             *newval = ovl_cons (*newval, NULL_TREE);
-             TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+             /* If we broke out of the loop, there's no reason to add
+                this function to the using declarations for this
+                scope.  */
+             if (tmp1)
+               continue;
+
+             /* If we are adding to an existing OVERLOAD, then we no
+                longer know the type of the set of functions.  */
+             if (*newval && TREE_CODE (*newval) == OVERLOAD)
+               TREE_TYPE (*newval) = unknown_type_node;
+             /* Add this new function to the set.  */
+             *newval = build_overload (OVL_CURRENT (tmp), *newval);
+             /* If there is only one function, then we use its type.  (A
+                using-declaration naming a single function can be used in
+                contexts where overload resolution cannot be
+                performed.)  */
+             if (TREE_CODE (*newval) != OVERLOAD)
+               {
+                 *newval = ovl_cons (*newval, NULL_TREE);
+                 TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+               }
+             OVL_USED (*newval) = 1;
            }
-         OVL_USED (*newval) = 1;
+       }
+      else
+       {
+         *newval = decls.value;
+         if (oldval && !decls_match (*newval, oldval))
+           error ("%qD is already declared in this scope", name);
        }
     }
   else
+    *newval = oldval;
+
+  if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
     {
-      *newval = decls.value;
-      if (oldval && !decls_match (*newval, oldval))
-       error ("%qD is already declared in this scope", name);
+      error ("reference to %qD is ambiguous", name);
+      print_candidates (decls.type);
     }
-
-  *newtype = decls.type;
-  if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
+  else
     {
-      error ("using declaration %qD introduced ambiguous type %qT",
-            name, oldtype);
-      return;
+      *newtype = decls.type;
+      if (oldtype && *newtype && !decls_match (oldtype, *newtype))
+       error ("%qD is already declared in this scope", name);
     }
+
+    /* If *newval is empty, shift any class or enumeration name down.  */
+    if (!*newval)
+      {
+       *newval = *newtype;
+       *newtype = NULL_TREE;
+      }
 }
 
 /* Process a using-declaration at function scope.  */
@@ -2169,7 +2262,8 @@ do_local_using_decl (tree decl, tree scope, tree name)
          for (fn = newval; fn && OVL_CURRENT (fn) != term;
               fn = OVL_NEXT (fn))
            push_overloaded_decl (OVL_CURRENT (fn),
-                                 PUSH_LOCAL | PUSH_USING);
+                                 PUSH_LOCAL | PUSH_USING,
+                                 false);
        }
       else
        push_local_binding (name, newval, PUSH_USING);
@@ -2560,6 +2654,9 @@ push_class_level_binding (tree name, tree x)
   if (!class_binding_level)
     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
 
+  if (name == error_mark_node)
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+
   /* Check for invalid member names.  */
   gcc_assert (TYPE_BEING_DEFINED (current_class_type));
   /* We could have been passed a tree list if this is an ambiguous
@@ -2643,7 +2740,13 @@ push_class_level_binding (tree name, tree x)
              INHERITED_VALUE_BINDING_P (binding) = 0;
            }
          else
-           old_decl = bval;
+           {
+             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))
+               binding->type = NULL_TREE;
+           }
        }
       else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
        old_decl = bval;
@@ -2692,9 +2795,24 @@ push_class_level_binding (tree name, tree x)
 tree
 do_class_using_decl (tree scope, tree name)
 {
-  tree value, decl, binfo;
-  base_kind b_kind;
-  bool dependent_p;
+  /* The USING_DECL returned by this function.  */
+  tree value;
+  /* The declaration (or declarations) name by this using
+     declaration.  NULL if we are in a template and cannot figure out
+     what has been named.  */
+  tree decl;
+  /* True if SCOPE is a dependent type.  */
+  bool scope_dependent_p;
+  /* True if SCOPE::NAME is dependent.  */
+  bool name_dependent_p;
+  /* True if any of the bases of CURRENT_CLASS_TYPE are dependent.  */
+  bool bases_dependent_p;
+  tree binfo;
+  tree base_binfo;
+  int i;
+
+  if (name == error_mark_node)
+    return NULL_TREE;
 
   if (!scope || !TYPE_P (scope))
     {
@@ -2702,32 +2820,13 @@ do_class_using_decl (tree scope, tree name)
       return NULL_TREE;
     }
 
-  /* Make sure the scope is a base.  */
-  dependent_p = dependent_type_p (scope);
-  if (!dependent_p)
-    binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
-  else
-    {
-      binfo = NULL;
-      if (same_type_p (current_class_type, scope))
-       b_kind = bk_same_type;
-      else
-       b_kind = bk_proper_base;
-    }
-
-  if (b_kind < bk_proper_base)
-    {
-      error_not_base_type (scope, current_class_type);
-      return NULL_TREE;
-    }
-
   /* Make sure the name is not invalid */
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
       error ("%<%T::%D%> names destructor", scope, name);
       return NULL_TREE;
     }
-  if (constructor_name_p (name, scope))
+  if (IS_AGGR_TYPE (scope) && constructor_name_p (name, scope))
     {
       error ("%<%T::%D%> names constructor", scope, name);
       return NULL_TREE;
@@ -2739,32 +2838,65 @@ do_class_using_decl (tree scope, tree name)
       return NULL_TREE;
     }
 
-  if (!dependent_p
-      && IDENTIFIER_OPNAME_P (name) && dependent_type_p (TREE_TYPE (name)))
-    dependent_p = 1;
+  scope_dependent_p = dependent_type_p (scope);
+  name_dependent_p = (scope_dependent_p
+                     || (IDENTIFIER_TYPENAME_P (name)
+                         && dependent_type_p (TREE_TYPE (name))));
+
+  bases_dependent_p = false;
+  if (processing_template_decl)
+    for (binfo = TYPE_BINFO (current_class_type), i = 0;
+        BINFO_BASE_ITERATE (binfo, i, base_binfo);
+        i++)
+      if (dependent_type_p (TREE_TYPE (base_binfo)))
+       {
+         bases_dependent_p = true;
+         break;
+       }
 
-  /* See if there are any members of the base. */
-  if (!dependent_p)
-    {
-      decl = lookup_member (binfo, name, 0, false);
+  decl = NULL_TREE;
+
+  /* From [namespace.udecl]:
+
+       A using-declaration used as a member-declaration shall refer to a
+       member of a base class of the class being defined.
 
-      if (!decl)
+     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.  */
+  if (!scope_dependent_p)
+    {
+      base_kind b_kind;
+      binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
+      if (b_kind < bk_proper_base)
        {
-         error ("no members matching %<%T::%D%> in %q#T", scope, name, scope);
-         return NULL_TREE;
+         if (!bases_dependent_p)
+           {
+             error_not_base_type (scope, current_class_type);
+             return NULL_TREE;
+           }
+       }
+      else if (!name_dependent_p)
+       {
+         decl = lookup_member (binfo, name, 0, false);
+         if (!decl)
+           {
+             error ("no members matching %<%T::%D%> in %q#T", scope, name,
+                    scope);
+             return NULL_TREE;
+           }
+         /* The binfo from which the functions came does not matter.  */
+         if (BASELINK_P (decl))
+           decl = BASELINK_FUNCTIONS (decl);
        }
-
-      if (BASELINK_P (decl))
-       /* Ignore base type this came from.  */
-       decl = BASELINK_FUNCTIONS (decl);
    }
-  else
-    decl = NULL_TREE;
 
   value = build_lang_decl (USING_DECL, name, NULL_TREE);
   USING_DECL_DECLS (value) = decl;
   USING_DECL_SCOPE (value) = scope;
-  DECL_DEPENDENT_P (value) = dependent_p;
+  DECL_DEPENDENT_P (value) = !decl;
 
   return value;
 }
@@ -2812,7 +2944,7 @@ set_namespace_binding (tree name, tree scope, tree val)
 void
 set_decl_namespace (tree decl, tree scope, bool friendp)
 {
-  tree old;
+  tree old, fn;
 
   /* Get rid of namespace aliases.  */
   scope = ORIGINAL_NAMESPACE (scope);
@@ -2833,13 +2965,10 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
     }
 
   /* See whether this has been declared in the namespace.  */
-  old = namespace_binding (DECL_NAME (decl), scope);
-  if (!old)
+  old = lookup_qualified_name (scope, DECL_NAME (decl), false, true);
+  if (old == error_mark_node)
     /* No old declaration at all.  */
     goto complain;
-  /* A template can be explicitly specialized in any namespace.  */
-  if (processing_explicit_instantiation)
-    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
@@ -2848,12 +2977,22 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
   /* 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;
   if (processing_template_decl || processing_specialization)
     /* We have not yet called push_template_decl to turn a
        FUNCTION_DECL into a TEMPLATE_DECL, so the declarations won't
        match.  But, we'll check later, when we construct the
        template.  */
     return;
+  /* Instantiations or specializations of templates may be declared as
+     friends in any namespace.  */
+  if (friendp && DECL_USE_TEMPLATE (decl))
+    return;
   if (is_overloaded_fn (old))
     {
       for (; old; old = OVL_NEXT (old))
@@ -2885,6 +3024,54 @@ current_decl_namespace (void)
   return result;
 }
 
+/* Process any ATTRIBUTES on a namespace definition.  Currently only
+   attribute visibility is meaningful, which is a property of the syntactic
+   block rather than the namespace as a whole, so we don't touch the
+   NAMESPACE_DECL at all.  Returns true if attribute visibility is seen.  */
+
+bool
+handle_namespace_attrs (tree ns, tree attributes)
+{
+  tree d;
+  bool saw_vis = false;
+
+  for (d = attributes; d; d = TREE_CHAIN (d))
+    {
+      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;
+         if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
+           {
+             warning (OPT_Wattributes,
+                      "%qD attribute requires a single NTBS argument",
+                      name);
+             continue;
+           }
+
+         if (!TREE_PUBLIC (ns))
+           warning (OPT_Wattributes,
+                    "%qD attribute is meaningless since members of the "
+                    "anonymous namespace get local symbols", name);
+
+         push_visibility (TREE_STRING_POINTER (x));
+         saw_vis = true;
+       }
+      else
+#endif
+       {
+         warning (OPT_Wattributes, "%qD attribute directive ignored",
+                  name);
+         continue;
+       }
+    }
+
+  return saw_vis;
+}
+  
 /* Push into the scope of the NAME namespace.  If NAME is NULL_TREE, then we
    select a name that is unique to this compilation unit.  */
 
@@ -2905,11 +3092,7 @@ push_namespace (tree name)
 
   if (anon)
     {
-      /* The name of anonymous namespace is unique for the translation
-        unit.  */
-      if (!anonymous_namespace_name)
-       anonymous_namespace_name = get_file_function_name ('N');
-      name = anonymous_namespace_name;
+      name = get_anonymous_namespace_name();
       d = IDENTIFIER_NAMESPACE_VALUE (name);
       if (d)
        /* Reopening anonymous namespace.  */
@@ -2937,6 +3120,12 @@ push_namespace (tree name)
       /* Make a new namespace, binding the name to it.  */
       d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
       DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
+      /* The name of this namespace is not visible to other translation
+        units if it is an anonymous namespace or member thereof.  */
+      if (anon || decl_anon_ns_mem_p (current_namespace))
+       TREE_PUBLIC (d) = 0;
+      else
+       TREE_PUBLIC (d) = 1;
       pushdecl (d);
       if (anon)
        {
@@ -3037,12 +3226,10 @@ namespace_ancestor (tree ns1, tree ns2)
 void
 do_namespace_alias (tree alias, tree namespace)
 {
-  if (TREE_CODE (namespace) != NAMESPACE_DECL)
-    {
-      /* The parser did not find it, so it's not there.  */
-      error ("unknown namespace %qD", namespace);
-      return;
-    }
+  if (namespace == error_mark_node)
+    return;
+
+  gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
 
   namespace = ORIGINAL_NAMESPACE (namespace);
 
@@ -3061,13 +3248,13 @@ do_namespace_alias (tree alias, tree namespace)
    if appropriate.  */
 
 tree
-pushdecl_namespace_level (tree x)
+pushdecl_namespace_level (tree x, bool is_friend)
 {
   struct cp_binding_level *b = current_binding_level;
   tree t;
 
   timevar_push (TV_NAME_LOOKUP);
-  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
+  t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend);
 
   /* Now, the type_shadowed stack may screw us.  Munge it so it does
      what we want.  */
@@ -3181,7 +3368,6 @@ do_toplevel_using_decl (tree decl, tree scope, tree name)
     binding->value = newval;
   if (newtype)
     binding->type = newtype;
-  return;
 }
 
 /* Process a using-directive.  */
@@ -3191,26 +3377,15 @@ do_using_directive (tree namespace)
 {
   tree context = NULL_TREE;
 
+  if (namespace == error_mark_node)
+    return;
+
+  gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
+
   if (building_stmt_tree ())
     add_stmt (build_stmt (USING_STMT, namespace));
-
-  /* using namespace A::B::C; */
-  if (TREE_CODE (namespace) == SCOPE_REF)
-      namespace = TREE_OPERAND (namespace, 1);
-  if (TREE_CODE (namespace) == IDENTIFIER_NODE)
-    {
-      /* Lookup in lexer did not find a namespace.  */
-      if (!processing_template_decl)
-       error ("namespace %qT undeclared", namespace);
-      return;
-    }
-  if (TREE_CODE (namespace) != NAMESPACE_DECL)
-    {
-      if (!processing_template_decl)
-       error ("%qT is not a namespace", namespace);
-      return;
-    }
   namespace = ORIGINAL_NAMESPACE (namespace);
+
   if (!toplevel_bindings_p ())
     {
       push_using_directive (namespace);
@@ -3247,9 +3422,14 @@ parse_using_directive (tree namespace, tree attribs)
          if (!toplevel_bindings_p ())
            error ("strong using only meaningful at namespace scope");
          else if (namespace != error_mark_node)
-           DECL_NAMESPACE_ASSOCIATIONS (namespace)
-             = tree_cons (current_namespace, 0,
-                          DECL_NAMESPACE_ASSOCIATIONS (namespace));
+           {
+             if (!is_ancestor (current_namespace, namespace))
+               error ("current namespace %qD does not enclose strongly used namespace %qD",
+                      current_namespace, namespace);
+             DECL_NAMESPACE_ASSOCIATIONS (namespace)
+               = tree_cons (current_namespace, 0,
+                            DECL_NAMESPACE_ASSOCIATIONS (namespace));
+           }
        }
       else
        warning (OPT_Wattributes, "%qD attribute directive ignored", name);
@@ -3261,13 +3441,13 @@ parse_using_directive (tree namespace, tree attribs)
    *INIT, if INIT is non-NULL.  */
 
 static tree
-pushdecl_top_level_1 (tree x, tree *init)
+pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
 {
   timevar_push (TV_NAME_LOOKUP);
   push_to_top_level ();
-  x = pushdecl_namespace_level (x);
+  x = pushdecl_namespace_level (x, is_friend);
   if (init)
-    cp_finish_decl (x, *init, NULL_TREE, 0);
+    finish_decl (x, *init, NULL_TREE);
   pop_from_top_level ();
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
@@ -3277,7 +3457,15 @@ pushdecl_top_level_1 (tree x, tree *init)
 tree
 pushdecl_top_level (tree x)
 {
-  return pushdecl_top_level_1 (x, NULL);
+  return pushdecl_top_level_1 (x, NULL, false);
+}
+
+/* Like pushdecl_top_level, but adding the IS_FRIEND parameter.  */
+
+tree
+pushdecl_top_level_maybe_friend (tree x, bool is_friend)
+{
+  return pushdecl_top_level_1 (x, NULL, is_friend);
 }
 
 /* Like pushdecl, only it places X in the global scope if
@@ -3287,7 +3475,7 @@ pushdecl_top_level (tree x)
 tree
 pushdecl_top_level_and_finish (tree x, tree init)
 {
-  return pushdecl_top_level_1 (x, &init);
+  return pushdecl_top_level_1 (x, &init, false);
 }
 
 /* Combines two sets of overloaded functions into an OVERLOAD chain, removing
@@ -3335,41 +3523,59 @@ merge_functions (tree s1, tree s2)
    XXX I don't want to repeat the entire duplicate_decls here */
 
 static void
-ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
-               int flags)
+ambiguous_decl (struct scope_binding *old, cxx_binding *new, int flags)
 {
   tree val, type;
   gcc_assert (old != NULL);
+
+  /* Copy the type.  */
+  type = new->type;
+  if (LOOKUP_NAMESPACES_ONLY (flags)
+      || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
+    type = NULL_TREE;
+
   /* Copy the value.  */
   val = new->value;
   if (val)
-    switch (TREE_CODE (val))
-      {
-      case TEMPLATE_DECL:
-       /* If we expect types or namespaces, and not templates,
-          or this is not a template class.  */
-       if ((LOOKUP_QUALIFIERS_ONLY (flags)
-            && !DECL_CLASS_TEMPLATE_P (val))
-           || hidden_name_p (val))
-         val = NULL_TREE;
-       break;
-      case TYPE_DECL:
-       if (LOOKUP_NAMESPACES_ONLY (flags) || hidden_name_p (val))
-         val = NULL_TREE;
-       break;
-      case NAMESPACE_DECL:
-       if (LOOKUP_TYPES_ONLY (flags))
-         val = NULL_TREE;
-       break;
-      case FUNCTION_DECL:
-       /* Ignore built-in functions that are still anticipated.  */
-       if (LOOKUP_QUALIFIERS_ONLY (flags) || hidden_name_p (val))
-         val = NULL_TREE;
-       break;
-      default:
-       if (LOOKUP_QUALIFIERS_ONLY (flags))
-         val = NULL_TREE;
-      }
+    {
+      if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
+       val = NULL_TREE;
+      else
+       switch (TREE_CODE (val))
+         {
+         case TEMPLATE_DECL:
+           /* If we expect types or namespaces, and not templates,
+              or this is not a template class.  */
+           if ((LOOKUP_QUALIFIERS_ONLY (flags)
+                && !DECL_CLASS_TEMPLATE_P (val)))
+             val = NULL_TREE;
+           break;
+         case TYPE_DECL:
+           if (LOOKUP_NAMESPACES_ONLY (flags)
+               || (type && (flags & LOOKUP_PREFER_TYPES)))
+             val = NULL_TREE;
+           break;
+         case NAMESPACE_DECL:
+           if (LOOKUP_TYPES_ONLY (flags))
+             val = NULL_TREE;
+           break;
+         case FUNCTION_DECL:
+           /* Ignore built-in functions that are still anticipated.  */
+           if (LOOKUP_QUALIFIERS_ONLY (flags))
+             val = NULL_TREE;
+           break;
+         default:
+           if (LOOKUP_QUALIFIERS_ONLY (flags))
+             val = NULL_TREE;
+         }
+    }
+
+  /* If val is hidden, shift down any class or enumeration name.  */
+  if (!val)
+    {
+      val = type;
+      type = NULL_TREE;
+    }
 
   if (!old->value)
     old->value = val;
@@ -3379,36 +3585,19 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
        old->value = merge_functions (old->value, val);
       else
        {
-         /* Some declarations are functions, some are not.  */
-         if (flags & LOOKUP_COMPLAIN)
-           {
-             /* If we've already given this error for this lookup,
-                old->value is error_mark_node, so let's not
-                repeat ourselves.  */
-             if (old->value != error_mark_node)
-               {
-                 error ("use of %qD is ambiguous", name);
-                 error ("  first declared as %q+#D here", old->value);
-               }
-             error ("  also declared as %q+#D here", val);
-           }
-         old->value = error_mark_node;
+         old->value = tree_cons (NULL_TREE, old->value,
+                                 build_tree_list (NULL_TREE, val));
+         TREE_TYPE (old->value) = error_mark_node;
        }
     }
-  /* ... and copy the type.  */
-  type = new->type;
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    type = NULL_TREE;
+
   if (!old->type)
     old->type = type;
   else if (type && old->type != type)
     {
-      if (flags & LOOKUP_COMPLAIN)
-       {
-         error ("%qD denotes an ambiguous type",name);
-         error ("%J  first type here", TYPE_MAIN_DECL (old->type));
-         error ("%J  other type here", TYPE_MAIN_DECL (type));
-       }
+      old->type = tree_cons (NULL_TREE, old->type,
+                            build_tree_list (NULL_TREE, type));
+      TREE_TYPE (old->type) = error_mark_node;
     }
 }
 
@@ -3454,7 +3643,7 @@ qualify_lookup (tree val, int flags)
 }
 
 /* Given a lookup that returned VAL, decide if we want to ignore it or
-   not based on DECL_ANTICIPATED_P.  */
+   not based on DECL_ANTICIPATED.  */
 
 bool
 hidden_name_p (tree val)
@@ -3466,111 +3655,36 @@ hidden_name_p (tree val)
   return false;
 }
 
-/* Look up NAME in the NAMESPACE.  */
+/* Remove any hidden friend functions from a possibly overloaded set
+   of functions.  */
 
 tree
-lookup_namespace_name (tree namespace, tree name)
+remove_hidden_names (tree fns)
 {
-  tree val;
-  tree template_id = NULL_TREE;
-  struct scope_binding binding = EMPTY_SCOPE_BINDING;
-
-  timevar_push (TV_NAME_LOOKUP);
-  gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
-
-  if (TREE_CODE (name) == NAMESPACE_DECL)
-    /* This happens for A::B<int> when B is a namespace.  */
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
-  else if (TREE_CODE (name) == TEMPLATE_DECL)
-    {
-      /* This happens for A::B where B is a template, and there are no
-        template arguments.  */
-      error ("invalid use of %qD", name);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-    }
-
-  namespace = ORIGINAL_NAMESPACE (namespace);
+  if (!fns)
+    return fns;
 
-  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+  if (TREE_CODE (fns) == FUNCTION_DECL && hidden_name_p (fns))
+    fns = NULL_TREE;
+  else if (TREE_CODE (fns) == OVERLOAD)
     {
-      template_id = name;
-      name = TREE_OPERAND (name, 0);
-      if (TREE_CODE (name) == OVERLOAD)
-       name = DECL_NAME (OVL_CURRENT (name));
-      else if (DECL_P (name))
-       name = DECL_NAME (name);
-    }
-
-  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
-
-  if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+      tree o;
 
-  if (binding.value)
-    {
-      val = binding.value;
-
-      if (template_id)
+      for (o = fns; o; o = OVL_NEXT (o))
+       if (hidden_name_p (OVL_CURRENT (o)))
+         break;
+      if (o)
        {
-         if (DECL_CLASS_TEMPLATE_P (val))
-           val = lookup_template_class (val,
-                                        TREE_OPERAND (template_id, 1),
-                                        /*in_decl=*/NULL_TREE,
-                                        /*context=*/NULL_TREE,
-                                        /*entering_scope=*/0,
-                                        tf_error | tf_warning);
-         else if (DECL_FUNCTION_TEMPLATE_P (val)
-                  || TREE_CODE (val) == OVERLOAD)
-           val = lookup_template_function (val,
-                                           TREE_OPERAND (template_id, 1));
-         else
-           {
-             error ("%<%D::%D%> is not a template", namespace, name);
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-           }
-       }
-
-      /* If we have a single function from a using decl, pull it out.  */
-      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
-       val = OVL_FUNCTION (val);
-
-      /* Ignore built-in functions and friends that haven't been declared
-        yet.  */
-      if (!val || !hidden_name_p (val))
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-    }
+         tree n = NULL_TREE;
 
-  error ("%qD undeclared in namespace %qD", name, namespace);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-}
-
-/* Select the right _DECL from multiple choices.  */
-
-static tree
-select_decl (const struct scope_binding *binding, int flags)
-{
-  tree val;
-  val = binding->value;
-
-  timevar_push (TV_NAME_LOOKUP);
-  if (LOOKUP_NAMESPACES_ONLY (flags))
-    {
-      /* We are not interested in types.  */
-      if (val && TREE_CODE (val) == NAMESPACE_DECL)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+         for (o = fns; o; o = OVL_NEXT (o))
+           if (!hidden_name_p (OVL_CURRENT (o)))
+             n = build_overload (OVL_CURRENT (o), n);
+         fns = n;
+       }
     }
 
-  /* If looking for a type, or if there is no non-type binding, select
-     the value binding.  */
-  if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
-    val = binding->type;
-  /* Don't return non-types if we really prefer types.  */
-  else if (val && LOOKUP_TYPES_ONLY (flags)
-          && ! DECL_DECLARES_TYPE_P (val))
-    val = NULL_TREE;
-
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+  return fns;
 }
 
 /* Unscoped lookup of a global: iterate over current namespaces,
@@ -3584,24 +3698,17 @@ unqualified_namespace_lookup (tree name, int flags)
   tree siter;
   struct cp_binding_level *level;
   tree val = NULL_TREE;
-  struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
   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);
 
       if (b)
-       {
-         if (b->value && hidden_name_p (b->value))
-           /* Ignore anticipated built-in functions and friends.  */
-           ;
-         else
-           binding.value = b->value;
-         binding.type = b->type;
-       }
+       ambiguous_decl (&binding, b, flags);
 
       /* Add all _DECLs seen through local using-directives.  */
       for (level = current_binding_level;
@@ -3626,7 +3733,7 @@ unqualified_namespace_lookup (tree name, int flags)
          siter = CP_DECL_CONTEXT (siter);
        }
 
-      val = select_decl (&binding, flags);
+      val = binding.value;
       if (scope == global_namespace)
        break;
     }
@@ -3646,6 +3753,7 @@ tree
 lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
 {
   int flags = 0;
+  tree t = NULL_TREE;
 
   if (TREE_CODE (scope) == NAMESPACE_DECL)
     {
@@ -3655,17 +3763,14 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
       if (is_type_p)
        flags |= LOOKUP_PREFER_TYPES;
       if (qualified_lookup_using_namespace (name, scope, &binding, flags))
-       return select_decl (&binding, flags);
+       t = binding.value;
     }
   else if (is_aggr_type (scope, complain))
-    {
-      tree t;
-      t = lookup_member (scope, name, 2, is_type_p);
-      if (t)
-       return t;
-    }
+    t = lookup_member (scope, name, 2, is_type_p);
 
-  return error_mark_node;
+  if (!t)
+    return error_mark_node;
+  return t;
 }
 
 /* Subroutine of unqualified_namespace_lookup:
@@ -3691,7 +3796,7 @@ lookup_using_namespace (tree name, struct scope_binding *val,
          cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
        /* Resolve ambiguities.  */
        if (val1)
-         ambiguous_decl (name, val, val1, flags);
+         ambiguous_decl (val, val1, flags);
       }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
 }
@@ -3720,7 +3825,7 @@ qualified_lookup_using_namespace (tree name, tree scope,
        cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
       seen = tree_cons (scope, NULL_TREE, seen);
       if (binding)
-       ambiguous_decl (name, result, binding, flags);
+       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
@@ -3903,18 +4008,59 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
          continue;
 
        /* If this is the kind of thing we're looking for, we're done.  */
-       if (qualify_lookup (iter->value, flags)
-           && !hidden_name_p (iter->value))
+       if (qualify_lookup (iter->value, flags))
          binding = iter->value;
        else if ((flags & LOOKUP_PREFER_TYPES)
-                && qualify_lookup (iter->type, flags)
-                && !hidden_name_p (iter->type))
+                && qualify_lookup (iter->type, flags))
          binding = iter->type;
        else
          binding = NULL_TREE;
 
        if (binding)
          {
+           if (hidden_name_p (binding))
+             {
+               /* A non namespace-scope binding can only be hidden if
+                  we are in a local class, due to friend declarations.
+                  In particular, consider:
+
+                  void f() {
+                    struct A {
+                      friend struct B;
+                      void g() { B* b; } // error: B is hidden
+                    }
+                    struct B {};
+                  }
+
+                  The standard says that "B" is a local class in "f"
+                  (but not nested within "A") -- but that name lookup
+                  for "B" does not find this declaration until it is
+                  declared directly with "f".
+
+                  In particular:
+
+                  [class.friend]
+
+                  If a friend declaration appears in a local class and
+                  the name specified is an unqualified name, a prior
+                  declaration is looked up without considering scopes
+                  that are outside the innermost enclosing non-class
+                  scope. For a friend class declaration, if there is no
+                  prior declaration, the class that is specified 
+                  belongs to the innermost enclosing non-class scope,
+                  but if it is subsequently referenced, its name is not
+                  found by name lookup until a matching declaration is
+                  provided in the innermost enclosing nonclass scope.
+               */
+               gcc_assert (current_class_type &&
+                           LOCAL_CLASS_P (current_class_type));
+
+               /* This binding comes from a friend declaration in the local
+                  class. The standard (11.4.8) states that the lookup can
+                  only succeed if there is a non-hidden declaration in the
+                  current scope, which is not the case here.  */
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+             }
            val = binding;
            break;
          }
@@ -3924,12 +4070,9 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
   if (!val)
     val = unqualified_namespace_lookup (name, flags);
 
-  if (val)
-    {
-      /* If we have a single function from a using decl, pull it out.  */
-      if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
-       val = OVL_FUNCTION (val);
-    }
+  /* If we have a single function from a using decl, pull it out.  */
+  if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
+    val = OVL_FUNCTION (val);
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
 }
@@ -3951,7 +4094,13 @@ lookup_function_nonclass (tree name, tree args, bool block_p)
 }
 
 tree
-lookup_name (tree name, int prefer_type)
+lookup_name (tree name)
+{
+  return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
+}
+
+tree
+lookup_name_prefer_type (tree name, int prefer_type)
 {
   return lookup_name_real (name, prefer_type, 0, /*block_p=*/true,
                           0, LOOKUP_COMPLAIN);
@@ -3966,7 +4115,7 @@ lookup_name (tree name, int prefer_type)
    Unlike lookup_name_real, we make sure that NAME is actually
    declared in the desired scope, not from inheritance, nor using
    directive.  For using declaration, there is DR138 still waiting
-   to be resolved.  Hidden name coming from earlier an friend
+   to be resolved.  Hidden name coming from an earlier friend
    declaration is also returned.
 
    A TYPE_DECL best matching the NAME is returned.  Catching error
@@ -4052,7 +4201,7 @@ lookup_type_scope (tree name, tag_scope scope)
 /* Similar to `lookup_name' but look only in the innermost non-class
    binding level.  */
 
-static tree
+tree
 lookup_name_innermost_nonclass_level (tree name)
 {
   struct cp_binding_level *b;
@@ -4126,6 +4275,7 @@ lookup_type_current_level (tree name)
 struct arg_lookup
 {
   tree name;
+  tree args;
   tree namespaces;
   tree classes;
   tree functions;
@@ -4204,6 +4354,53 @@ is_associated_namespace (tree current, tree scope)
     }
 }
 
+/* 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;
+       }
+    }
+
+  /* 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;
+
+  return false;
+}
+
 /* Add functions of a namespace to the lookup structure.
    Returns true on error.  */
 
@@ -4227,8 +4424,25 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
     return false;
 
   for (; value; value = OVL_NEXT (value))
-    if (add_function (k, OVL_CURRENT (value)))
-      return true;
+    {
+      /* We don't want to find arbitrary hidden functions via argument
+        dependent lookup.  We only want to find friends of associated
+        classes.  */
+      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;
+       }
+
+      if (add_function (k, OVL_CURRENT (value)))
+       return true;
+    }
 
   return false;
 }
@@ -4265,6 +4479,17 @@ arg_assoc_template_arg (struct arg_lookup *k, tree arg)
       else
        return arg_assoc_class (k, ctx);
     }
+  /* It's an argument pack; handle it recursively.  */
+  else if (ARGUMENT_PACK_P (arg))
+    {
+      tree args = ARGUMENT_PACK_ARGS (arg);
+      int i, len = TREE_VEC_LENGTH (args);
+      for (i = 0; i < len; ++i) 
+       if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, i)))
+         return true;
+
+      return false;
+    }
   /* It's not a template template argument, but it is a type template
      argument.  */
   else if (TYPE_P (arg))
@@ -4368,7 +4593,6 @@ arg_assoc_type (struct arg_lookup *k, tree type)
     case REAL_TYPE:
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
-    case CHAR_TYPE:
     case BOOLEAN_TYPE:
       return false;
     case RECORD_TYPE:
@@ -4399,6 +4623,9 @@ arg_assoc_type (struct arg_lookup *k, tree type)
     case LANG_TYPE:
       gcc_assert (type == unknown_type_node);
       return false;
+    case TYPE_PACK_EXPANSION:
+      return arg_assoc_type (k, PACK_EXPANSION_PATTERN (type));
+
     default:
       gcc_unreachable ();
     }
@@ -4476,9 +4703,10 @@ arg_assoc (struct arg_lookup *k, tree n)
        return true;
 
       /* Now the arguments.  */
-      for (ix = TREE_VEC_LENGTH (args); ix--;)
-       if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
-         return true;
+      if (args)
+       for (ix = TREE_VEC_LENGTH (args); ix--;)
+         if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
+           return true;
     }
   else if (TREE_CODE (n) == OVERLOAD)
     {
@@ -4499,7 +4727,14 @@ lookup_arg_dependent (tree name, tree fns, tree args)
   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.  */
+  fns = remove_hidden_names (fns);
+
   k.name = name;
+  k.args = args;
   k.functions = fns;
   k.classes = NULL_TREE;
 
@@ -4511,7 +4746,19 @@ lookup_arg_dependent (tree name, tree fns, tree args)
   k.namespaces = NULL_TREE;
 
   arg_assoc_args (&k, args);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
+
+  fns = k.functions;
+  
+  if (fns
+      && TREE_CODE (fns) != VAR_DECL
+      && !is_overloaded_fn (fns))
+    {
+      error ("argument dependent lookup finds %q+D", fns);
+      error ("  in call to %qD", name);
+      fns = error_mark_node;
+    }
+    
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
 }
 
 /* Add namespace to using_directives. Return NULL_TREE if nothing was
@@ -4564,6 +4811,11 @@ maybe_process_template_type_declaration (tree type, int is_friend,
 
        is a forward-declaration of `A'.  */
     ;
+  else if (b->kind == sk_namespace
+          && current_binding_level->kind != sk_namespace)
+    /* If this new type is being injected into a containing scope,
+       then it's not a template type.  */
+    ;
   else
     {
       gcc_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE);
@@ -4592,7 +4844,7 @@ maybe_process_template_type_declaration (tree type, int is_friend,
                {
                  maybe_add_class_template_decl_list (current_class_type,
                                                      type, /*friend_p=*/0);
-                 /* Put this UDT in the table of UDTs for the class.  */
+                 /* Put this UTD in the table of UTDs for the class.  */
                  if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
                    CLASSTYPE_NESTED_UTDS (current_class_type) =
                      binding_table_new (SCOPE_DEFAULT_HT_SIZE);
@@ -4626,6 +4878,7 @@ tree
 pushtag (tree name, tree type, tag_scope scope)
 {
   struct cp_binding_level *b;
+  tree decl;
 
   timevar_push (TV_NAME_LOOKUP);
   b = current_binding_level;
@@ -4647,121 +4900,111 @@ pushtag (tree name, tree type, tag_scope scope)
                 || COMPLETE_TYPE_P (b->this_entity))))
     b = b->level_chain;
 
-  if (name)
+  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+
+  /* Do C++ gratuitous typedefing.  */
+  if (IDENTIFIER_TYPE_VALUE (name) != type)
     {
-      /* Do C++ gratuitous typedefing.  */
-      if (IDENTIFIER_TYPE_VALUE (name) != type)
-       {
-         tree d = NULL_TREE;
-         int in_class = 0;
-         tree context = TYPE_CONTEXT (type);
+      tree tdef;
+      int in_class = 0;
+      tree context = TYPE_CONTEXT (type);
 
-         if (! context)
-           {
-             tree cs = current_scope ();
-
-             if (scope == ts_current)
-               context = cs;
-             else if (cs != NULL_TREE && TYPE_P (cs))
-               /* When declaring a friend class of a local class, we want
-                  to inject the newly named class into the scope
-                  containing the local class, not the namespace scope.  */
-               context = decl_function_context (get_type_decl (cs));
-           }
-         if (!context)
-           context = current_namespace;
+      if (! context)
+       {
+         tree cs = current_scope ();
+
+         if (scope == ts_current)
+           context = cs;
+         else if (cs != NULL_TREE && TYPE_P (cs))
+           /* When declaring a friend class of a local class, we want
+              to inject the newly named class into the scope
+              containing the local class, not the namespace
+              scope.  */
+           context = decl_function_context (get_type_decl (cs));
+       }
+      if (!context)
+       context = current_namespace;
 
-         if (b->kind == sk_class
-             || (b->kind == sk_template_parms
-                 && b->level_chain->kind == sk_class))
-           in_class = 1;
+      if (b->kind == sk_class
+         || (b->kind == sk_template_parms
+             && b->level_chain->kind == sk_class))
+       in_class = 1;
 
-         if (current_lang_name == lang_name_java)
-           TYPE_FOR_JAVA (type) = 1;
+      if (current_lang_name == lang_name_java)
+       TYPE_FOR_JAVA (type) = 1;
 
-         d = create_implicit_typedef (name, type);
-         DECL_CONTEXT (d) = FROB_CONTEXT (context);
-         if (scope == ts_within_enclosing_non_class)
-           {
-             /* This is a friend.  Make this TYPE_DECL node hidden from
-                ordinary name lookup.  Its corresponding TEMPLATE_DECL
-                will be marked in push_template_decl_real.  */
-             retrofit_lang_decl (d);
-             DECL_ANTICIPATED (d) = 1;
-             DECL_FRIEND_P (d) = 1;
-           }
+      tdef = create_implicit_typedef (name, type);
+      DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
+      if (scope == ts_within_enclosing_non_class)
+       {
+         /* This is a friend.  Make this TYPE_DECL node hidden from
+            ordinary name lookup.  Its corresponding TEMPLATE_DECL
+            will be marked in push_template_decl_real.  */
+         retrofit_lang_decl (tdef);
+         DECL_ANTICIPATED (tdef) = 1;
+         DECL_FRIEND_P (tdef) = 1;
+       }
 
-         if (! in_class)
-           set_identifier_type_value_with_scope (name, d, b);
+      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);
 
-         d = maybe_process_template_type_declaration
-               (type, scope == ts_within_enclosing_non_class, b);
-         if (d == error_mark_node)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+      if (b->kind == sk_class)
+       {
+         if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+           /* Put this TYPE_DECL on the TYPE_FIELDS list for the
+              class.  But if it's a member template class, we want
+              the TEMPLATE_DECL, not the TYPE_DECL, so this is done
+              later.  */
+           finish_member_declaration (decl);
+         else
+           pushdecl_class_level (decl);
+       }
+      else if (b->kind != sk_template_parms)
+       {
+         decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
+         if (decl == error_mark_node)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+       }
 
-         if (b->kind == sk_class)
-           {
-             if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
-               /* Put this TYPE_DECL on the TYPE_FIELDS list for the
-                  class.  But if it's a member template class, we
-                  want the TEMPLATE_DECL, not the TYPE_DECL, so this
-                  is done later.  */
-               finish_member_declaration (d);
-             else
-               pushdecl_class_level (d);
-           }
-         else if (b->kind != sk_template_parms)
-           d = pushdecl_with_scope (d, b);
+      if (! in_class)
+       set_identifier_type_value_with_scope (name, tdef, b);
 
-         if (d == error_mark_node)
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+      TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
 
-         /* FIXME what if it gets a name from typedef?  */
-         if (ANON_AGGRNAME_P (name))
-           DECL_IGNORED_P (d) = 1;
+      /* If this is a local class, keep track of it.  We need this
+        information for name-mangling, and so that it is possible to
+        find all function definitions in a translation unit in a
+        convenient way.  (It's otherwise tricky to find a member
+        function definition it's only pointed to from within a local
+        class.)  */
+      if (TYPE_CONTEXT (type)
+         && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
+       VEC_safe_push (tree, gc, local_classes, type);
+    }
+  if (b->kind == sk_class
+      && !COMPLETE_TYPE_P (current_class_type))
+    {
+      maybe_add_class_template_decl_list (current_class_type,
+                                         type, /*friend_p=*/0);
 
-         TYPE_CONTEXT (type) = DECL_CONTEXT (d);
+      if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
+       CLASSTYPE_NESTED_UTDS (current_class_type)
+         = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
 
-         /* If this is a local class, keep track of it.  We need this
-            information for name-mangling, and so that it is possible to find
-            all function definitions in a translation unit in a convenient
-            way.  (It's otherwise tricky to find a member function definition
-            it's only pointed to from within a local class.)  */
-         if (TYPE_CONTEXT (type)
-             && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
-           VEC_safe_push (tree, gc, local_classes, type);
-       }
-      if (b->kind == sk_class
-         && !COMPLETE_TYPE_P (current_class_type))
-       {
-         maybe_add_class_template_decl_list (current_class_type,
-                                             type, /*friend_p=*/0);
+      binding_table_insert
+       (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
+    }
 
-         if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
-           CLASSTYPE_NESTED_UTDS (current_class_type)
-             = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+  decl = TYPE_NAME (type);
+  gcc_assert (TREE_CODE (decl) == TYPE_DECL);
+  TYPE_STUB_DECL (type) = decl;
 
-         binding_table_insert
-           (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
-       }
-    }
+  /* Set type visibility now if this is a forward declaration.  */
+  TREE_PUBLIC (decl) = 1;
+  determine_visibility (decl);
 
-  if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
-    /* Use the canonical TYPE_DECL for this node.  */
-    TYPE_STUB_DECL (type) = TYPE_NAME (type);
-  else
-    {
-      /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
-        will be the tagged type we just added to the current
-        binding level.  This fake NULL-named TYPE_DECL node helps
-        dwarfout.c to know when it needs to output a
-        representation of a tagged type, and it also gives us a
-        convenient place to record the "scope start" address for
-        the tagged type.  */
-
-      tree d = build_decl (TYPE_DECL, NULL_TREE, type);
-      TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
-    }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
 }
 \f
@@ -4838,7 +5081,7 @@ push_to_top_level (void)
   struct cp_binding_level *b;
   cxx_saved_binding *sb;
   size_t i;
-  int need_pop;
+  bool need_pop;
 
   timevar_push (TV_NAME_LOOKUP);
   s = GGC_CNEW (struct saved_scope);
@@ -4848,11 +5091,11 @@ push_to_top_level (void)
   /* If we're in the middle of some function, save our state.  */
   if (cfun)
     {
-      need_pop = 1;
+      need_pop = true;
       push_function_context_to (NULL_TREE);
     }
   else
-    need_pop = 0;
+    need_pop = false;
 
   if (scope_chain && previous_class_level)
     store_class_bindings (previous_class_level->class_shadowed,
@@ -4889,12 +5132,15 @@ push_to_top_level (void)
   s->bindings = b;
   s->need_pop_function_context = need_pop;
   s->function_decl = current_function_decl;
+  s->skip_evaluation = skip_evaluation;
 
   scope_chain = s;
   current_function_decl = NULL_TREE;
   current_lang_base = VEC_alloc (tree, gc, 10);
   current_lang_name = lang_name_cplusplus;
   current_namespace = global_namespace;
+  push_class_stack ();
+  skip_evaluation = 0;
   timevar_pop (TV_NAME_LOOKUP);
 }
 
@@ -4909,6 +5155,7 @@ pop_from_top_level (void)
   /* Clear out class-level bindings cache.  */
   if (previous_class_level)
     invalidate_class_lookup_cache ();
+  pop_class_stack ();
 
   current_lang_base = 0;
 
@@ -4926,6 +5173,7 @@ pop_from_top_level (void)
   if (s->need_pop_function_context)
     pop_function_context_from (NULL_TREE);
   current_function_decl = s->function_decl;
+  skip_evaluation = s->skip_evaluation;
   timevar_pop (TV_NAME_LOOKUP);
 }
 
@@ -4956,6 +5204,10 @@ pop_everything (void)
 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)
+    return;
+
   /* Ignore this FUNCTION_DECL if it refers to a builtin declaration
      of a builtin function.  */
   if (TREE_CODE (t) == FUNCTION_DECL