OSDN Git Service

PR c++/28048
[pf3gnuchains/gcc-fork.git] / gcc / cp / name-lookup.c
index 0abe1ec..7cc2fee 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for C++ name lookup routines.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
@@ -16,8 +16,8 @@ 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "diagnostic.h"
 #include "debug.h"
+#include "c-pragma.h"
 
 /* The bindings for a particular name in a particular scope.  */
 
@@ -44,14 +45,13 @@ 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);
+                                   tree, int);
 static bool qualified_lookup_using_namespace (tree, tree,
                                              struct scope_binding *, int);
 static tree lookup_type_current_level (tree);
 static tree push_using_directive (tree);
-static void cp_emit_debug_info_for_using (tree, tree);
 
 /* The :: namespace.  */
 
@@ -95,7 +95,7 @@ binding_entry_make (tree name, tree type)
 }
 
 /* Put ENTRY back on the free list.  */
-
+#if 0
 static inline void
 binding_entry_free (binding_entry entry)
 {
@@ -104,6 +104,7 @@ binding_entry_free (binding_entry entry)
   entry->chain = free_binding_entry;
   free_binding_entry = entry;
 }
+#endif
 
 /* The datatype used to implement the mapping from names to types at
    a given scope.  */
@@ -131,7 +132,7 @@ binding_table_construct (binding_table table, size_t chain_count)
 }
 
 /* Make TABLE's entries ready for reuse.  */
-
+#if 0
 static void
 binding_table_free (binding_table table)
 {
@@ -145,15 +146,16 @@ binding_table_free (binding_table table)
     {
       binding_entry temp = table->chain[i];
       while (temp != NULL)
-        {
-          binding_entry entry = temp;
-          temp = entry->chain;
-          binding_entry_free (entry);
-        }
+       {
+         binding_entry entry = temp;
+         temp = entry->chain;
+         binding_entry_free (entry);
+       }
       table->chain[i] = NULL;
     }
   table->entry_count = 0;
 }
+#endif
 
 /* Allocate a table with CHAIN_COUNT, assumed to be a power of two.  */
 
@@ -182,14 +184,14 @@ binding_table_expand (binding_table table)
     {
       binding_entry entry = old_chains[i];
       for (; entry != NULL; entry = old_chains[i])
-        {
-          const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
-          const size_t j = ENTRY_INDEX (hash, new_chain_count);
-
-          old_chains[i] = entry->chain;
-          entry->chain = table->chain[j];
-          table->chain[j] = entry;
-        }
+       {
+         const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
+         const size_t j = ENTRY_INDEX (hash, new_chain_count);
+
+         old_chains[i] = entry->chain;
+         entry->chain = table->chain[j];
+         table->chain[j] = entry;
+       }
     }
   table->entry_count = old_entry_count;
 }
@@ -225,82 +227,6 @@ binding_table_find (binding_table table, tree name)
   return entry;
 }
 
-/* Return the binding_entry, if any, that maps NAME to an anonymous type.  */
-
-static tree
-binding_table_find_anon_type (binding_table table, tree name)
-{
-  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
-  binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
-
-  while (entry != NULL && TYPE_IDENTIFIER (entry->type) != name)
-    entry = entry->chain;
-
-  return entry ? entry->type : NULL;
-}
-
-/* Return the binding_entry, if any, that has TYPE as target.  If NAME
-   is non-null, then set the domain and rehash that entry.  */
-
-static binding_entry
-binding_table_reverse_maybe_remap (binding_table table, tree type, tree name)
-{
-  const size_t chain_count = table->chain_count;
-  binding_entry entry = NULL;
-  binding_entry *p = NULL;
-  size_t i;
-
-  for (i = 0; i < chain_count && entry == NULL; ++i)
-    {
-      p = &table->chain[i];
-      while (*p != NULL && entry == NULL)
-        if ((*p)->type == type)
-          entry = *p;
-        else
-          p = &(*p)->chain;
-    }
-
-  if (entry != NULL && name != NULL && entry->name != name)
-    {
-      /* Remove the bucket from the previous chain.  */
-      *p = (*p)->chain;
-
-      /* Remap the name type to type.  */
-      i = ENTRY_INDEX (IDENTIFIER_HASH_VALUE (name), chain_count);
-      entry->chain = table->chain[i];
-      entry->name = name;
-      table->chain[i] = entry;
-    }
-
-  return entry;
-}
-
-/* Remove from TABLE all entries that map to anonymous enums or
-   class-types.  */
-
-void
-binding_table_remove_anonymous_types (binding_table table)
-{
-  const size_t chain_count = table->chain_count;
-  size_t i;
-
-  for (i = 0; i < chain_count; ++i)
-    {
-      binding_entry *p = &table->chain[i];
-
-      while (*p != NULL)
-        if (ANON_AGGRNAME_P ((*p)->name))
-          {
-            binding_entry e = *p;
-            *p = (*p)->chain;
-            --table->entry_count;
-            binding_entry_free (e);
-          }
-        else
-          p = &(*p)->chain;
-    }
-}
-
 /* Apply PROC -- with DATA -- to all entries in TABLE.  */
 
 void
@@ -313,7 +239,7 @@ binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
     {
       binding_entry entry = table->chain[i];
       for (; entry != NULL; entry = entry->chain)
-        proc (entry, data);
+       proc (entry, data);
     }
 }
 \f
@@ -375,16 +301,16 @@ 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, scope->class_shadowed, -1))
+      if (VEC_reserve (cp_class_binding, gc, scope->class_shadowed, 1))
        {
          /* Fixup the current bindings, as they might have moved.  */
          size_t i;
-         
+
          for (i = 0;
               VEC_iterate (cp_class_binding, scope->class_shadowed, i, cb);
               i++)
@@ -399,8 +325,8 @@ new_class_binding (tree name, tree value, tree type, cxx_scope *scope)
       cb = VEC_quick_push (cp_class_binding, scope->class_shadowed, NULL);
     }
   else
-    cb = VEC_safe_push (cp_class_binding, scope->class_shadowed, NULL);
-  
+    cb = VEC_safe_push (cp_class_binding, gc, scope->class_shadowed, NULL);
+
   cb->identifier = name;
   binding = &cb->base;
   binding->scope = scope;
@@ -423,7 +349,7 @@ push_binding (tree id, tree decl, cxx_scope* level)
     }
   else
     binding = new_class_binding (id, decl, /*type=*/NULL_TREE, level);
-                             
+
   /* Now, fill in the binding information.  */
   binding->previous = IDENTIFIER_BINDING (id);
   INHERITED_VALUE_BINDING_P (binding) = 0;
@@ -474,7 +400,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
@@ -505,17 +431,18 @@ supplement_binding (cxx_binding *binding, tree decl)
   else if (/* BVAL is null when push_class_level_binding moves an
              inherited type-binding out of the way to make room for a
              new value binding.  */
-          !bval 
+          !bval
           /* BVAL is error_mark_node when DECL's name has been used
              in a non-class scope prior declaration.  In that case,
              we should have already issued a diagnostic; for graceful
              error recovery purpose, pretend this was the intended
              declaration for that name.  */
           || bval == error_mark_node
-          /* If BVAL is 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))
     {
@@ -531,19 +458,24 @@ supplement_binding (cxx_binding *binding, tree decl)
   else if (TREE_CODE (bval) == TYPE_DECL
           && TREE_CODE (decl) == TYPE_DECL
           && DECL_NAME (decl) == DECL_NAME (bval)
+          && binding->scope->kind != sk_class
           && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
               /* If either type involves template parameters, we must
                  wait until instantiation.  */
               || uses_template_parms (TREE_TYPE (decl))
               || uses_template_parms (TREE_TYPE (bval))))
     /* We have two typedef-names, both naming the same type to have
-       the same name.  This is OK because of:
+       the same name.  In general, this is OK because of:
 
-         [dcl.typedef]
+        [dcl.typedef]
 
         In a given scope, a typedef specifier can be used to redefine
         the name of any type declared in that scope to refer to the
-        type to which it already refers.  */
+        type to which it already refers.
+
+       However, in class scopes, this rule does not apply due to the
+       stricter language in [class.mem] prohibiting redeclarations of
+       members.  */
     ok = false;
   /* There can be two block-scope declarations of the same variable,
      so long as they are `extern' declarations.  However, there cannot
@@ -557,7 +489,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
@@ -566,7 +498,7 @@ supplement_binding (cxx_binding *binding, tree decl)
           && DECL_NAMESPACE_ALIAS (bval)
           && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
     /* [namespace.alias]
-       
+
       In a declarative region, a namespace-alias-definition can be
       used to redefine a namespace-alias declared in that declarative
       region to refer only to the namespace to which it already
@@ -575,7 +507,7 @@ supplement_binding (cxx_binding *binding, tree decl)
   else
     {
       error ("declaration of %q#D", decl);
-      cp_error_at ("conflicts with previous declaration %q#D", bval);
+      error ("conflicts with previous declaration %q+#D", bval);
       ok = false;
     }
 
@@ -587,7 +519,7 @@ supplement_binding (cxx_binding *binding, tree decl)
 static void
 add_decl_to_level (tree decl, cxx_scope *b)
 {
-  if (TREE_CODE (decl) == NAMESPACE_DECL 
+  if (TREE_CODE (decl) == NAMESPACE_DECL
       && !DECL_NAMESPACE_ALIAS (decl))
     {
       TREE_CHAIN (decl) = b->namespaces;
@@ -598,16 +530,16 @@ add_decl_to_level (tree decl, cxx_scope *b)
       TREE_CHAIN (decl) = b->vtables;
       b->vtables = decl;
     }
-  else       
+  else
     {
       /* We build up the list in reverse order, and reverse it later if
-         necessary.  */
+        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 
+        include extern variables because they might turn out to be
         static later.  It's OK for this list to contain a few false
         positives.  */
       if (b->kind == sk_namespace)
@@ -615,20 +547,21 @@ add_decl_to_level (tree decl, cxx_scope *b)
             && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
            || (TREE_CODE (decl) == FUNCTION_DECL
                && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
-         VARRAY_PUSH_TREE (b->static_decls, decl);
+         VEC_safe_push (tree, gc, b->static_decls, decl);
     }
 }
 
 /* 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;
@@ -636,6 +569,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))
@@ -646,7 +582,7 @@ pushdecl (tree x)
     {
       if (current_function_decl && x != current_function_decl
          /* A local declaration for a function doesn't constitute
-             nesting.  */
+            nesting.  */
          && TREE_CODE (x) != FUNCTION_DECL
          /* A local declaration for an `extern' variable is in the
             scope of the current namespace, not the current
@@ -670,6 +606,9 @@ pushdecl (tree x)
     {
       int different_binding_level = 0;
 
+      if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
+       check_default_args (x);
+
       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        name = TREE_OPERAND (name, 0);
 
@@ -734,14 +673,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)
@@ -749,7 +702,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)
@@ -760,15 +713,15 @@ pushdecl (tree x)
            {
              if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
                pedwarn ("redeclaration of %<wchar_t%> as %qT",
-                         TREE_TYPE (x));
+                        TREE_TYPE (x));
 
              /* Throw away the redeclaration.  */
              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
            }
          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.  */
              if (olddecl == error_mark_node)
@@ -778,8 +731,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);
                }
@@ -787,11 +738,11 @@ pushdecl (tree x)
                {
                  /* A redeclaration of main, but not a duplicate of the
                     previous one.
-                    
+
                     [basic.start.main]
-                    
+
                     This function shall not be overloaded.  */
-                 cp_error_at ("invalid redeclaration of %qD", t);
+                 error ("invalid redeclaration of %q+D", t);
                  error ("as %qD", x);
                  /* We don't try to push this declaration since that
                     causes a crash.  */
@@ -812,7 +763,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 ())
@@ -823,7 +774,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);
@@ -836,28 +787,28 @@ pushdecl (tree x)
        {
          tree type = TREE_TYPE (x);
          if (DECL_IS_BUILTIN (x))
-            {
+           {
              if (TYPE_NAME (type) == 0)
-               TYPE_NAME (type) = x;
-            }
-          else if (type != error_mark_node && TYPE_NAME (type) != x
+               TYPE_NAME (type) = x;
+           }
+         else if (type != error_mark_node && TYPE_NAME (type) != x
                   /* We don't want to copy the type when all we're
                      doing is making a TYPE_DECL for the purposes of
                      inlining.  */
                   && (!TYPE_NAME (type)
                       || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))
-            {
+           {
              DECL_ORIGINAL_TYPE (x) = type;
-              type = build_variant_type_copy (type);
+             type = build_variant_type_copy (type);
              TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
-              TYPE_NAME (type) = x;
-              TREE_TYPE (x) = type;
-            }
+             TYPE_NAME (type) = x;
+             TREE_TYPE (x) = type;
+           }
 
          if (type != error_mark_node
              && TYPE_NAME (type)
              && TYPE_IDENTIFIER (type))
-            set_identifier_type_value (DECL_NAME (x), x);
+           set_identifier_type_value (DECL_NAME (x), x);
        }
 
       /* Multiple external decls of the same identifier ought to match.
@@ -881,10 +832,20 @@ pushdecl (tree x)
              && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
            {
              pedwarn ("type mismatch with previous external decl of %q#D", x);
-             cp_pedwarn_at ("previous external decl of %q#D", decl);
+             pedwarn ("previous external decl of %q+#D", decl);
            }
        }
 
+      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 ())
@@ -896,16 +857,15 @@ pushdecl (tree x)
          if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
            TREE_PUBLIC (name) = 1;
 
-         /* Bind the name for the entity.  */
-         if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (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))
-           SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
+         /* Bind the name for the entity.  */
+         if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
+               && t != NULL_TREE)
+             && (TREE_CODE (x) == TYPE_DECL
+                 || TREE_CODE (x) == VAR_DECL
+                 || TREE_CODE (x) == NAMESPACE_DECL
+                 || TREE_CODE (x) == CONST_DECL
+                 || TREE_CODE (x) == TEMPLATE_DECL))
+           SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
 
          /* If new decl is `static' and an `extern' was seen previously,
             warn about it.  */
@@ -963,8 +923,8 @@ pushdecl (tree x)
                /* OK */;
              else
                {
-                 warning ("extern declaration of %q#D doesn't match", x);
-                 cp_warning_at ("global declaration %q#D", oldglobal);
+                 warning (0, "extern declaration of %q#D doesn't match", x);
+                 warning (0, "global declaration %q+#D", oldglobal);
                }
            }
          /* If we have a local external declaration,
@@ -994,8 +954,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)
@@ -1007,8 +968,8 @@ pushdecl (tree x)
 
              if (warn_shadow && !err)
                {
-                 warning ("declaration of %q#D shadows a parameter", x);
-                 warning ("%Jshadowed declaration is here", oldlocal);
+                 warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x);
+                 warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
                }
            }
 
@@ -1028,33 +989,30 @@ pushdecl (tree x)
                                        /*want_type=*/false);
              else
                member = NULL_TREE;
-                 
+
              if (member && !TREE_STATIC (member))
                {
                  /* Location of previous decl is not useful in this case.  */
-                 warning ("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 ("declaration of %qD shadows a previous local", x);
-                 warning ("%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 ("declaration of %qD shadows a global declaration",
+                 warning (OPT_Wshadow, "declaration of %qD shadows a global declaration",
                           x);
-                 warning ("%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);
     }
@@ -1068,6 +1026,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.  */
 
@@ -1151,20 +1117,22 @@ check_for_out_of_scope_variable (tree decl)
   if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
     return decl;
 
-  shadowed = DECL_SHADOWED_FOR_VAR (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_SHADOWED_FOR_VAR (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));
   if (shadowed)
     {
       if (!DECL_ERROR_REPORTED (decl))
        {
-         warning ("name lookup of %qD changed", DECL_NAME (decl));
-         cp_warning_at ("  matches this %qD under ISO standard rules",
-                        shadowed);
-         cp_warning_at ("  matches this %qD under old rules", decl);
+         warning (0, "name lookup of %qD changed", DECL_NAME (decl));
+         warning (0, "  matches this %q+D under ISO standard rules",
+                  shadowed);
+         warning (0, "  matches this %q+D under old rules", decl);
          DECL_ERROR_REPORTED (decl) = 1;
        }
       return shadowed;
@@ -1184,15 +1152,15 @@ check_for_out_of_scope_variable (tree decl)
     {
       error ("name lookup of %qD changed for new ISO %<for%> scoping",
             DECL_NAME (decl));
-      cp_error_at ("  cannot use obsolete binding at %qD because "
-                   "it has a destructor", decl);
+      error ("  cannot use obsolete binding at %q+D because "
+            "it has a destructor", decl);
       return error_mark_node;
     }
   else
     {
       pedwarn ("name lookup of %qD changed for new ISO %<for%> scoping",
               DECL_NAME (decl));
-      cp_pedwarn_at ("  using obsolete binding at %qD", decl);
+      pedwarn ("  using obsolete binding at %q+D", decl);
     }
 
   return decl;
@@ -1246,7 +1214,7 @@ cxx_scope_debug (cxx_scope *scope, int line, const char *action)
   const char *desc = cxx_scope_descriptor (scope);
   if (scope->this_entity)
     verbatim ("%s %s(%E) %p %d\n", action, desc,
-              scope->this_entity, (void *) scope, line);
+             scope->this_entity, (void *) scope, line);
   else
     verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
 }
@@ -1298,7 +1266,7 @@ cxx_scope *
 begin_scope (scope_kind kind, tree entity)
 {
   cxx_scope *scope;
-  
+
   /* Reuse or create a struct for this binding level.  */
   if (!ENABLE_SCOPE_CHECKING && free_binding_level)
     {
@@ -1316,7 +1284,7 @@ begin_scope (scope_kind kind, tree entity)
     case sk_cleanup:
       scope->keep = true;
       break;
-      
+
     case sk_template_spec:
       scope->explicit_spec_p = true;
       kind = sk_template_parms;
@@ -1328,17 +1296,17 @@ 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;
 
     case sk_namespace:
-      scope->type_decls = binding_table_new (namespace_scope_ht_size (entity));
       NAMESPACE_LEVEL (entity) = scope;
-      VARRAY_TREE_INIT (scope->static_decls,
-                        DECL_NAME (entity) == std_identifier
-                        || DECL_NAME (entity) == global_scope_name
-                        ? 200 : 10,
-                        "Static declarations");
+      scope->static_decls =
+       VEC_alloc (tree, gc,
+                  DECL_NAME (entity) == std_identifier
+                  || DECL_NAME (entity) == global_scope_name
+                  ? 200 : 10);
       break;
 
     default:
@@ -1367,24 +1335,29 @@ leave_scope (void)
   /* We cannot leave a scope, if there are none left.  */
   if (NAMESPACE_LEVEL (global_namespace))
     gcc_assert (!global_scope_p (scope));
-  
+
   if (ENABLE_SCOPE_CHECKING)
     {
       indent (--binding_depth);
       cxx_scope_debug (scope, input_line, "leave");
       if (is_class_level != (scope == class_binding_level))
-        {
-          indent (binding_depth);
-          verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
-        }
+       {
+         indent (binding_depth);
+         verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
+       }
       is_class_level = 0;
     }
 
+#ifdef HANDLE_PRAGMA_VISIBILITY
+  if (scope->has_visibility)
+    pop_visibility ();
+#endif
+
   /* Move one nesting level up.  */
   current_binding_level = scope->level_chain;
 
   /* Namespace-scopes are left most probably temporarily, not
-     completely; they can be reopen later, e.g. in namespace-extension
+     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.  */
@@ -1392,10 +1365,6 @@ leave_scope (void)
       && scope->kind != sk_class)
     {
       scope->level_chain = free_binding_level;
-      if (scope->kind == sk_class)
-        scope->type_decls = NULL;
-      else
-        binding_table_free (scope->type_decls);
       gcc_assert (!ENABLE_SCOPE_CHECKING
                  || scope->binding_depth == binding_depth);
       free_binding_level = scope;
@@ -1403,11 +1372,16 @@ leave_scope (void)
 
   /* Find the innermost enclosing class scope, and reset
      CLASS_BINDING_LEVEL appropriately.  */
-  for (scope = current_binding_level;
-       scope && scope->kind != sk_class;
-       scope = scope->level_chain)
-    ;
-  class_binding_level = scope && scope->kind == sk_class ? scope : NULL;
+  if (scope->kind == sk_class)
+    {
+      class_binding_level = NULL;
+      for (scope = current_binding_level; scope; scope = scope->level_chain)
+       if (scope->kind == sk_class)
+         {
+           class_binding_level = scope;
+           break;
+         }
+    }
 
   return current_binding_level;
 }
@@ -1502,9 +1476,8 @@ kept_level_p (void)
 {
   return (current_binding_level->blocks != NULL_TREE
          || current_binding_level->keep
-          || current_binding_level->kind == sk_cleanup
-         || current_binding_level->names != NULL_TREE
-         || current_binding_level->type_decls != NULL);
+         || current_binding_level->kind == sk_cleanup
+         || current_binding_level->names != NULL_TREE);
 }
 
 /* Returns the kind of the innermost scope.  */
@@ -1544,64 +1517,16 @@ getdecls (void)
   return current_binding_level->names;
 }
 
-/* Set the current binding TABLE for type declarations..  This is a
-   temporary workaround of the fact that the data structure classtypes
-   does not currently carry its allocated cxx_scope structure.  */
-void
-cxx_remember_type_decls (binding_table table)
-{
-  current_binding_level->type_decls = table;
-}
-
 /* For debugging.  */
 static int no_print_functions = 0;
 static int no_print_builtins = 0;
 
-/* Called from print_binding_level through binding_table_foreach to
-   print the content of binding ENTRY.  DATA is a pointer to line offset
-   marker.  */
 static void
-bt_print_entry (binding_entry entry, void *data)
-{
-  int *p = (int *) data;
-  int len;
-
-  if (entry->name == NULL)
-    len = 3;
-  else if (entry->name == TYPE_IDENTIFIER (entry->type))
-    len = 2;
-  else
-    len = 4;
-    len = 4;
-
-  *p += len;
-
-  if (*p > 5)
-    {
-      fprintf (stderr, "\n\t");
-      *p = len;
-    }
-  if (entry->name == NULL)
-    {
-      print_node_brief (stderr, "<unnamed-typedef", entry->type, 0);
-      fprintf (stderr, ">");
-    }
-  else if (entry->name == TYPE_IDENTIFIER (entry->type))
-    print_node_brief (stderr, "", entry->type, 0);
-  else
-    {
-      print_node_brief (stderr, "<typedef", entry->name, 0);
-      print_node_brief (stderr, "", entry->type, 0);
-      fprintf (stderr, ">");
-    }
-}
-
-void
 print_binding_level (struct cp_binding_level* lvl)
 {
   tree t;
   int i = 0, len;
-  fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
+  fprintf (stderr, " blocks=%p", (void *) lvl->blocks);
   if (lvl->more_cleanups_ok)
     fprintf (stderr, " more-cleanups-ok");
   if (lvl->have_cleanups)
@@ -1636,14 +1561,6 @@ print_binding_level (struct cp_binding_level* lvl)
            break;
        }
       if (i)
-        fprintf (stderr, "\n");
-    }
-  if (lvl->type_decls)
-    {
-      fprintf (stderr, " tags:\t");
-      i = 0;
-      binding_table_foreach (lvl->type_decls, bt_print_entry, &i);
-      if (i)
        fprintf (stderr, "\n");
     }
   if (VEC_length (cp_class_binding, lvl->class_shadowed))
@@ -1651,9 +1568,9 @@ print_binding_level (struct cp_binding_level* lvl)
       size_t i;
       cp_class_binding *b;
       fprintf (stderr, " class-shadowed:");
-      for (i = 0; 
+      for (i = 0;
           VEC_iterate(cp_class_binding, lvl->class_shadowed, i, b);
-          ++i) 
+          ++i)
        fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
       fprintf (stderr, "\n");
     }
@@ -1661,9 +1578,9 @@ print_binding_level (struct cp_binding_level* lvl)
     {
       fprintf (stderr, " type-shadowed:");
       for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
-        {
+       {
          fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
-        }
+       }
       fprintf (stderr, "\n");
     }
 }
@@ -1674,7 +1591,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);
     }
 }
@@ -1683,11 +1600,11 @@ 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));
+          (void *) NAMESPACE_LEVEL (global_namespace));
   if (class_binding_level)
     {
       for (b = class_binding_level; b; b = b->level_chain)
@@ -1762,7 +1679,7 @@ set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b)
        supplement_binding (binding, decl);
       else
        binding->value = decl;
-      
+
       /* Store marker instead of real type.  */
       type = global_type_node;
     }
@@ -1782,7 +1699,7 @@ set_identifier_type_value (tree id, tree decl)
    specified class TYPE.  When given a template, this routine doesn't
    lose the specialization.  */
 
-tree
+static inline tree
 constructor_name_full (tree type)
 {
   return TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
@@ -1811,10 +1728,10 @@ constructor_name_p (tree name, tree type)
 
   if (!name)
     return false;
-  
+
   if (TREE_CODE (name) != IDENTIFIER_NODE)
     return false;
-  
+
   ctor_name = constructor_name_full (type);
   if (name == ctor_name)
     return true;
@@ -1840,28 +1757,7 @@ make_anon_name (void)
   return get_identifier (buf);
 }
 
-/* Clear the TREE_PURPOSE slot of UTDs which have anonymous typenames.
-   This keeps dbxout from getting confused.  */
-
-void
-clear_anon_tags (void)
-{
-  struct cp_binding_level *b;
-  static int last_cnt = 0;
-
-  /* Fast out if no new anon names were declared.  */
-  if (last_cnt == anon_cnt)
-    return;
-
-  b = current_binding_level;
-  while (b->kind == sk_cleanup)
-    b = b->level_chain;
-  if (b->type_decls != NULL)
-    binding_table_remove_anonymous_types (b->type_decls);
-  last_cnt = anon_cnt;
-}
-\f
-/* Return (from the stack of) the BINDING, if any, established at SCOPE.  */ 
+/* Return (from the stack of) the BINDING, if any, established at SCOPE.  */
 
 static inline cxx_binding *
 find_binding (cxx_scope *scope, cxx_binding *binding)
@@ -1885,7 +1781,7 @@ cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
     {
       /* Fold-in case where NAME is used only once.  */
       if (scope == b->scope && b->previous == NULL)
-        return b;
+       return b;
       return find_binding (scope, b);
     }
   return NULL;
@@ -1917,7 +1813,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;
@@ -1926,13 +1822,13 @@ push_using_decl (tree scope, tree name)
   gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
   for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
-    if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
+    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);
-  decl = build_lang_decl (USING_DECL, name, void_type_node);
-  DECL_INITIAL (decl) = scope;
+                           namespace_bindings_p () ? decl : NULL_TREE);
+  decl = build_lang_decl (USING_DECL, name, NULL_TREE);
+  USING_DECL_SCOPE (decl) = scope;
   TREE_CHAIN (decl) = current_binding_level->usings;
   current_binding_level->usings = decl;
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
@@ -1942,7 +1838,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;
@@ -1960,7 +1856,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;
@@ -1978,16 +1874,18 @@ pushdecl_with_scope (tree x, cxx_scope *level)
 
    FLAGS is a bitwise-or of the following values:
      PUSH_LOCAL: Bind DECL in the current scope, rather than at
-                 namespace scope.
+                namespace scope.
      PUSH_USING: DECL is being pushed as the result of a using
-                 declaration.
+                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;
@@ -2008,34 +1906,47 @@ push_overloaded_decl (tree decl, int flags)
          if (IS_AGGR_TYPE (t) && warn_shadow
              && (! DECL_IN_SYSTEM_HEADER (decl)
                  || ! DECL_IN_SYSTEM_HEADER (old)))
-           warning ("%q#D hides constructor for %q#T", decl, t);
+           warning (0, "%q#D hides constructor for %q#T", decl, t);
          old = NULL_TREE;
        }
       else if (is_overloaded_fn (old))
-        {
-          tree tmp;
+       {
+         tree tmp;
 
          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)
                  && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
-                               TYPE_ARG_TYPES (TREE_TYPE (decl))))
+                               TYPE_ARG_TYPES (TREE_TYPE (decl)))
+                 && ! decls_match (fn, decl))
                error ("%q#D conflicts with previous using declaration %q#D",
-                       decl, fn);
+                      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_HIDDEN_FRIEND_P (old))
+           old = NULL;
        }
       else if (old == error_mark_node)
        /* Ignore the undefined symbol marker.  */
        old = NULL_TREE;
       else
        {
-         cp_error_at ("previous non-function declaration %q#D", old);
+         error ("previous non-function declaration %q+#D", old);
          error ("conflicts with function declaration %q#D", decl);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
        }
@@ -2125,7 +2036,7 @@ validate_nonmember_using_decl (tree decl, tree scope, tree name)
       /* 7.3.3/5
           A using-declaration shall not name a template-id.  */
       error ("a using-declaration cannot specify a template-id.  "
-             "Try %<using %D%>", name);
+            "Try %<using %D%>", name);
       return NULL_TREE;
     }
 
@@ -2156,7 +2067,7 @@ validate_nonmember_using_decl (tree decl, tree scope, tree name)
 
 static void
 do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
-                         tree *newval, tree *newtype)
+                        tree *newval, tree *newtype)
 {
   struct scope_binding decls = EMPTY_SCOPE_BINDING;
 
@@ -2171,6 +2082,15 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
       return;
     }
 
+  /* 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_HIDDEN_FRIEND_P (oldval))
+    oldval = NULL_TREE;
+
   /* Check for using functions.  */
   if (decls.value && is_overloaded_fn (decls.value))
     {
@@ -2198,35 +2118,27 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
            {
              tree old_fn = OVL_CURRENT (tmp1);
 
-              if (new_fn == old_fn)
-                /* The function already exists in the current namespace.  */
-                break;
+             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 */
+               continue; /* this is a using decl */
              else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
-                                 TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+                                 TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
                {
-                 /* There was already a non-using declaration in
+                 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))
-                   {
-                     /* If the OLD_FN was a builtin, there is now a
-                        real declaration.  */
-                     if (DECL_ANTICIPATED (old_fn))
-                       DECL_ANTICIPATED (old_fn) = 0;
-                     break;
-                   }
-                 else if (!DECL_ANTICIPATED (old_fn))
+                    are the same extern "C" functions, that's ok.  */
+                 if (decls_match (new_fn, old_fn))
+                   break;
+                 else
                    {
-                     /* If the OLD_FN was really declared, the
-                        declarations don't match.  */
                      error ("%qD is already declared in this scope", name);
                      break;
                    }
-
-                 /* If the OLD_FN was not really there, just ignore
-                    it and keep going.  */
                }
            }
 
@@ -2235,7 +2147,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
             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)
@@ -2254,7 +2166,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
          OVL_USED (*newval) = 1;
        }
     }
-  else 
+  else
     {
       *newval = decls.value;
       if (oldval && !decls_match (*newval, oldval))
@@ -2265,7 +2177,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
   if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
     {
       error ("using declaration %qD introduced ambiguous type %qT",
-             name, oldtype);
+            name, oldtype);
       return;
     }
 }
@@ -2305,10 +2217,11 @@ do_local_using_decl (tree decl, tree scope, tree name)
            term = OVL_FUNCTION (oldval);
          else
            term = oldval;
-         for (fn = newval; fn && OVL_CURRENT (fn) != term; 
+         for (fn = newval; fn && OVL_CURRENT (fn) != term;
               fn = OVL_NEXT (fn))
-           push_overloaded_decl (OVL_CURRENT (fn), 
-                                 PUSH_LOCAL | PUSH_USING);
+           push_overloaded_decl (OVL_CURRENT (fn),
+                                 PUSH_LOCAL | PUSH_USING,
+                                 false);
        }
       else
        push_local_binding (name, newval, PUSH_USING);
@@ -2324,188 +2237,6 @@ do_local_using_decl (tree decl, tree scope, tree name)
     cp_emit_debug_info_for_using (orig_decl, current_scope());
 }
 
-/* Return the type that should be used when TYPE's name is preceded
-   by a tag such as 'struct' or 'union', or null if the name cannot
-   be used in this way.
-
-   For example, when processing the third line of:
-
-       struct A;
-       typedef struct A A;
-       struct A;
-
-   lookup of A will find the typedef.  Given A's typedef, this function
-   will return the type associated with "struct A".  For the tag to be
-   anything other than TYPE, TYPE must be a typedef whose original type
-   has the same name and context as TYPE itself.
-
-   It is not valid for a typedef of an anonymous type to be used with
-   an explicit tag:
-
-       typedef struct { ... } B;
-       struct B;
-
-   Return null for this case.  */
-
-static tree
-follow_tag_typedef (tree type)
-{
-  tree original;
-
-  original = original_type (type);
-  if (! TYPE_NAME (original))
-    return NULL_TREE;
-  if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type)
-      && (CP_DECL_CONTEXT (TYPE_NAME (original))
-         == CP_DECL_CONTEXT (TYPE_NAME (type)))
-      && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original)))
-    return original;
-  else
-    return NULL_TREE;
-}
-
-/* Given NAME, an IDENTIFIER_NODE,
-   return the structure (or union or enum) definition for that name.
-   Searches binding levels from its SCOPE up to the global level.
-   If THISLEVEL_ONLY is nonzero, searches only the specified context
-   (but skips any sk_cleanup contexts to find one that is
-   meaningful for tags).
-   FORM says which kind of type the caller wants;
-   it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
-   If the wrong kind of type is found, and it's not a template, an error is
-   reported.  */
-
-tree
-lookup_tag (enum tree_code form, tree name,
-            cxx_scope *binding_level, int thislevel_only)
-{
-  struct cp_binding_level *level;
-  /* Nonzero if, we should look past a template parameter level, even
-     if THISLEVEL_ONLY.  */
-  int allow_template_parms_p = 1;
-  bool type_is_anonymous = ANON_AGGRNAME_P (name);
-
-  timevar_push (TV_NAME_LOOKUP);
-  for (level = binding_level; level; level = level->level_chain)
-    {
-      tree tail;
-      if (type_is_anonymous && level->type_decls != NULL)
-        {
-          tree type = binding_table_find_anon_type (level->type_decls, name);
-          /* There is no need for error checking here, because
-           anon names are unique throughout the compilation.  */
-          if (type != NULL)
-            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
-        }
-      else if (level->kind == sk_namespace)
-       /* Do namespace lookup.  */
-       for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
-         {
-            cxx_binding *binding =
-              cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
-
-           if (binding && (binding->type
-                           || (binding->value 
-                               && DECL_DECLARES_TYPE_P (binding->value))))
-             {
-               tree old;
-               
-               /* If we just skipped past a template parameter level,
-                  even though THISLEVEL_ONLY, and we find a template
-                  class declaration, then we use the _TYPE node for the
-                  template.  See the example below.  */
-               if (thislevel_only && !allow_template_parms_p
-                   && binding->value
-                   && DECL_CLASS_TEMPLATE_P (binding->value))
-                 old = binding->value;
-               else
-                 old = binding->type ? binding->type : binding->value;
-
-               /* We've found something at this binding level.  If it is
-                  a typedef, extract the tag it refers to.  Lookup fails
-                  if the typedef doesn't refer to a taggable type.  */
-               old = TREE_TYPE (old);
-               old = follow_tag_typedef (old);
-               if (!old)
-                 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-               if (TREE_CODE (old) != form
-                   && (form == ENUMERAL_TYPE
-                       || TREE_CODE (old) == ENUMERAL_TYPE))
-                 {
-                   error ("%q#D redeclared as %C", old, form);
-                   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-                 }
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
-             }
-           if (thislevel_only || tail == global_namespace)
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-         }
-      else if (level->type_decls != NULL)
-        {
-          binding_entry entry = binding_table_find (level->type_decls, name);
-          if (entry != NULL)
-            {
-              enum tree_code code = TREE_CODE (entry->type);
-               
-              if (code != form
-                  && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
-                {
-                  /* Definition isn't the kind we were looking for.  */
-                  error ("%q#D redeclared as %C", entry->type, form);
-                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-                }
-              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
-            }
-         }
-      if (thislevel_only && level->kind != sk_cleanup)
-       {
-         if (level->kind == sk_template_parms && allow_template_parms_p)
-           {
-             /* We must deal with cases like this:
-
-                  template <class T> struct S;
-                  template <class T> struct S {};
-
-                When looking up `S', for the second declaration, we
-                would like to find the first declaration.  But, we
-                are in the pseudo-global level created for the
-                template parameters, rather than the (surrounding)
-                namespace level.  Thus, we keep going one more level,
-                even though THISLEVEL_ONLY is nonzero.  */
-             allow_template_parms_p = 0;
-             continue;
-           }
-         else
-           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-       }
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
-/* Given a type, find the tag that was defined for it and return the tag name.
-   Otherwise return 0.  However, the value can never be 0
-   in the cases in which this is used.
-
-   C++: If NAME is nonzero, this is the new name to install.  This is
-   done when replacing anonymous tags with real tag names.  */
-
-tree
-lookup_tag_reverse (tree type, tree name)
-{
-  struct cp_binding_level *level;
-
-  timevar_push (TV_NAME_LOOKUP);
-  for (level = current_binding_level; level; level = level->level_chain)
-    {
-      binding_entry entry = level->type_decls == NULL
-        ? NULL
-        : binding_table_reverse_maybe_remap (level->type_decls, type, name);
-      if (entry)
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name);
-    }
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
 /* Returns true if ROOT (a namespace, class, or function) encloses
    CHILD.  CHILD may be either a class type or a namespace.  */
 
@@ -2517,7 +2248,7 @@ is_ancestor (tree root, tree child)
               || CLASS_TYPE_P (root)));
   gcc_assert ((TREE_CODE (child) == NAMESPACE_DECL
               || CLASS_TYPE_P (child)));
-  
+
   /* The global namespace encloses everything.  */
   if (root == global_namespace)
     return true;
@@ -2537,14 +2268,14 @@ is_ancestor (tree root, tree child)
     }
 }
 
-/* Enter the class or namespace scope indicated by T.  Returns TRUE iff
-   pop_scope should be called later to exit this scope.  */
+/* Enter the class or namespace scope indicated by T suitable for name
+   lookup.  T can be arbitrary scope, not necessary nested inside the
+   current scope.  Returns a non-null scope to pop iff pop_scope
+   should be called later to exit this scope.  */
 
-bool
+tree
 push_scope (tree t)
 {
-  bool pop = true;
-
   if (TREE_CODE (t) == NAMESPACE_DECL)
     push_decl_namespace (t);
   else if (CLASS_TYPE_P (t))
@@ -2557,10 +2288,10 @@ push_scope (tree t)
           need to re-enter the scope.  Since we are not actually
           pushing a new scope, our caller should not call
           pop_scope.  */
-       pop = false;
+       t = NULL_TREE;
     }
 
-  return pop;
+  return t;
 }
 
 /* Leave scope pushed by push_scope.  */
@@ -2573,6 +2304,110 @@ pop_scope (tree t)
   else if CLASS_TYPE_P (t)
     pop_nested_class ();
 }
+
+/* Subroutine of push_inner_scope.  */
+
+static void
+push_inner_scope_r (tree outer, tree inner)
+{
+  tree prev;
+
+  if (outer == inner
+      || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
+    return;
+
+  prev = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
+  if (outer != prev)
+    push_inner_scope_r (outer, prev);
+  if (TREE_CODE (inner) == NAMESPACE_DECL)
+    {
+      struct cp_binding_level *save_template_parm = 0;
+      /* Temporary take out template parameter scopes.  They are saved
+        in reversed order in save_template_parm.  */
+      while (current_binding_level->kind == sk_template_parms)
+       {
+         struct cp_binding_level *b = current_binding_level;
+         current_binding_level = b->level_chain;
+         b->level_chain = save_template_parm;
+         save_template_parm = b;
+       }
+
+      resume_scope (NAMESPACE_LEVEL (inner));
+      current_namespace = inner;
+
+      /* Restore template parameter scopes.  */
+      while (save_template_parm)
+       {
+         struct cp_binding_level *b = save_template_parm;
+         save_template_parm = b->level_chain;
+         b->level_chain = current_binding_level;
+         current_binding_level = b;
+       }
+    }
+  else
+    pushclass (inner);
+}
+
+/* Enter the scope INNER from current scope.  INNER must be a scope
+   nested inside current scope.  This works with both name lookup and
+   pushing name into scope.  In case a template parameter scope is present,
+   namespace is pushed under the template parameter scope according to
+   name lookup rule in 14.6.1/6.
+
+   Return the former current scope suitable for pop_inner_scope.  */
+
+tree
+push_inner_scope (tree inner)
+{
+  tree outer = current_scope ();
+  if (!outer)
+    outer = current_namespace;
+
+  push_inner_scope_r (outer, inner);
+  return outer;
+}
+
+/* Exit the current scope INNER back to scope OUTER.  */
+
+void
+pop_inner_scope (tree outer, tree inner)
+{
+  if (outer == inner
+      || (TREE_CODE (inner) != NAMESPACE_DECL && !CLASS_TYPE_P (inner)))
+    return;
+
+  while (outer != inner)
+    {
+      if (TREE_CODE (inner) == NAMESPACE_DECL)
+       {
+         struct cp_binding_level *save_template_parm = 0;
+         /* Temporary take out template parameter scopes.  They are saved
+            in reversed order in save_template_parm.  */
+         while (current_binding_level->kind == sk_template_parms)
+           {
+             struct cp_binding_level *b = current_binding_level;
+             current_binding_level = b->level_chain;
+             b->level_chain = save_template_parm;
+             save_template_parm = b;
+           }
+
+         pop_namespace ();
+
+         /* Restore template parameter scopes.  */
+         while (save_template_parm)
+           {
+             struct cp_binding_level *b = save_template_parm;
+             save_template_parm = b->level_chain;
+             b->level_chain = current_binding_level;
+             current_binding_level = b;
+           }
+       }
+      else
+       popclass ();
+
+      inner = CP_DECL_CONTEXT (TREE_CODE (inner) == NAMESPACE_DECL ? inner : TYPE_NAME (inner));
+    }
+}
 \f
 /* Do a pushlevel for class declarations.  */
 
@@ -2697,9 +2532,7 @@ pushdecl_class_level (tree x)
          input_location = save_location;
        }
     }
-  timevar_pop (TV_NAME_LOOKUP);
-
-  return is_valid;
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid);
 }
 
 /* Return the BINDING (if any) for NAME in SCOPE, which is a class
@@ -2736,7 +2569,7 @@ get_class_binding (tree name, cxx_scope *scope)
     ;
   else if (value_binding)
     {
-      if (TREE_CODE (value_binding) == TREE_LIST 
+      if (TREE_CODE (value_binding) == TREE_LIST
          && TREE_TYPE (value_binding) == error_mark_node)
        /* NAME is ambiguous.  */
        ;
@@ -2749,8 +2582,8 @@ get_class_binding (tree name, cxx_scope *scope)
      new binding object.  */
   if (type_binding || value_binding)
     {
-      binding = new_class_binding (name, 
-                                  value_binding, 
+      binding = new_class_binding (name,
+                                  value_binding,
                                   type_binding,
                                   scope);
       /* This is a class-scope binding, not a block-scope binding.  */
@@ -2762,7 +2595,7 @@ get_class_binding (tree name, cxx_scope *scope)
 
   return binding;
 }
-                  
+
 /* Make the declaration(s) of X appear in CLASS scope under the name
    NAME.  Returns true if the binding is valid.  */
 
@@ -2779,12 +2612,15 @@ 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
      declaration. If so, pull the declaration out because
      check_template_shadow will not handle a TREE_LIST.  */
-  if (TREE_CODE (decl) == TREE_LIST 
+  if (TREE_CODE (decl) == TREE_LIST
       && TREE_TYPE (decl) == error_mark_node)
     decl = TREE_VALUE (decl);
 
@@ -2850,9 +2686,9 @@ push_class_level_binding (tree name, tree x)
       if (INHERITED_VALUE_BINDING_P (binding))
        {
          /* If the old binding was from a base class, and was for a
-            tag name, slide it over to make room for the new binding.
-            The old binding is still visible if explicitly qualified
-            with a class-key.  */
+            tag name, slide it over to make room for the new binding.
+            The old binding is still visible if explicitly qualified
+            with a class-key.  */
          if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
              && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
            {
@@ -2862,7 +2698,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;
@@ -2905,51 +2747,114 @@ push_class_level_binding (tree name, tree x)
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
 }
 
+/* Process "using SCOPE::NAME" in a class scope.  Return the
+   USING_DECL created.  */
+
 tree
-do_class_using_decl (tree decl)
+do_class_using_decl (tree scope, tree name)
 {
-  tree name, value, scope, type;
-  
-  if (TREE_CODE (decl) != SCOPE_REF
-      || !TREE_OPERAND (decl, 0)
-      || !TYPE_P (TREE_OPERAND (decl, 0)))
+  /* 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))
     {
       error ("using-declaration for non-member at class scope");
       return NULL_TREE;
     }
-  scope = TREE_OPERAND (decl, 0);
-  name = TREE_OPERAND (decl, 1);
+
+  /* Make sure the name is not invalid */
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
-      error ("using-declaration cannot name destructor");
+      error ("%<%T::%D%> names destructor", scope, name);
       return NULL_TREE;
     }
-  if (TREE_CODE (name) == TYPE_DECL)
-    name = DECL_NAME (name);
-  else if (TREE_CODE (name) == TEMPLATE_DECL)
-     name = DECL_NAME (name);
-  else if (BASELINK_P (name))
+  if (constructor_name_p (name, scope))
     {
-      tree fns = BASELINK_FUNCTIONS (name);
-      name = DECL_NAME (get_first_fn (fns));
+      error ("%<%T::%D%> names constructor", scope, name);
+      return NULL_TREE;
+    }
+  if (constructor_name_p (name, current_class_type))
+    {
+      error ("%<%T::%D%> names constructor in %qT",
+            scope, name, current_class_type);
+      return NULL_TREE;
     }
 
-  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+  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;
+       }
 
-  /* Dependent using decls have a NULL type, non-dependent ones have a
-     void type.  */
-  type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
-  value = build_lang_decl (USING_DECL, name, type);
-  DECL_INITIAL (value) = scope;
+  decl = NULL_TREE;
 
-  if (scope && !processing_template_decl)
+  /* 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.
+
+     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 && !bases_dependent_p)
     {
-      tree r;
+      base_kind b_kind;
+      tree binfo;
+      binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
+      if (b_kind < bk_proper_base)
+       {
+         error_not_base_type (scope, current_class_type);
+         return NULL_TREE;
+       }
+
+      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);
+       }
+   }
+
+  value = build_lang_decl (USING_DECL, name, NULL_TREE);
+  USING_DECL_DECLS (value) = decl;
+  USING_DECL_SCOPE (value) = scope;
+  DECL_DEPENDENT_P (value) = !decl;
 
-      r = lookup_qualified_name (scope, name, false, false);
-      if (r && (DECL_P (r) || TREE_CODE (r) == OVERLOAD))
-       cp_emit_debug_info_for_using (r, scope);
-    }
   return value;
 }
 
@@ -2963,7 +2868,10 @@ namespace_binding (tree name, tree scope)
 
   if (scope == NULL)
     scope = global_namespace;
-  scope = ORIGINAL_NAMESPACE (scope);
+  else
+    /* Unnecessary for the global namespace because it can't be an alias. */
+    scope = ORIGINAL_NAMESPACE (scope);
+
   binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
   return binding ? binding->value : NULL_TREE;
@@ -2993,59 +2901,70 @@ 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);
-  
+
   /* It is ok for friends to be qualified in parallel space.  */
   if (!friendp && !is_ancestor (current_namespace, scope))
     error ("declaration of %qD not in a namespace surrounding %qD",
-           decl, scope);
+          decl, scope);
   DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
-  if (scope != current_namespace)
+
+  /* Writing "int N::i" to declare a variable within "N" is invalid.  */
+  if (scope == current_namespace)
     {
-      /* See whether this has been declared in the namespace.  */
-      old = namespace_binding (DECL_NAME (decl), scope);
-      if (!old)
-       /* 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
-          point. pushdecl will find those errors later.  */
-       return;
-      /* Since decl is a function, old should contain a function decl.  */
-      if (!is_overloaded_fn (old))
-       goto complain;
-      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;
-      if (is_overloaded_fn (old))
-       {
-         for (; old; old = OVL_NEXT (old))
-           if (decls_match (decl, OVL_CURRENT (old)))
-             return;
-       }
-      else
-       if (decls_match (decl, old))
-         return;
+      if (at_namespace_scope_p ())
+       error ("explicit qualification in declaration of %qD",
+              decl);
+      return;
     }
-  else
+
+  /* See whether this has been declared in the namespace.  */
+  old = lookup_qualified_name (scope, DECL_NAME (decl), false, true);
+  if (!old)
+    /* No old declaration at all.  */
+    goto complain;
+  if (!is_overloaded_fn (decl))
+    /* Don't compare non-function decls with decls_match here, since
+       it can't check for the correct constness at this
+       point. pushdecl will find those errors later.  */
+    return;
+  /* 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))
+       if (decls_match (decl, OVL_CURRENT (old)))
+         return;
+    }
+  else if (decls_match (decl, old))
+      return;
  complain:
   error ("%qD should have been declared inside %qD", decl, scope);
-} 
+}
 
 /* Return the namespace where the current declaration is declared.  */
 
-tree
+static tree
 current_decl_namespace (void)
 {
   tree result;
@@ -3057,7 +2976,7 @@ current_decl_namespace (void)
     result = decl_namespace_context (current_class_type);
   else if (current_function_decl)
     result = decl_namespace_context (current_function_decl);
-  else 
+  else
     result = current_namespace;
   return result;
 }
@@ -3068,13 +2987,22 @@ current_decl_namespace (void)
 void
 push_namespace (tree name)
 {
+  push_namespace_with_attribs (name, NULL_TREE);
+}
+
+/* Same, but specify attributes to apply to the namespace.  The attributes
+   only apply to the current namespace-body, not to any later extensions. */
+
+void
+push_namespace_with_attribs (tree name, tree attributes)
+{
   tree d = NULL_TREE;
   int need_new = 1;
   int implicit_use = 0;
   bool anon = !name;
 
   timevar_push (TV_NAME_LOOKUP);
-  
+
   /* We should not get here if the global_namespace is not yet constructed
      nor if NAME designates the global namespace:  The global scope is
      constructed elsewhere.  */
@@ -3083,14 +3011,14 @@ push_namespace (tree name)
   if (anon)
     {
       /* The name of anonymous namespace is unique for the translation
-         unit.  */
+        unit.  */
       if (!anonymous_namespace_name)
-        anonymous_namespace_name = get_file_function_name ('N');
+       anonymous_namespace_name = get_file_function_name ('N');
       name = anonymous_namespace_name;
       d = IDENTIFIER_NAMESPACE_VALUE (name);
       if (d)
-        /* Reopening anonymous namespace.  */
-        need_new = 0;
+       /* Reopening anonymous namespace.  */
+       need_new = 0;
       implicit_use = 1;
     }
   else
@@ -3098,15 +3026,15 @@ push_namespace (tree name)
       /* Check whether this is an extended namespace definition.  */
       d = IDENTIFIER_NAMESPACE_VALUE (name);
       if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
-        {
-          need_new = 0;
-          if (DECL_NAMESPACE_ALIAS (d))
-            {
-              error ("namespace alias %qD not allowed here, assuming %qD",
-                     d, DECL_NAMESPACE_ALIAS (d));
-              d = DECL_NAMESPACE_ALIAS (d);
-            }
-        }
+       {
+         need_new = 0;
+         if (DECL_NAMESPACE_ALIAS (d))
+           {
+             error ("namespace alias %qD not allowed here, assuming %qD",
+                    d, DECL_NAMESPACE_ALIAS (d));
+             d = DECL_NAMESPACE_ALIAS (d);
+           }
+       }
     }
 
   if (need_new)
@@ -3114,6 +3042,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)
        {
@@ -3131,6 +3065,38 @@ push_namespace (tree name)
   /* Enter the name space.  */
   current_namespace = d;
 
+#ifdef HANDLE_PRAGMA_VISIBILITY
+  /* Clear has_visibility in case a previous namespace-definition had a
+     visibility attribute and this one doesn't.  */
+  current_binding_level->has_visibility = 0;
+  for (d = attributes; d; d = TREE_CHAIN (d))
+    {
+      tree name = TREE_PURPOSE (d);
+      tree args = TREE_VALUE (d);
+      tree x;
+
+      if (! is_attribute_p ("visibility", name))
+       {
+         warning (OPT_Wattributes, "%qs attribute directive ignored",
+                  IDENTIFIER_POINTER (name));
+         continue;
+       }
+
+      x = args ? TREE_VALUE (args) : NULL_TREE;
+      if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
+       {
+         warning (OPT_Wattributes, "%qs attribute requires a single NTBS argument",
+                  IDENTIFIER_POINTER (name));
+         continue;
+       }
+
+      current_binding_level->has_visibility = 1;
+      push_visibility (TREE_STRING_POINTER (x));
+      goto found;
+    }
+ found:
+#endif
+
   timevar_pop (TV_NAME_LOOKUP);
 }
 
@@ -3185,7 +3151,7 @@ push_decl_namespace (tree decl)
   if (TREE_CODE (decl) != NAMESPACE_DECL)
     decl = decl_namespace_context (decl);
   decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
-                                   NULL_TREE, decl_namespace_list);
+                                  NULL_TREE, decl_namespace_list);
 }
 
 /* [namespace.memdef]/2 */
@@ -3196,7 +3162,7 @@ pop_decl_namespace (void)
   decl_namespace_list = TREE_CHAIN (decl_namespace_list);
 }
 
-/* Return the namespace that is the common ancestor 
+/* Return the namespace that is the common ancestor
    of two given namespaces.  */
 
 static tree
@@ -3206,7 +3172,7 @@ namespace_ancestor (tree ns1, tree ns2)
   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));
+                         namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
 }
 
 /* Process a namespace-alias declaration.  */
@@ -3214,17 +3180,15 @@ 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);
 
   /* Build the alias.  */
-  alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);     
+  alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
   DECL_NAMESPACE_ALIAS (alias) = namespace;
   DECL_EXTERNAL (alias) = 1;
   DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
@@ -3238,44 +3202,44 @@ 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.  */
-  if (TREE_CODE (x) == TYPE_DECL)
+  if (TREE_CODE (t) == TYPE_DECL)
     {
-      tree name = DECL_NAME (x);
+      tree name = DECL_NAME (t);
       tree newval;
       tree *ptr = (tree *)0;
       for (; !global_scope_p (b); b = b->level_chain)
-        {
-          tree shadowed = b->type_shadowed;
-          for (; shadowed; shadowed = TREE_CHAIN (shadowed))
-            if (TREE_PURPOSE (shadowed) == name)
-              {
+       {
+         tree shadowed = b->type_shadowed;
+         for (; shadowed; shadowed = TREE_CHAIN (shadowed))
+           if (TREE_PURPOSE (shadowed) == name)
+             {
                ptr = &TREE_VALUE (shadowed);
                /* Can't break out of the loop here because sometimes
                   a binding level will have duplicate bindings for
                   PT names.  It's gross, but I haven't time to fix it.  */
-              }
-        }
-      newval = TREE_TYPE (x);
+             }
+       }
+      newval = TREE_TYPE (t);
       if (ptr == (tree *)0)
-        {
-          /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
-             up here if this is changed to an assertion.  --KR  */
-         SET_IDENTIFIER_TYPE_VALUE (name, x);
+       {
+         /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
+            up here if this is changed to an assertion.  --KR  */
+         SET_IDENTIFIER_TYPE_VALUE (name, t);
        }
       else
-        {
+       {
          *ptr = newval;
-        }
+       }
     }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
@@ -3283,7 +3247,7 @@ pushdecl_namespace_level (tree x)
 /* 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 
+static void
 add_using_namespace (tree user, tree used, bool indirect)
 {
   tree t;
@@ -3308,8 +3272,8 @@ add_using_namespace (tree user, tree used, bool indirect)
     }
 
   /* Add used to the user's using list.  */
-  DECL_NAMESPACE_USING (user) 
-    = tree_cons (used, namespace_ancestor (user, used), 
+  DECL_NAMESPACE_USING (user)
+    = tree_cons (used, namespace_ancestor (user, used),
                 DECL_NAMESPACE_USING (user));
 
   TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
@@ -3341,7 +3305,7 @@ do_toplevel_using_decl (tree decl, tree scope, tree name)
   decl = validate_nonmember_using_decl (decl, scope, name);
   if (decl == NULL_TREE)
     return;
-  
+
   binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
 
   oldval = binding->value;
@@ -3358,7 +3322,6 @@ do_toplevel_using_decl (tree decl, tree scope, tree name)
     binding->value = newval;
   if (newtype)
     binding->type = newtype;
-  return;
 }
 
 /* Process a using-directive.  */
@@ -3368,26 +3331,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);
@@ -3400,7 +3352,7 @@ do_using_directive (tree namespace)
       if (current_namespace != global_namespace)
        context = current_namespace;
     }
-      
+
   /* Emit debugging info.  */
   if (!processing_template_decl)
     (*debug_hooks->imported_module_or_decl) (namespace, context);
@@ -3424,12 +3376,17 @@ 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 ("%qD attribute directive ignored", name);
+       warning (OPT_Wattributes, "%qD attribute directive ignored", name);
     }
 }
 
@@ -3438,13 +3395,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);
 }
@@ -3454,7 +3411,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
@@ -3464,7 +3429,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
@@ -3490,12 +3455,12 @@ merge_functions (tree s1, tree s2)
             need to add it again.  For `extern "C"' functions, we
             might have two FUNCTION_DECLs for the same function, in
             different namespaces; again, we only need one of them.  */
-         if (fn1 == fn2 
+         if (fn1 == fn2
              || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
                  && DECL_NAME (fn1) == DECL_NAME (fn2)))
            break;
        }
-      
+
       /* If we exhausted all of the functions in S1, FN2 is new.  */
       if (!fns1)
        s1 = build_overload (fn2, s1);
@@ -3523,52 +3488,42 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
     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;
+       /* 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))
-          val = NULL_TREE;
-        break;
+       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;
+       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) || DECL_ANTICIPATED (val))
-          val = NULL_TREE;
-        break;
+       /* 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 (LOOKUP_QUALIFIERS_ONLY (flags))
+         val = NULL_TREE;
       }
-        
+
   if (!old->value)
     old->value = val;
   else if (val && val != old->value)
     {
       if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
-        old->value = merge_functions (old->value, val);
+       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);
-                 cp_error_at ("  first declared as %q#D here", old->value);
-               }
-              cp_error_at ("  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, new->value));
+         TREE_TYPE (old->value) = error_mark_node;
        }
     }
   /* ... and copy the type.  */
@@ -3580,11 +3535,11 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
   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));
-        }
+       {
+         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));
+       }
     }
 }
 
@@ -3611,100 +3566,67 @@ lookup_flags (int prefer_type, int namespaces_only)
 }
 
 /* Given a lookup that returned VAL, use FLAGS to decide if we want to
-   ignore it or not.  Subroutine of lookup_name_real.  */
+   ignore it or not.  Subroutine of lookup_name_real and
+   lookup_type_scope.  */
 
-static tree
+static bool
 qualify_lookup (tree val, int flags)
 {
   if (val == NULL_TREE)
-    return val;
+    return false;
   if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
-    return val;
+    return true;
   if ((flags & LOOKUP_PREFER_TYPES)
       && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
-    return val;
+    return true;
   if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
-    return NULL_TREE;
-  return val;
+    return false;
+  return true;
 }
 
-/* Look up NAME in the NAMESPACE.  */
+/* Given a lookup that returned VAL, decide if we want to ignore it or
+   not based on DECL_ANTICIPATED.  */
 
-tree
-lookup_namespace_name (tree namespace, tree name)
+bool
+hidden_name_p (tree val)
 {
-  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 (TREE_CODE (name) == TEMPLATE_ID_EXPR)
-    {
-      template_id = name;
-      name = TREE_OPERAND (name, 0);
-      if (TREE_CODE (name) == OVERLOAD)
-       name = DECL_NAME (OVL_CURRENT (name));
-      else if (DECL_P (name))
-       name = DECL_NAME (name);
-    }
+  if (DECL_P (val)
+      && DECL_LANG_SPECIFIC (val)
+      && DECL_ANTICIPATED (val))
+    return true;
+  return false;
+}
 
-  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+/* Remove any hidden friend functions from a possibly overloaded set
+   of functions.  */
 
-  if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
-    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+tree
+remove_hidden_names (tree fns)
+{
+  if (!fns)
+    return fns;
 
-  if (binding.value)
+  if (TREE_CODE (fns) == FUNCTION_DECL && hidden_name_p (fns))
+    fns = NULL_TREE;
+  else if (TREE_CODE (fns) == OVERLOAD)
     {
-      val = binding.value;
+      tree o;
 
-      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);
+         tree n = NULL_TREE;
 
-      /* Ignore built-in functions that haven't been prototyped yet.  */
-      if (!val || !DECL_P(val)
-          || !DECL_LANG_SPECIFIC(val)
-          || !DECL_ANTICIPATED (val))
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+         for (o = fns; o; o = OVL_NEXT (o))
+           if (!hidden_name_p (OVL_CURRENT (o)))
+             n = build_overload (OVL_CURRENT (o), n);
+         fns = n;
+       }
     }
 
-  error ("%qD undeclared in namespace %qD", name, namespace);
-  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+  return fns;
 }
 
 /* Select the right _DECL from multiple choices.  */
@@ -3719,8 +3641,9 @@ select_decl (const struct scope_binding *binding, int flags)
   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);
+      if (val && (TREE_CODE (val) == NAMESPACE_DECL
+                 || TREE_CODE (val) == TREE_LIST))
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
     }
 
@@ -3729,7 +3652,7 @@ select_decl (const struct scope_binding *binding, int flags)
   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) 
+  else if (val && LOOKUP_TYPES_ONLY (flags)
           && ! DECL_DECLARES_TYPE_P (val))
     val = NULL_TREE;
 
@@ -3754,14 +3677,12 @@ unqualified_namespace_lookup (tree name, int flags)
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
       cxx_binding *b =
-         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+        cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
 
       if (b)
        {
-         if (b->value && DECL_P (b->value)
-             && DECL_LANG_SPECIFIC (b->value) 
-             && DECL_ANTICIPATED (b->value))
-           /* Ignore anticipated built-in functions.  */
+         if (b->value && hidden_name_p (b->value))
+           /* Ignore anticipated built-in functions and friends.  */
            ;
          else
            binding.value = b->value;
@@ -3773,7 +3694,7 @@ unqualified_namespace_lookup (tree name, int flags)
           level->kind != sk_namespace;
           level = level->level_chain)
        if (!lookup_using_namespace (name, &binding, level->using_directives,
-                                     scope, flags))
+                                    scope, flags))
          /* Give up because of error.  */
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
@@ -3783,7 +3704,7 @@ unqualified_namespace_lookup (tree name, int flags)
       while (1)
        {
          if (!lookup_using_namespace (name, &binding,
-                                       DECL_NAMESPACE_USING (siter),
+                                      DECL_NAMESPACE_USING (siter),
                                       scope, flags))
            /* Give up because of error.  */
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@@ -3800,7 +3721,7 @@ unqualified_namespace_lookup (tree name, int flags)
 
 /* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
    or a class TYPE).  If IS_TYPE_P is TRUE, then ignore non-type
-   bindings.  
+   bindings.
 
    Returns a DECL (or OVERLOAD, or BASELINK) representing the
    declaration found.  If no suitable declaration can be found,
@@ -3811,6 +3732,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)
     {
@@ -3820,17 +3742,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 = select_decl (&binding, flags);
     }
   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:
@@ -3851,12 +3770,12 @@ lookup_using_namespace (tree name, struct scope_binding *val,
   for (iter = usings; iter; iter = TREE_CHAIN (iter))
     if (TREE_VALUE (iter) == scope)
       {
-        tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
-        cxx_binding *val1 =
-          cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
-        /* Resolve ambiguities.  */
-        if (val1)
-          ambiguous_decl (name, val, val1, flags);
+       tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
+       cxx_binding *val1 =
+         cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+       /* Resolve ambiguities.  */
+       if (val1)
+         ambiguous_decl (name, val, val1, flags);
       }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
 }
@@ -3885,7 +3804,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 (name, result, binding, flags);
 
       /* Consider strong using directives always, and non-strong ones
         if we haven't found a binding yet.  ??? Shouldn't we consider
@@ -3935,7 +3854,7 @@ qualified_lookup_using_namespace (tree name, tree scope,
    CLASS_P is false, then class bindings are ignored.  */
 
 cxx_binding *
-outer_binding (tree name, 
+outer_binding (tree name,
               cxx_binding *binding,
               bool class_p)
 {
@@ -3962,10 +3881,10 @@ outer_binding (tree name,
   if (class_p)
     while (scope && scope != outer_scope && scope->kind != sk_namespace)
       {
-       if (scope->kind == sk_class) 
+       if (scope->kind == sk_class)
          {
            cxx_binding *class_binding;
-           
+
            class_binding = get_class_binding (name, scope);
            if (class_binding)
              {
@@ -4002,6 +3921,8 @@ innermost_non_namespace_value (tree name)
    node of some kind representing its definition if there is only one
    such declaration, or return a TREE_LIST with all the overloaded
    definitions if there are many, or return 0 if it is undefined.
+   Hidden name, either friend declaration or built-in function, are
+   not ignored.
 
    If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
    If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
@@ -4021,22 +3942,22 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
   /* Conversion operators are handled specially because ordinary
      unqualified name lookup will not find template conversion
      operators.  */
-  if (IDENTIFIER_TYPENAME_P (name)) 
+  if (IDENTIFIER_TYPENAME_P (name))
     {
       struct cp_binding_level *level;
 
-      for (level = current_binding_level; 
+      for (level = current_binding_level;
           level && level->kind != sk_namespace;
           level = level->level_chain)
        {
          tree class_type;
          tree operators;
-         
-         /* A conversion operator can only be declared in a class 
+
+         /* A conversion operator can only be declared in a class
             scope.  */
          if (level->kind != sk_class)
            continue;
-         
+
          /* Lookup the conversion operator in the class.  */
          class_type = level->this_entity;
          operators = lookup_fnfields (class_type, name, /*protect=*/0);
@@ -4060,20 +3981,22 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
         iter = outer_binding (name, iter, !nonclass))
       {
        tree binding;
-       
+
        /* Skip entities we don't want.  */
        if (LOCAL_BINDING_P (iter) ? !block_p : nonclass)
          continue;
-       
+
        /* If this is the kind of thing we're looking for, we're done.  */
-       if (qualify_lookup (iter->value, flags))
+       if (qualify_lookup (iter->value, flags)
+           && !hidden_name_p (iter->value))
          binding = iter->value;
        else if ((flags & LOOKUP_PREFER_TYPES)
-                && qualify_lookup (iter->type, flags))
+                && qualify_lookup (iter->type, flags)
+                && !hidden_name_p (iter->type))
          binding = iter->type;
        else
          binding = NULL_TREE;
-       
+
        if (binding)
          {
            val = binding;
@@ -4083,18 +4006,11 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
 
   /* Now lookup in namespace scopes.  */
   if (!val)
-    {
-      tree t = unqualified_namespace_lookup (name, flags);
-      if (t)
-       val = t;
-    }
+    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);
 }
@@ -4108,30 +4024,43 @@ lookup_name_nonclass (tree name)
 tree
 lookup_function_nonclass (tree name, tree args, bool block_p)
 {
-  return 
-    lookup_arg_dependent (name, 
-                         lookup_name_real (name, 0, 1, block_p, 0, 
+  return
+    lookup_arg_dependent (name,
+                         lookup_name_real (name, 0, 1, block_p, 0,
                                            LOOKUP_COMPLAIN),
                          args);
 }
 
 tree
-lookup_name (tree name, int prefer_type)
+lookup_name (tree name)
 {
-  return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, 
+  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);
 }
 
 /* Look up NAME for type used in elaborated name specifier in
-   the current scope (possibly more if cleanup or template parameter
-   scope is encounter).  Unlike lookup_name_real, we make sure that
-   NAME is actually declared in the desired scope, not from inheritance,
-   using declaration, nor using directive.  A TYPE_DECL best matching
-   the NAME is returned.  Catching error and issuing diagnostics are
-   caller's responsibility.  */
+   the scopes given by SCOPE.  SCOPE can be either TS_CURRENT or
+   TS_WITHIN_ENCLOSING_NON_CLASS.  Although not implied by the
+   name, more scopes are checked if cleanup or template parameter
+   scope is encountered.
+
+   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 an earlier friend
+   declaration is also returned.
+
+   A TYPE_DECL best matching the NAME is returned.  Catching error
+   and issuing diagnostics are caller's responsibility.  */
 
 tree
-lookup_type_scope (tree name)
+lookup_type_scope (tree name, tag_scope scope)
 {
   cxx_binding *iter = NULL;
   tree val = NULL_TREE;
@@ -4144,19 +4073,22 @@ lookup_type_scope (tree name)
   for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true))
     {
       /* Check if this is the kind of thing we're looking for.
-        Make sure it doesn't come from base class.  For ITER->VALUE,
-        we can simply use INHERITED_VALUE_BINDING_P.  For ITER->TYPE,
-        we have to use our own check.
+        If SCOPE is TS_CURRENT, also make sure it doesn't come from
+        base class.  For ITER->VALUE, we can simply use
+        INHERITED_VALUE_BINDING_P.  For ITER->TYPE, we have to use
+        our own check.
 
         We check ITER->TYPE before ITER->VALUE in order to handle
           typedef struct C {} C;
         correctly.  */
 
       if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES)
-         && (LOCAL_BINDING_P (iter)
+         && (scope != ts_current
+             || LOCAL_BINDING_P (iter)
              || DECL_CONTEXT (iter->type) == iter->scope->this_entity))
        val = iter->type;
-      else if (!INHERITED_VALUE_BINDING_P (iter)
+      else if ((scope != ts_current
+               || !INHERITED_VALUE_BINDING_P (iter))
               && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
        val = iter->value;
 
@@ -4178,10 +4110,10 @@ lookup_type_scope (tree name)
          else if (qualify_lookup (iter->value, LOOKUP_PREFER_TYPES))
            val = iter->value;
        }
-       
+
     }
 
-  /* Type found, check if it is in the current scope, ignoring cleanup
+  /* Type found, check if it is in the allowed scopes, ignoring cleanup
      and template parameter scopes.  */
   if (val)
     {
@@ -4193,6 +4125,9 @@ lookup_type_scope (tree name)
 
          if (b->kind == sk_cleanup || b->kind == sk_template_parms)
            b = b->level_chain;
+         else if (b->kind == sk_class
+                  && scope == ts_within_enclosing_non_class)
+           b = b->level_chain;
          else
            break;
        }
@@ -4261,7 +4196,7 @@ lookup_type_current_level (tree name)
        {
          if (purpose_member (name, b->type_shadowed))
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
-                                    REAL_IDENTIFIER_TYPE_VALUE (name));
+                                   REAL_IDENTIFIER_TYPE_VALUE (name));
          if (b->kind == sk_cleanup)
            b = b->level_chain;
          else
@@ -4278,6 +4213,7 @@ lookup_type_current_level (tree name)
 struct arg_lookup
 {
   tree name;
+  tree args;
   tree namespaces;
   tree classes;
   tree functions;
@@ -4305,7 +4241,7 @@ add_function (struct arg_lookup *k, tree fn)
      case.  */
 
   /* We must find only functions, or exactly one non-function.  */
-  if (!k->functions) 
+  if (!k->functions)
     k->functions = fn;
   else if (fn == k->functions)
     ;
@@ -4319,8 +4255,8 @@ add_function (struct arg_lookup *k, tree fn)
        {
          fn = f1; f1 = f2; f2 = fn;
        }
-      cp_error_at ("%qD is not a function,", f1);
-      cp_error_at ("  conflict with %qD", f2);
+      error ("%q+D is not a function,", f1);
+      error ("  conflict with %q+D", f2);
       error ("  in call to %qD", k->name);
       return true;
     }
@@ -4356,6 +4292,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.  */
 
@@ -4373,15 +4356,32 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
        value = TREE_CHAIN (value))
     if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
       return true;
-  
+
   value = namespace_binding (k->name, scope);
   if (!value)
     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;
 }
 
@@ -4412,10 +4412,10 @@ arg_assoc_template_arg (struct arg_lookup *k, tree arg)
 
       /* It's not a member template.  */
       if (TREE_CODE (ctx) == NAMESPACE_DECL)
-        return arg_assoc_namespace (k, ctx);
+       return arg_assoc_namespace (k, ctx);
       /* Otherwise, it must be member template.  */
-      else 
-        return arg_assoc_class (k, ctx);
+      else
+       return arg_assoc_class (k, ctx);
     }
   /* It's not a template template argument, but it is a type template
      argument.  */
@@ -4434,7 +4434,7 @@ arg_assoc_class (struct arg_lookup *k, tree type)
 {
   tree list, friends, context;
   int i;
-  
+
   /* Backend build structures, such as __builtin_va_list, aren't
      affected by all this.  */
   if (!CLASS_TYPE_P (type))
@@ -4443,7 +4443,7 @@ arg_assoc_class (struct arg_lookup *k, tree type)
   if (purpose_member (type, k->classes))
     return false;
   k->classes = tree_cons (type, NULL_TREE, k->classes);
-  
+
   context = decl_namespace_context (type);
   if (arg_assoc_namespace (k, context))
     return true;
@@ -4452,18 +4452,18 @@ arg_assoc_class (struct arg_lookup *k, tree type)
     {
       /* Process baseclasses.  */
       tree binfo, base_binfo;
-      
+
       for (binfo = TYPE_BINFO (type), i = 0;
           BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
        if (arg_assoc_class (k, BINFO_TYPE (base_binfo)))
          return true;
     }
-  
+
   /* Process friends.  */
-  for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
+  for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
        list = TREE_CHAIN (list))
     if (k->name == FRIEND_NAME (list))
-      for (friends = FRIEND_DECLS (list); friends; 
+      for (friends = FRIEND_DECLS (list); friends;
           friends = TREE_CHAIN (friends))
        {
          tree fn = TREE_VALUE (friends);
@@ -4482,12 +4482,12 @@ arg_assoc_class (struct arg_lookup *k, tree type)
        }
 
   /* Process template arguments.  */
-  if (CLASSTYPE_TEMPLATE_INFO (type) 
+  if (CLASSTYPE_TEMPLATE_INFO (type)
       && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
     {
       list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
-      for (i = 0; i < TREE_VEC_LENGTH (list); ++i) 
-        arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
+      for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
+       arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
     }
 
   return false;
@@ -4520,7 +4520,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:
@@ -4608,8 +4607,8 @@ arg_assoc (struct arg_lookup *k, tree n)
       int ix;
 
       if (TREE_CODE (template) == COMPONENT_REF)
-        template = TREE_OPERAND (template, 1);
-      
+       template = TREE_OPERAND (template, 1);
+
       /* First, the template.  There may actually be more than one if
         this is an overloaded function template.  But, in that case,
         we only need the first; all the functions will be in the same
@@ -4617,7 +4616,7 @@ arg_assoc (struct arg_lookup *k, tree n)
       template = OVL_CURRENT (template);
 
       ctx = CP_DECL_CONTEXT (template);
-       
+
       if (TREE_CODE (ctx) == NAMESPACE_DECL)
        {
          if (arg_assoc_namespace (k, ctx) == 1)
@@ -4628,9 +4627,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)
     {
@@ -4649,34 +4649,25 @@ tree
 lookup_arg_dependent (tree name, tree fns, tree args)
 {
   struct arg_lookup k;
-  tree fn = NULL_TREE;
 
   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;
 
-  /* We've already looked at some namespaces during normal unqualified
-     lookup -- but we don't know exactly which ones.  If the functions
-     we found were brought into the current namespace via a using
-     declaration, we have not really checked the namespace from which
-     they came.  Therefore, we check all namespaces here -- unless the
-     function we have is from the current namespace.  Even then, we
-     must check all namespaces if the function is a local
-     declaration; any other declarations present at namespace scope
-     should be visible during argument-dependent lookup.  */
-  if (fns)
-    fn = OVL_CURRENT (fns);
-  if (fn && TREE_CODE (fn) == FUNCTION_DECL 
-      && (CP_DECL_CONTEXT (fn) != current_decl_namespace ()
-         || DECL_LOCAL_FUNCTION_P (fn)))
-    k.namespaces = NULL_TREE;
-  else
-    /* Setting NAMESPACES is purely an optimization; it prevents
-       adding functions which are already in FNS.  Adding them would
-       be safe -- "joust" will eliminate the duplicates -- but
-       wasteful.  */
-    k.namespaces = build_tree_list (current_decl_namespace (), NULL_TREE);
+  /* We previously performed an optimization here by setting
+     NAMESPACES to the current namespace when it was safe. However, DR
+     164 says that namespaces that were already searched in the first
+     stage of template processing are searched again (potentially
+     picking up later definitions) in the second stage. */
+  k.namespaces = NULL_TREE;
 
   arg_assoc_args (&k, args);
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
@@ -4719,8 +4710,8 @@ push_using_directive (tree used)
    processing.  */
 
 static tree
-maybe_process_template_type_declaration (tree type, int globalize,
-                                         cxx_scope *b)
+maybe_process_template_type_declaration (tree type, int is_friend,
+                                        cxx_scope *b)
 {
   tree decl = TYPE_NAME (type);
 
@@ -4728,14 +4719,17 @@ maybe_process_template_type_declaration (tree type, int globalize,
     /* You can't declare a new template type in a template parameter
        list.  But, you can declare a non-template type:
 
-         template <class A*> struct S;
+        template <class A*> struct S;
 
        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
     {
-      maybe_check_template_type (type);
-
       gcc_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE);
 
       if (processing_template_decl)
@@ -4744,7 +4738,7 @@ maybe_process_template_type_declaration (tree type, int globalize,
             push_template_decl_real, but we want the original value.  */
          tree name = DECL_NAME (decl);
 
-         decl = push_template_decl_real (decl, globalize);
+         decl = push_template_decl_real (decl, is_friend);
          /* If the current binding level is the binding level for the
             template parameters (see the comment in
             begin_template_parm_list) and the enclosing level is a class
@@ -4753,23 +4747,22 @@ maybe_process_template_type_declaration (tree type, int globalize,
             friend case, push_template_decl will already have put the
             friend into global scope, if appropriate.  */
          if (TREE_CODE (type) != ENUMERAL_TYPE
-             && !globalize && b->kind == sk_template_parms
+             && !is_friend && b->kind == sk_template_parms
              && b->level_chain->kind == sk_class)
            {
              finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
-             /* Put this UDT in the table of UDTs for the class, since
-                that won't happen below because B is not the class
-                binding level, but is instead the pseudo-global level.  */
-              if (b->level_chain->type_decls == NULL)
-                b->level_chain->type_decls =
-                  binding_table_new (SCOPE_DEFAULT_HT_SIZE);
-              binding_table_insert (b->level_chain->type_decls, name, type);
+
              if (!COMPLETE_TYPE_P (current_class_type))
                {
                  maybe_add_class_template_decl_list (current_class_type,
                                                      type, /*friend_p=*/0);
-                 CLASSTYPE_NESTED_UTDS (current_class_type) =
-                    b->level_chain->type_decls;
+                 /* 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);
+
+                 binding_table_insert
+                   (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
                }
            }
        }
@@ -4778,15 +4771,26 @@ maybe_process_template_type_declaration (tree type, int globalize,
   return decl;
 }
 
-/* Push a tag name NAME for struct/class/union/enum type TYPE.
-   Normally put it into the inner-most non-sk_cleanup scope,
-   but if GLOBALIZE is true, put it in the inner-most non-class scope.
-   The latter is needed for implicit declarations.  */
+/* Push a tag name NAME for struct/class/union/enum type TYPE.  In case
+   that the NAME is a class template, the tag is processed but not pushed.
 
-void
-pushtag (tree name, tree type, int globalize)
+   The pushed scope depend on the SCOPE parameter:
+   - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
+     scope.
+   - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
+     non-template-parameter scope.  This case is needed for forward
+     declarations.
+   - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
+     TS_GLOBAL case except that names within template-parameter scopes
+     are not pushed at all.
+
+   Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
+
+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;
@@ -4796,12 +4800,11 @@ pushtag (tree name, tree type, int globalize)
         /* Neither are the scopes used to hold template parameters
            for an explicit specialization.  For an ordinary template
            declaration, these scopes are not scopes from the point of
-           view of the language -- but we need a place to stash
-           things that will go in the containing namespace when the
-           template is instantiated.  */
-        || (b->kind == sk_template_parms && b->explicit_spec_p)
+           view of the language.  */
+        || (b->kind == sk_template_parms
+            && (b->explicit_spec_p || scope == ts_global))
         || (b->kind == sk_class
-            && (globalize
+            && (scope != ts_current
                 /* We may be defining a new type in the initializer
                    of a static member variable. We allow this when
                    not pedantic, and it is particularly useful for
@@ -4809,106 +4812,112 @@ pushtag (tree name, tree type, int globalize)
                 || COMPLETE_TYPE_P (b->this_entity))))
     b = b->level_chain;
 
-  if (b->type_decls == NULL)
-    b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
-  binding_table_insert (b->type_decls, name, type);
+  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
 
-  if (name)
+  /* 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);
-
-         if (! context)
-           {
-             tree cs = current_scope ();
-
-             if (! globalize)
-               context = cs;
-             else if (cs != NULL_TREE && TYPE_P (cs))
-               /* When declaring a friend class of a local class, we want
-                  to inject the newly named class into the scope
-                  containing the local class, not the namespace scope.  */
-               context = decl_function_context (get_type_decl (cs));
-           }
-         if (!context)
-           context = current_namespace;
+      tree tdef;
+      int in_class = 0;
+      tree context = TYPE_CONTEXT (type);
 
-         if (b->kind == sk_class
-             || (b->kind == sk_template_parms 
-                 && b->level_chain->kind == sk_class))
-           in_class = 1;
+      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 (current_lang_name == lang_name_java)
-           TYPE_FOR_JAVA (type) = 1;
+      if (b->kind == sk_class
+         || (b->kind == sk_template_parms
+             && b->level_chain->kind == sk_class))
+       in_class = 1;
 
-         d = create_implicit_typedef (name, type);
-         DECL_CONTEXT (d) = FROB_CONTEXT (context);
-         if (! in_class)
-           set_identifier_type_value_with_scope (name, d, b);
+      if (current_lang_name == lang_name_java)
+       TYPE_FOR_JAVA (type) = 1;
 
-         d = maybe_process_template_type_declaration (type,
-                                                      globalize, b);
+      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 (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);
-           }
+      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);
+
+      if (! in_class)
+       set_identifier_type_value_with_scope (name, tdef, b);
+
+      if (b->kind == sk_class)
+       {
+         if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+           /* Put this TYPE_DECL on the TYPE_FIELDS list for the
+              class.  But if it's a member template class, we want
+              the TEMPLATE_DECL, not the TYPE_DECL, so this is done
+              later.  */
+           finish_member_declaration (decl);
          else
-           d = pushdecl_with_scope (d, b);
-
-         /* FIXME what if it gets a name from typedef?  */
-         if (ANON_AGGRNAME_P (name))
-           DECL_IGNORED_P (d) = 1;
-
-         TYPE_CONTEXT (type) = DECL_CONTEXT (d);
-
-         /* If this is a local class, keep track of it.  We need this
-            information for name-mangling, and so that it is possible to find
-            all function definitions in a translation unit in a convenient
-            way.  (It's otherwise tricky to find a member function definition
-            it's only pointed to from within a local class.)  */
-         if (TYPE_CONTEXT (type)
-             && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
-             && !processing_template_decl)
-           VARRAY_PUSH_TREE (local_classes, type);
-        }
-      if (b->kind == sk_class
-         && !COMPLETE_TYPE_P (current_class_type))
+           pushdecl_class_level (decl);
+       }
+      else if (b->kind != sk_template_parms)
        {
-         maybe_add_class_template_decl_list (current_class_type,
-                                             type, /*friend_p=*/0);
-         CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
+         decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
+         if (decl == error_mark_node)
+           POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, 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
+      TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
+
+      /* 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))
     {
-      /* 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);
+      maybe_add_class_template_decl_list (current_class_type,
+                                         type, /*friend_p=*/0);
+
+      if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
+       CLASSTYPE_NESTED_UTDS (current_class_type)
+         = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+
+      binding_table_insert
+       (CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
     }
-  timevar_pop (TV_NAME_LOOKUP);
+
+  decl = TYPE_NAME (type);
+  gcc_assert (TREE_CODE (decl) == TYPE_DECL);
+  TYPE_STUB_DECL (type) = decl;
+
+  /* Set type visibility now if this is a forward declaration.  */
+  TREE_PUBLIC (decl) = 1;
+  determine_visibility (decl);
+
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
 }
 \f
 /* Subroutines for reverting temporarily to top-level for instantiation
@@ -4922,7 +4931,7 @@ struct saved_scope *scope_chain;
    *OLD_BINDINGS.  */
 
 static void
-store_binding (tree id, VEC(cxx_saved_binding) **old_bindings)
+store_binding (tree id, VEC(cxx_saved_binding,gc) **old_bindings)
 {
   cxx_saved_binding *saved;
 
@@ -4931,10 +4940,10 @@ store_binding (tree id, VEC(cxx_saved_binding) **old_bindings)
 
   if (IDENTIFIER_MARKED (id))
     return;
-  
+
   IDENTIFIER_MARKED (id) = 1;
 
-  saved = VEC_safe_push (cxx_saved_binding, *old_bindings, NULL);
+  saved = VEC_safe_push (cxx_saved_binding, gc, *old_bindings, NULL);
   saved->identifier = id;
   saved->binding = IDENTIFIER_BINDING (id);
   saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
@@ -4942,7 +4951,7 @@ store_binding (tree id, VEC(cxx_saved_binding) **old_bindings)
 }
 
 static void
-store_bindings (tree names, VEC(cxx_saved_binding) **old_bindings)
+store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings)
 {
   tree t;
 
@@ -4965,8 +4974,8 @@ store_bindings (tree names, VEC(cxx_saved_binding) **old_bindings)
    objects, rather than a TREE_LIST.  */
 
 static void
-store_class_bindings (VEC(cp_class_binding) *names, 
-                     VEC(cxx_saved_binding) **old_bindings)
+store_class_bindings (VEC(cp_class_binding,gc) *names,
+                     VEC(cxx_saved_binding,gc) **old_bindings)
 {
   size_t i;
   cp_class_binding *cb;
@@ -5035,12 +5044,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;
-  VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
+  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);
 }
 
@@ -5051,10 +5063,11 @@ pop_from_top_level (void)
   cxx_saved_binding *saved;
   size_t i;
 
-  timevar_push (TV_NAME_LOOKUP); 
+  timevar_push (TV_NAME_LOOKUP);
   /* Clear out class-level bindings cache.  */
   if (previous_class_level)
     invalidate_class_lookup_cache ();
+  pop_class_stack ();
 
   current_lang_base = 0;
 
@@ -5072,6 +5085,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);
 }
 
@@ -5096,15 +5110,19 @@ pop_everything (void)
 }
 
 /* Emit debugging information for using declarations and directives.
-   If input tree is overloaded fn then emit debug info for all 
+   If input tree is overloaded fn then emit debug info for all
    candidates.  */
 
-static void
+void
 cp_emit_debug_info_for_using (tree t, tree context)
 {
-  /* Ignore this FUNCTION_DECL if it refers to a builtin declaration 
+  /* 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 
+  if (TREE_CODE (t) == FUNCTION_DECL
       && DECL_EXTERNAL (t)
       && DECL_BUILT_IN (t))
     return;
@@ -5113,14 +5131,14 @@ cp_emit_debug_info_for_using (tree t, tree context)
      it is a global namespace.  */
   if (context == global_namespace)
     context = NULL_TREE;
-  
+
   if (BASELINK_P (t))
     t = BASELINK_FUNCTIONS (t);
-  
+
   /* FIXME: Handle TEMPLATE_DECLs.  */
   for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
     if (TREE_CODE (t) != TEMPLATE_DECL)
       (*debug_hooks->imported_module_or_decl) (t, context);
-  }
+}
 
 #include "gt-cp-name-lookup.h"