OSDN Git Service

/cp
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 7fe4012..db3956b 100644 (file)
@@ -82,6 +82,19 @@ static tree cur_stmt_expr;
    local variables.  */
 static htab_t local_specializations;
 
+typedef struct GTY(()) spec_entry
+{
+  tree tmpl;
+  tree args;
+  tree spec;
+} spec_entry;
+
+static GTY ((param_is (spec_entry)))
+  htab_t decl_specializations;
+
+static GTY ((param_is (spec_entry)))
+  htab_t type_specializations;
+
 /* Contains canonical template parameter types. The vector is indexed by
    the TEMPLATE_TYPE_IDX of the template parameter. Each element is a
    TREE_LIST, whose TREE_VALUEs contain the canonical template
@@ -133,6 +146,7 @@ static bool inline_needs_template_parms (tree);
 static void push_inline_template_parms_recursive (tree, int);
 static tree retrieve_local_specialization (tree);
 static void register_local_specialization (tree, tree);
+static hashval_t hash_specialization (const void *p);
 static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t);
 static int mark_template_parm (tree, void *);
 static int template_parm_this_level_p (tree, void *);
@@ -175,7 +189,11 @@ static tree tsubst_copy    (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_decl (tree, tree, tsubst_flags_t);
 static void perform_typedefs_access_check (tree tmpl, tree targs);
-static void append_type_to_template_for_access_check_1 (tree, tree, tree);
+static void append_type_to_template_for_access_check_1 (tree, tree, tree,
+                                                       location_t);
+static hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
+static tree listify (tree);
+static tree listify_autos (tree, tree);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -269,17 +287,31 @@ finish_member_template_decl (tree decl)
   return error_mark_node;
 }
 
+/* Create a template info node.  */
+
+tree
+build_template_info (tree template_decl, tree template_args)
+{
+  tree result = make_node (TEMPLATE_INFO);
+  TI_TEMPLATE (result) = template_decl;
+  TI_ARGS (result) = template_args;
+  return result;
+}
+
 /* Return the template info node corresponding to T, whatever T is.  */
 
 tree
-get_template_info (tree t)
+get_template_info (const_tree t)
 {
   tree tinfo = NULL_TREE;
 
+  if (!t || t == error_mark_node)
+    return NULL;
+
   if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
     tinfo = DECL_TEMPLATE_INFO (t);
 
-  if (!tinfo && TREE_CODE (t) == TYPE_DECL)
+  if (!tinfo && DECL_IMPLICIT_TYPEDEF_P (t))
     t = TREE_TYPE (t);
 
   if (TAGGED_TYPE_P (t))
@@ -811,13 +843,13 @@ maybe_process_partial_specialization (tree type)
          && !COMPLETE_TYPE_P (type))
        {
          tree t;
+         tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
 
          if (current_namespace
-             != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
+             != decl_namespace_context (tmpl))
            {
              permerror (input_location, "specializing %q#T in different namespace", type);
-             permerror (input_location, "  from definition of %q+#D",
-                        CLASSTYPE_TI_TEMPLATE (type));
+             permerror (input_location, "  from definition of %q+#D", tmpl);
            }
 
          /* Check for invalid specialization after instantiation:
@@ -825,13 +857,38 @@ maybe_process_partial_specialization (tree type)
               template <> template <> class C<int>::D<int>;
               template <> template <class U> class C<int>::D;  */
 
-         for (t = DECL_TEMPLATE_INSTANTIATIONS
-                (most_general_template (CLASSTYPE_TI_TEMPLATE (type)));
+         for (t = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
               t; t = TREE_CHAIN (t))
-           if (TREE_VALUE (t) != type
-               && TYPE_CONTEXT (TREE_VALUE (t)) == context)
-             error ("specialization %qT after instantiation %qT",
-                    type, TREE_VALUE (t));
+           {
+             tree inst = TREE_VALUE (t);
+             if (CLASSTYPE_TEMPLATE_SPECIALIZATION (inst))
+               {
+                 /* We already have a full specialization of this partial
+                    instantiation.  Reassign it to the new member
+                    specialization template.  */
+                 spec_entry elt;
+                 spec_entry **slot;
+
+                 elt.tmpl = most_general_template (tmpl);
+                 elt.args = CLASSTYPE_TI_ARGS (inst);
+                 elt.spec = inst;
+
+                 htab_remove_elt (type_specializations, &elt);
+
+                 elt.tmpl = tmpl;
+                 elt.args = INNERMOST_TEMPLATE_ARGS (elt.args);
+
+                 slot = (spec_entry **)
+                   htab_find_slot (type_specializations, &elt, INSERT);
+                 *slot = GGC_NEW (spec_entry);
+                 **slot = elt;
+               }
+             else if (COMPLETE_TYPE_P (inst) || TYPE_BEING_DEFINED (inst))
+               /* But if we've had an implicit instantiation, that's a
+                  problem ([temp.expl.spec]/6).  */
+               error ("specialization %qT after instantiation %qT",
+                      type, inst);
+           }
 
          /* Mark TYPE as a specialization.  And as a result, we only
             have one level of template argument for the innermost
@@ -895,8 +952,7 @@ optimize_specialization_lookup_p (tree tmpl)
    parameter is ignored if TMPL is not a class template.  */
 
 static tree
-retrieve_specialization (tree tmpl, tree args,
-                        bool class_specializations_p)
+retrieve_specialization (tree tmpl, tree args, hashval_t hash)
 {
   if (args == error_mark_node)
     return NULL_TREE;
@@ -921,8 +977,7 @@ retrieve_specialization (tree tmpl, tree args,
         arguments.  */
       class_template = CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (tmpl));
       class_specialization
-       = retrieve_specialization (class_template, args,
-                                  /*class_specializations_p=*/false);
+       = retrieve_specialization (class_template, args, 0);
       if (!class_specialization)
        return NULL_TREE;
       /* Now, find the appropriate entry in the CLASSTYPE_METHOD_VEC
@@ -936,46 +991,34 @@ retrieve_specialization (tree tmpl, tree args,
       for (fns = VEC_index (tree, methods, idx); fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
-         if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl)
+         if (DECL_TEMPLATE_INFO (fn) && DECL_TI_TEMPLATE (fn) == tmpl
+             /* using-declarations can add base methods to the method vec,
+                and we don't want those here.  */
+             && DECL_CONTEXT (fn) == class_specialization)
            return fn;
        }
       return NULL_TREE;
     }
   else
     {
-      tree *sp;
-      tree *head;
-
-      /* Class templates store their instantiations on the
-        DECL_TEMPLATE_INSTANTIATIONS list; other templates use the
-        DECL_TEMPLATE_SPECIALIZATIONS list.  */
-      if (!class_specializations_p
-         && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL
-         && !is_typedef_decl (DECL_TEMPLATE_RESULT (tmpl))
-         && TAGGED_TYPE_P (TREE_TYPE (tmpl)))
-       sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl);
+      spec_entry *found;
+      spec_entry elt;
+      htab_t specializations;
+
+      elt.tmpl = tmpl;
+      elt.args = args;
+      elt.spec = NULL_TREE;
+
+      if (DECL_CLASS_TEMPLATE_P (tmpl))
+       specializations = type_specializations;
       else
-       sp = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
-      head = sp;
-      /* Iterate through the list until we find a matching template.  */
-      while (*sp != NULL_TREE)
-       {
-         tree spec = *sp;
+       specializations = decl_specializations;
 
-         if (comp_template_args (TREE_PURPOSE (spec), args))
-           {
-             /* Use the move-to-front heuristic to speed up future
-                searches.  */
-             if (spec != *head)
-               {
-                 *sp = TREE_CHAIN (*sp);
-                 TREE_CHAIN (spec) = *head;
-                 *head = spec;
-               }
-             return TREE_VALUE (spec);
-           }
-         sp = &TREE_CHAIN (spec);
-       }
+      if (hash == 0)
+       hash = hash_specialization (&elt);
+      found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash);
+      if (found)
+       return found->spec;
     }
 
   return NULL_TREE;
@@ -1214,11 +1257,14 @@ is_specialization_of_friend (tree decl, tree friend_decl)
    equivalent prior declaration, if available.  */
 
 static tree
-register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
+register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
+                        hashval_t hash)
 {
   tree fn;
+  spec_entry **slot = NULL;
+  spec_entry elt;
 
-  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec));
 
   if (TREE_CODE (spec) == FUNCTION_DECL
       && uses_template_parms (DECL_TI_ARGS (spec)))
@@ -1235,8 +1281,27 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
        instantiation unless and until it is actually needed.  */
     return spec;
 
-  fn = retrieve_specialization (tmpl, args,
-                               /*class_specializations_p=*/false);
+  if (optimize_specialization_lookup_p (tmpl))
+    /* We don't put these specializations in the hash table, but we might
+       want to give an error about a mismatch.  */
+    fn = retrieve_specialization (tmpl, args, 0);
+  else
+    {
+      elt.tmpl = tmpl;
+      elt.args = args;
+      elt.spec = spec;
+
+      if (hash == 0)
+       hash = hash_specialization (&elt);
+
+      slot = (spec_entry **)
+       htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT);
+      if (*slot)
+       fn = (*slot)->spec;
+      else
+       fn = NULL_TREE;
+    }
+
   /* We can sometimes try to re-register a specialization that we've
      already got.  In particular, regenerate_decl_from_template calls
      duplicate_decls which will update the specialization list.  But,
@@ -1248,7 +1313,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
     {
       if (DECL_TEMPLATE_INSTANTIATION (fn))
        {
-         if (TREE_USED (fn)
+         if (DECL_ODR_USED (fn)
              || DECL_EXPLICIT_INSTANTIATION (fn))
            {
              error ("specialization of %qD after instantiation",
@@ -1294,8 +1359,12 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
                to the primary function; now copy the inline bits to
                the various clones.  */
              FOR_EACH_CLONE (clone, fn)
-               DECL_DECLARED_INLINE_P (clone)
-                 = DECL_DECLARED_INLINE_P (fn);
+               {
+                 DECL_DECLARED_INLINE_P (clone)
+                   = DECL_DECLARED_INLINE_P (fn);
+                 DECL_SOURCE_LOCATION (clone)
+                   = DECL_SOURCE_LOCATION (fn);
+               }
              check_specialization_namespace (fn);
 
              return fn;
@@ -1312,6 +1381,8 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
          return fn;
        }
     }
+  else if (fn)
+    return duplicate_decls (spec, fn, is_friend);
 
   /* A specialization must be declared in the same namespace as the
      template it is specializing.  */
@@ -1320,32 +1391,215 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
     DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl);
 
   if (!optimize_specialization_lookup_p (tmpl))
-    DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
-      = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
+    {
+      gcc_assert (tmpl && args && spec);
+      *slot = GGC_NEW (spec_entry);
+      **slot = elt;
+      if (TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec)
+         && PRIMARY_TEMPLATE_P (tmpl)
+         && DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (tmpl)) == NULL_TREE)
+       /* TMPL is a forward declaration of a template function; keep a list
+          of all specializations in case we need to reassign them to a friend
+          template later in tsubst_friend_function.  */
+       DECL_TEMPLATE_INSTANTIATIONS (tmpl)
+         = tree_cons (args, spec, DECL_TEMPLATE_INSTANTIATIONS (tmpl));
+    }
 
   return spec;
 }
 
+/* Returns true iff two spec_entry nodes are equivalent.  Only compares the
+   TMPL and ARGS members, ignores SPEC.  */
+
+static int
+eq_specializations (const void *p1, const void *p2)
+{
+  const spec_entry *e1 = (const spec_entry *)p1;
+  const spec_entry *e2 = (const spec_entry *)p2;
+
+  return (e1->tmpl == e2->tmpl
+         && comp_template_args (e1->args, e2->args));
+}
+
+/* Returns a hash for a template TMPL and template arguments ARGS.  */
+
+static hashval_t
+hash_tmpl_and_args (tree tmpl, tree args)
+{
+  hashval_t val = DECL_UID (tmpl);
+  return iterative_hash_template_arg (args, val);
+}
+
+/* Returns a hash for a spec_entry node based on the TMPL and ARGS members,
+   ignoring SPEC.  */
+
+static hashval_t
+hash_specialization (const void *p)
+{
+  const spec_entry *e = (const spec_entry *)p;
+  return hash_tmpl_and_args (e->tmpl, e->args);
+}
+
+/* Recursively calculate a hash value for a template argument ARG, for use
+   in the hash tables of template specializations.  */
+
+static hashval_t
+iterative_hash_template_arg (tree arg, hashval_t val)
+{
+  unsigned HOST_WIDE_INT i;
+  enum tree_code code;
+  char tclass;
+
+  if (arg == NULL_TREE)
+    return iterative_hash_object (arg, val);
+
+  if (!TYPE_P (arg))
+    STRIP_NOPS (arg);
+
+  code = TREE_CODE (arg);
+  tclass = TREE_CODE_CLASS (code);
+
+  val = iterative_hash_object (code, val);
+
+  switch (code)
+    {
+    case ERROR_MARK:
+      return val;
+
+    case IDENTIFIER_NODE:
+      return iterative_hash_object (IDENTIFIER_HASH_VALUE (arg), val);
+
+    case TREE_VEC:
+      {
+       int i, len = TREE_VEC_LENGTH (arg);
+       for (i = 0; i < len; ++i)
+         val = iterative_hash_template_arg (TREE_VEC_ELT (arg, i), val);
+       return val;
+      }
+
+    case TYPE_PACK_EXPANSION:
+    case EXPR_PACK_EXPANSION:
+      return iterative_hash_template_arg (PACK_EXPANSION_PATTERN (arg), val);
+
+    case ARGUMENT_PACK_SELECT:
+      /* We can get one of these when re-hashing a previous entry in the middle
+         of substituting into a pack expansion.  Just look through it...  */
+      arg = ARGUMENT_PACK_SELECT_FROM_PACK (arg);
+      /* ...and fall through.  */
+    case TYPE_ARGUMENT_PACK:
+    case NONTYPE_ARGUMENT_PACK:
+      return iterative_hash_template_arg (ARGUMENT_PACK_ARGS (arg), val);
+
+    case TREE_LIST:
+      for (; arg; arg = TREE_CHAIN (arg))
+       val = iterative_hash_template_arg (TREE_VALUE (arg), val);
+      return val;
+
+    case OVERLOAD:
+      for (; arg; arg = OVL_CHAIN (arg))
+       val = iterative_hash_template_arg (OVL_FUNCTION (arg), val);
+      return val;
+
+    case CONSTRUCTOR:
+      {
+       tree field, value;
+       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg), i, field, value)
+         {
+           val = iterative_hash_template_arg (field, val);
+           val = iterative_hash_template_arg (value, val);
+         }
+       return val;
+      }
+
+    case PARM_DECL:
+      if (!DECL_ARTIFICIAL (arg))
+       val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
+      return iterative_hash_template_arg (TREE_TYPE (arg), val);
+
+    case TARGET_EXPR:
+      return iterative_hash_template_arg (TARGET_EXPR_INITIAL (arg), val);
+
+    case PTRMEM_CST:
+      val = iterative_hash_template_arg (PTRMEM_CST_CLASS (arg), val);
+      return iterative_hash_template_arg (PTRMEM_CST_MEMBER (arg), val);
+
+    case TEMPLATE_PARM_INDEX:
+      val = iterative_hash_template_arg
+       (TREE_TYPE (TEMPLATE_PARM_DECL (arg)), val);
+      val = iterative_hash_object (TEMPLATE_PARM_LEVEL (arg), val);
+      return iterative_hash_object (TEMPLATE_PARM_IDX (arg), val);
+
+    case TRAIT_EXPR:
+      val = iterative_hash_object (TRAIT_EXPR_KIND (arg), val);
+      val = iterative_hash_template_arg (TRAIT_EXPR_TYPE1 (arg), val);
+      return iterative_hash_template_arg (TRAIT_EXPR_TYPE2 (arg), val);
+
+    case BASELINK:
+      val = iterative_hash_template_arg (BINFO_TYPE (BASELINK_BINFO (arg)),
+                                        val);
+      return iterative_hash_template_arg (DECL_NAME (get_first_fn (arg)),
+                                         val);
+
+    case MODOP_EXPR:
+      val = iterative_hash_template_arg (TREE_OPERAND (arg, 0), val);
+      code = TREE_CODE (TREE_OPERAND (arg, 1));
+      val = iterative_hash_object (code, val);
+      return iterative_hash_template_arg (TREE_OPERAND (arg, 2), val);
+
+    default:
+      switch (tclass)
+       {
+       case tcc_type:
+         if (TYPE_CANONICAL (arg))
+           return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)),
+                                         val);
+         else if (TREE_CODE (arg) == DECLTYPE_TYPE)
+           return iterative_hash_template_arg (DECLTYPE_TYPE_EXPR (arg), val);
+         /* Otherwise just compare the types during lookup.  */
+         return val;
+
+       case tcc_declaration:
+       case tcc_constant:
+         return iterative_hash_expr (arg, val);
+
+       default:
+         gcc_assert (IS_EXPR_CODE_CLASS (tclass));
+         {
+           unsigned n = TREE_OPERAND_LENGTH (arg);
+           for (i = 0; i < n; ++i)
+             val = iterative_hash_template_arg (TREE_OPERAND (arg, i), val);
+           return val;
+         }
+       }
+    }
+  gcc_unreachable ();
+  return 0;
+}
+
 /* Unregister the specialization SPEC as a specialization of TMPL.
    Replace it with NEW_SPEC, if NEW_SPEC is non-NULL.  Returns true
-   if the SPEC was listed as a specialization of TMPL.  */
+   if the SPEC was listed as a specialization of TMPL.
+
+   Note that SPEC has been ggc_freed, so we can't look inside it.  */
 
 bool
-reregister_specialization (tree spec, tree tmpl, tree new_spec)
+reregister_specialization (tree spec, tree tinfo, tree new_spec)
 {
-  tree* s;
+  spec_entry **slot;
+  spec_entry elt;
 
-  for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
-       *s != NULL_TREE;
-       s = &TREE_CHAIN (*s))
-    if (TREE_VALUE (*s) == spec)
-      {
-       if (!new_spec)
-         *s = TREE_CHAIN (*s);
-       else
-         TREE_VALUE (*s) = new_spec;
-       return 1;
-      }
+  elt.tmpl = most_general_template (TI_TEMPLATE (tinfo));
+  elt.args = TI_ARGS (tinfo);
+  elt.spec = NULL_TREE;
+
+  slot = (spec_entry **) htab_find_slot (decl_specializations, &elt, INSERT);
+  if (*slot)
+    {
+      gcc_assert ((*slot)->spec == spec || (*slot)->spec == new_spec);
+      gcc_assert (new_spec != NULL_TREE);
+      (*slot)->spec = new_spec;
+      return 1;
+    }
 
   return 0;
 }
@@ -1392,22 +1646,36 @@ explicit_class_specialization_p (tree type)
   return !uses_template_parms (CLASSTYPE_TI_ARGS (type));
 }
 
+/* Print the list of overloaded FNS in an error message.   */
+
+static void
+print_overloaded_functions (tree fns, const char **str)
+{
+  tree fn;
+  for (fn = fns; fn; fn = OVL_NEXT (fn))
+    {
+      if (TREE_CODE (fn) == TREE_LIST)
+       print_candidates (fn);
+      else
+       error ("%s %+#D", *str, OVL_CURRENT (fn));
+      *str = "               ";
+    }
+}
+
 /* Print the list of candidate FNS in an error message.  */
 
 void
 print_candidates (tree fns)
 {
-  tree fn;
-
   const char *str = "candidates are:";
 
-  for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn))
+  if (is_overloaded_fn (fns))
+    print_overloaded_functions (fns, &str);
+  else
     {
-      tree f;
-
-      for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f))
-       error ("%s %+#D", str, OVL_CURRENT (f));
-      str = "               ";
+      tree fn;
+      for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn))
+       print_overloaded_functions (TREE_VALUE (fn), &str);
     }
 }
 
@@ -1684,6 +1952,10 @@ determine_specialization (tree template_id,
     {
       error ("template-id %qD for %q+D does not match any template "
             "declaration", template_id, decl);
+      if (header_count && header_count != template_count + 1)
+       inform (input_location, "saw %d %<template<>%>, need %d for "
+               "specializing a member function template",
+               header_count, template_count + 1);
       return error_mark_node;
     }
   else if ((templates && TREE_CHAIN (templates))
@@ -1692,7 +1964,7 @@ determine_specialization (tree template_id,
     {
       error ("ambiguous template specialization %qD for %q+D",
             template_id, decl);
-      chainon (candidates, templates);
+      candidates = chainon (candidates, templates);
       print_candidates (candidates);
       return error_mark_node;
     }
@@ -1701,12 +1973,13 @@ determine_specialization (tree template_id,
   if (candidates)
     {
       tree fn = TREE_VALUE (candidates);
-      /* DECL is a re-declaration of a template function.  */
+      *targs_out = copy_node (DECL_TI_ARGS (fn));
+      /* DECL is a re-declaration or partial instantiation of a template
+        function.  */
       if (TREE_CODE (fn) == TEMPLATE_DECL)
        return fn;
       /* It was a specialization of an ordinary member function in a
         template class.  */
-      *targs_out = copy_node (DECL_TI_ARGS (fn));
       return DECL_TI_TEMPLATE (fn);
     }
 
@@ -2237,11 +2510,12 @@ check_explicit_specialization (tree declarator,
                       parm = TREE_CHAIN (parm))
                    DECL_CONTEXT (parm) = result;
                }
-             return tmpl;
+             return register_specialization (tmpl, gen_tmpl, targs,
+                                             is_friend, 0);
            }
 
          /* Set up the DECL_TEMPLATE_INFO for DECL.  */
-         DECL_TEMPLATE_INFO (decl) = tree_cons (tmpl, targs, NULL_TREE);
+         DECL_TEMPLATE_INFO (decl) = build_template_info (tmpl, targs);
 
          /* Inherit default function arguments from the template
             DECL is specializing.  */
@@ -2315,7 +2589,7 @@ check_explicit_specialization (tree declarator,
 
          /* Register this specialization so that we can find it
             again.  */
-         decl = register_specialization (decl, gen_tmpl, targs, is_friend);
+         decl = register_specialization (decl, gen_tmpl, targs, is_friend, 0);
        }
     }
 
@@ -2380,6 +2654,7 @@ comp_template_parms (const_tree parms1, const_tree parms2)
 }
 
 /* Determine whether PARM is a parameter pack.  */
+
 bool 
 template_parameter_pack_p (const_tree parm)
 {
@@ -2398,8 +2673,50 @@ template_parameter_pack_p (const_tree parm)
          && TEMPLATE_TYPE_PARAMETER_PACK (parm));
 }
 
+/* Determine if T is a function parameter pack.  */
+
+bool
+function_parameter_pack_p (const_tree t)
+{
+  if (t && TREE_CODE (t) == PARM_DECL)
+    return FUNCTION_PARAMETER_PACK_P (t);
+  return false;
+}
+
+/* Return the function template declaration of PRIMARY_FUNC_TMPL_INST.
+   PRIMARY_FUNC_TMPL_INST is a primary function template instantiation.  */
+
+tree
+get_function_template_decl (const_tree primary_func_tmpl_inst)
+{
+  if (! primary_func_tmpl_inst
+      || TREE_CODE (primary_func_tmpl_inst) != FUNCTION_DECL
+      || ! primary_template_instantiation_p (primary_func_tmpl_inst))
+    return NULL;
+
+  return DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (primary_func_tmpl_inst));
+}
+
+/* Return true iff the function parameter PARAM_DECL was expanded
+   from the function parameter pack PACK.  */
+
+bool
+function_parameter_expanded_from_pack_p (tree param_decl, tree pack)
+{
+    if (DECL_ARTIFICIAL (param_decl)
+       || !function_parameter_pack_p (pack))
+      return false;
+
+    gcc_assert (DECL_NAME (param_decl) && DECL_NAME (pack));
+
+    /* The parameter pack and its pack arguments have the same
+       DECL_PARM_INDEX.  */
+    return DECL_PARM_INDEX (pack) == DECL_PARM_INDEX (param_decl);
+}
+
 /* Determine whether ARGS describes a variadic template args list,
    i.e., one that is terminated by a template argument pack.  */
+
 static bool 
 template_args_variadic_p (tree args)
 {
@@ -2422,19 +2739,96 @@ template_args_variadic_p (tree args)
 
 /* Generate a new name for the parameter pack name NAME (an
    IDENTIFIER_NODE) that incorporates its */
+
 static tree
 make_ith_pack_parameter_name (tree name, int i)
 {
   /* Munge the name to include the parameter index.  */
-  char numbuf[128];
+#define NUMBUF_LEN 128
+  char numbuf[NUMBUF_LEN];
   char* newname;
-  
-  sprintf(numbuf, "%i", i);
-  newname = (char*)alloca (IDENTIFIER_LENGTH (name) + strlen(numbuf) + 2);
-  sprintf(newname, "%s#%i", IDENTIFIER_POINTER (name), i);
+  int newname_len;
+
+  snprintf (numbuf, NUMBUF_LEN, "%i", i);
+  newname_len = IDENTIFIER_LENGTH (name)
+               + strlen (numbuf) + 2;
+  newname = (char*)alloca (newname_len);
+  snprintf (newname, newname_len,
+           "%s#%i", IDENTIFIER_POINTER (name), i);
   return get_identifier (newname);
 }
 
+/* Return true if T is a primary function
+   or class template instantiation.  */
+
+bool
+primary_template_instantiation_p (const_tree t)
+{
+  if (!t)
+    return false;
+
+  if (TREE_CODE (t) == FUNCTION_DECL)
+    return DECL_LANG_SPECIFIC (t)
+          && DECL_TEMPLATE_INSTANTIATION (t)
+          && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t));
+  else if (CLASS_TYPE_P (t))
+    return CLASSTYPE_TEMPLATE_INSTANTIATION (t)
+          && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t));
+  return false;
+}
+
+/* Return true if PARM is a template template parameter.  */
+
+bool
+template_template_parameter_p (const_tree parm)
+{
+  return DECL_TEMPLATE_TEMPLATE_PARM_P (parm);
+}
+
+/* Return the template parameters of T if T is a
+   primary template instantiation, NULL otherwise.  */
+
+tree
+get_primary_template_innermost_parameters (const_tree t)
+{
+  tree parms = NULL, template_info = NULL;
+
+  if ((template_info = get_template_info (t))
+      && primary_template_instantiation_p (t))
+    parms = INNERMOST_TEMPLATE_PARMS
+       (DECL_TEMPLATE_PARMS (TI_TEMPLATE (template_info)));
+
+  return parms;
+}
+
+/* Returns the template arguments of T if T is a template instantiation,
+   NULL otherwise.  */
+
+tree
+get_template_innermost_arguments (const_tree t)
+{
+  tree args = NULL, template_info = NULL;
+
+  if ((template_info = get_template_info (t))
+      && TI_ARGS (template_info))
+    args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (template_info));
+
+  return args;
+}
+
+/* Return the argument pack elements of T if T is a template argument pack,
+   NULL otherwise.  */
+
+tree
+get_template_argument_pack_elems (const_tree t)
+{
+  if (TREE_CODE (t) != TYPE_ARGUMENT_PACK
+      && TREE_CODE (t) != NONTYPE_ARGUMENT_PACK)
+    return NULL;
+
+  return ARGUMENT_PACK_ARGS (t);
+}
+
 /* Structure used to track the progress of find_parameter_packs_r.  */
 struct find_parameter_pack_data 
 {
@@ -2529,7 +2923,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case UNION_TYPE:
     case ENUMERAL_TYPE:
       if (TYPE_TEMPLATE_INFO (t))
-       cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), 
+       cp_walk_tree (&TI_ARGS (TYPE_TEMPLATE_INFO (t)),
                      &find_parameter_packs_r, ppd, ppd->visited);
 
       *walk_subtrees = 0;
@@ -2654,7 +3048,7 @@ make_pack_expansion (tree arg)
       pointer_set_destroy (ppd.visited);
 
       /* Create the pack expansion type for the base type.  */
-      purpose = make_node (TYPE_PACK_EXPANSION);
+      purpose = cxx_make_type (TYPE_PACK_EXPANSION);
       SET_PACK_EXPANSION_PATTERN (purpose, TREE_PURPOSE (arg));
       PACK_EXPANSION_PARAMETER_PACKS (purpose) = parameter_packs;
 
@@ -2669,7 +3063,9 @@ make_pack_expansion (tree arg)
     for_types = true;
 
   /* Build the PACK_EXPANSION_* node.  */
-  result = make_node (for_types ? TYPE_PACK_EXPANSION : EXPR_PACK_EXPANSION);
+  result = for_types
+     ? cxx_make_type (TYPE_PACK_EXPANSION)
+     : make_node (EXPR_PACK_EXPANSION);
   SET_PACK_EXPANSION_PATTERN (result, arg);
   if (TREE_CODE (result) == EXPR_PACK_EXPANSION)
     {
@@ -2777,6 +3173,8 @@ expand_template_argument_pack (tree args)
   for (in_arg = 0; in_arg < nargs; ++in_arg)
     {
       tree arg = TREE_VEC_ELT (args, in_arg);
+      if (arg == NULL_TREE)
+       return args;
       if (ARGUMENT_PACK_P (arg))
         {
           int num_packed = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg));
@@ -3179,7 +3577,7 @@ current_template_args (void)
                           tree vec = make_tree_vec (1);
                           TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
                           
-                          t = make_node (TYPE_ARGUMENT_PACK);
+                          t = cxx_make_type (TYPE_ARGUMENT_PACK);
                           SET_ARGUMENT_PACK_ARGS (t, vec);
                         }
                     }
@@ -3225,17 +3623,6 @@ build_template_decl (tree decl, tree parms, bool member_template_p)
   DECL_TEMPLATE_PARMS (tmpl) = parms;
   DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
   DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
-  if (DECL_LANG_SPECIFIC (decl))
-    {
-      DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
-      DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);
-      DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl);
-      DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);
-      DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);
-      if (DECL_OVERLOADED_OPERATOR_P (decl))
-       SET_OVERLOADED_OPERATOR_CODE (tmpl,
-                                     DECL_OVERLOADED_OPERATOR_P (decl));
-    }
 
   return tmpl;
 }
@@ -3431,12 +3818,11 @@ process_partial_specialization (tree decl)
                   || (!packed_args && i < nargs - 1))
                 {
                   if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
-                    error ("parameter pack argument %qE must be at the end of the template argument list", arg);
+                    error ("parameter pack argument %qE must be at the "
+                          "end of the template argument list", arg);
                   else
-                    error ("parameter pack argument %qT must be at the end of the template argument list", arg);
-
-                 if (packed_args)
-                   TREE_VEC_ELT (packed_args, j) = error_mark_node;
+                    error ("parameter pack argument %qT must be at the "
+                          "end of the template argument list", arg);
                 }
             }
 
@@ -3510,10 +3896,8 @@ process_partial_specialization (tree decl)
         }
     }
 
-  if (retrieve_specialization (maintmpl, specargs,
-                              /*class_specializations_p=*/true))
-    /* We've already got this specialization.  */
-    return decl;
+  /* We should only get here once.  */
+  gcc_assert (!COMPLETE_TYPE_P (type));
 
   DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
     = tree_cons (specargs, inner_parms,
@@ -3561,6 +3945,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
   if (current_class_type
       && !TYPE_BEING_DEFINED (current_class_type)
       && DECL_LANG_SPECIFIC (decl)
+      && DECL_DECLARES_FUNCTION_P (decl)
       /* If this is either a friend defined in the scope of the class
         or a member function.  */
       && (DECL_FUNCTION_MEMBER_P (decl)
@@ -3671,7 +4056,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
   else if (is_friend_decl)
     msg = "default template arguments may not be used in function template friend declarations";
   else if (TREE_CODE (decl) == FUNCTION_DECL && (cxx_dialect == cxx98))
-    msg = "default template arguments may not be used in function templates";
+    msg = ("default template arguments may not be used in function templates "
+          "without -std=c++0x or -std=gnu++0x");
   else if (is_partial)
     msg = "default template arguments may not be used in partial specializations";
   else
@@ -3988,12 +4374,12 @@ push_template_decl_real (tree decl, bool is_friend)
          DECL_TI_TEMPLATE (decl) = new_tmpl;
          SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
          DECL_TEMPLATE_INFO (new_tmpl)
-           = tree_cons (tmpl, args, NULL_TREE);
+           = build_template_info (tmpl, args);
 
          register_specialization (new_tmpl,
                                   most_general_template (tmpl),
                                   args,
-                                  is_friend);
+                                  is_friend, 0);
          return decl;
        }
 
@@ -4107,7 +4493,7 @@ template arguments to %qD do not match original template %qD",
   if (DECL_TEMPLATE_INFO (tmpl))
     args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
 
-  info = tree_cons (tmpl, args, NULL_TREE);
+  info = build_template_info (tmpl, args);
 
   if (DECL_IMPLICIT_TYPEDEF_P (decl))
     SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info);
@@ -4208,8 +4594,9 @@ redeclare_class_template (tree type, tree parms)
 
             A template-parameter may not be given default arguments
             by two different declarations in the same scope.  */
-         error ("redefinition of default argument for %q#D", parm);
-         inform (input_location, "%Joriginal definition appeared here", tmpl_parm);
+         error_at (input_location, "redefinition of default argument for %q#D", parm);
+         inform (DECL_SOURCE_LOCATION (tmpl_parm),
+                 "original definition appeared here");
          return false;
        }
 
@@ -4322,6 +4709,22 @@ convert_nontype_argument_function (tree type, tree expr)
   return fn;
 }
 
+/* Subroutine of convert_nontype_argument.
+   Check if EXPR of type TYPE is a valid pointer-to-member constant.
+   Emit an error otherwise.  */
+
+static bool
+check_valid_ptrmem_cst_expr (tree type, tree expr)
+{
+  STRIP_NOPS (expr);
+  if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
+    return true;
+  error ("%qE is not a valid template argument for type %qT",
+        expr, type);
+  error ("it must be a pointer-to-member of the form `&X::Y'");
+  return false;
+}
+
 /* Attempt to convert the non-type template parameter EXPR to the
    indicated TYPE.  If the conversion is successful, return the
    converted value.  If the conversion is unsuccessful, return
@@ -4548,6 +4951,27 @@ convert_nontype_argument (tree type, tree expr)
         shall be one of: [...]
 
         -- the address of an object or function with external linkage.  */
+      if (TREE_CODE (expr) == INDIRECT_REF
+         && TYPE_REF_OBJ_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
+       {
+         expr = TREE_OPERAND (expr, 0);
+         if (DECL_P (expr))
+           {
+             error ("%q#D is not a valid template argument for type %qT "
+                    "because a reference variable does not have a constant "
+                    "address", expr, type);
+             return NULL_TREE;
+           }
+       }
+
+      if (!DECL_P (expr))
+       {
+         error ("%qE is not a valid template argument for type %qT "
+                "because it is not an object with external linkage",
+                expr, type);
+         return NULL_TREE;
+       }
+
       if (!DECL_EXTERNAL_LINKAGE_P (expr))
        {
          error ("%qE is not a valid template argument for type %qT "
@@ -4621,6 +5045,11 @@ convert_nontype_argument (tree type, tree expr)
       if (expr == error_mark_node)
        return error_mark_node;
 
+      /* [temp.arg.nontype] bullet 1 says the pointer to member
+         expression must be a pointer-to-member constant.  */
+      if (!check_valid_ptrmem_cst_expr (type, expr))
+       return error_mark_node;
+
       /* There is no way to disable standard conversions in
         resolve_address_of_overloaded_function (called by
         instantiate_type). It is possible that the call succeeded by
@@ -4647,6 +5076,11 @@ convert_nontype_argument (tree type, tree expr)
      qualification conversions (_conv.qual_) are applied.  */
   else if (TYPE_PTRMEM_P (type))
     {
+      /* [temp.arg.nontype] bullet 1 says the pointer to member
+         expression must be a pointer-to-member constant.  */
+      if (!check_valid_ptrmem_cst_expr (type, expr))
+       return error_mark_node;
+
       expr = perform_qualification_conversions (type, expr);
       if (expr == error_mark_node)
        return expr;
@@ -4958,6 +5392,22 @@ convert_template_argument (tree parm,
   if (TREE_CODE (arg) == TYPE_PACK_EXPANSION)
     arg = PACK_EXPANSION_PATTERN (arg);
 
+  /* Deal with an injected-class-name used as a template template arg.  */
+  if (requires_tmpl_type && CLASS_TYPE_P (arg))
+    {
+      tree t = maybe_get_template_decl_from_type_decl (TYPE_NAME (arg));
+      if (TREE_CODE (t) == TEMPLATE_DECL)
+       {
+         if (complain & tf_warning_or_error)
+           pedwarn (input_location, OPT_pedantic, "injected-class-name %qD"
+                    " used as template template argument", TYPE_NAME (arg));
+         else if (flag_pedantic_errors)
+           t = arg;
+
+         arg = t;
+       }
+    }
+
   is_tmpl_type = 
     ((TREE_CODE (arg) == TEMPLATE_DECL
       && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
@@ -5039,7 +5489,7 @@ convert_template_argument (tree parm,
                                                  complain, in_decl,
                                                  args))
                {
-                 val = orig_arg;
+                 val = arg;
 
                  /* TEMPLATE_TEMPLATE_PARM node is preferred over
                     TEMPLATE_DECL.  */
@@ -5047,12 +5497,8 @@ convert_template_argument (tree parm,
                     {
                       if (DECL_TEMPLATE_TEMPLATE_PARM_P (val))
                         val = TREE_TYPE (val);
-                      else if (TREE_CODE (val) == TYPE_PACK_EXPANSION
-                               && DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
-                        {
-                          val = TREE_TYPE (arg);
-                          val = make_pack_expansion (val);
-                        }
+                     if (TREE_CODE (orig_arg) == TYPE_PACK_EXPANSION)
+                       val = make_pack_expansion (val);
                     }
                }
              else
@@ -5062,7 +5508,7 @@ convert_template_argument (tree parm,
                      error ("type/value mismatch at argument %d in "
                             "template parameter list for %qD",
                             i + 1, in_decl);
-                     error ("  expected a template of type %qD, got %qD",
+                     error ("  expected a template of type %qD, got %qT",
                             parm, orig_arg);
                    }
 
@@ -5227,7 +5673,7 @@ coerce_template_parameter_pack (tree parms,
 
   if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL
       || TREE_CODE (TREE_VALUE (parm)) == TEMPLATE_DECL)
-    argument_pack = make_node (TYPE_ARGUMENT_PACK);
+    argument_pack = cxx_make_type (TYPE_ARGUMENT_PACK);
   else
     {
       argument_pack = make_node (NONTYPE_ARGUMENT_PACK);
@@ -5264,7 +5710,8 @@ coerce_template_parms (tree parms,
   tree inner_args;
   tree new_args;
   tree new_inner_args;
-  bool saved_skip_evaluation;
+  int saved_unevaluated_operand;
+  int saved_inhibit_evaluation_warnings;
 
   /* When used as a boolean value, indicates whether this is a
      variadic template parameter list. Since it's an int, we can also
@@ -5322,8 +5769,10 @@ coerce_template_parms (tree parms,
 
   /* We need to evaluate the template arguments, even though this
      template-id may be nested within a "sizeof".  */
-  saved_skip_evaluation = skip_evaluation;
-  skip_evaluation = false;
+  saved_unevaluated_operand = cp_unevaluated_operand;
+  cp_unevaluated_operand = 0;
+  saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+  c_inhibit_evaluation_warnings = 0;
   new_inner_args = make_tree_vec (nparms);
   new_args = add_outermost_template_args (args, new_inner_args);
   for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
@@ -5416,7 +5865,8 @@ coerce_template_parms (tree parms,
        lost++;
       TREE_VEC_ELT (new_inner_args, arg_idx) = arg;
     }
-  skip_evaluation = saved_skip_evaluation;
+  cp_unevaluated_operand = saved_unevaluated_operand;
+  c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
   if (lost)
     return error_mark_node;
@@ -5458,6 +5908,18 @@ template_args_equal (tree ot, tree nt)
          return 0;
       return 1;
     }
+  else if (ot && TREE_CODE (ot) == ARGUMENT_PACK_SELECT)
+    {
+      /* We get here probably because we are in the middle of substituting
+         into the pattern of a pack expansion. In that case the
+        ARGUMENT_PACK_SELECT temporarily replaces the pack argument we are
+        interested in. So we want to use the initial pack argument for
+        the comparison.  */
+      ot = ARGUMENT_PACK_SELECT_FROM_PACK (ot);
+      if (nt && TREE_CODE (nt) == ARGUMENT_PACK_SELECT)
+       nt = ARGUMENT_PACK_SELECT_FROM_PACK (nt);
+      return template_args_equal (ot, nt);
+    }
   else if (TYPE_P (nt))
     return TYPE_P (ot) && same_type_p (ot, nt);
   else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
@@ -5562,15 +6024,43 @@ lookup_template_function (tree fns, tree arglist)
    TEMPLATE_DECL.  If DECL is a TYPE_DECL for current_class_type,
    or one of its enclosing classes, and that type is a template,
    return the associated TEMPLATE_DECL.  Otherwise, the original
-   DECL is returned.  */
+   DECL is returned.
+
+   Also handle the case when DECL is a TREE_LIST of ambiguous
+   injected-class-names from different bases.  */
 
 tree
 maybe_get_template_decl_from_type_decl (tree decl)
 {
+  if (decl == NULL_TREE)
+    return decl;
+
+  /* DR 176: A lookup that finds an injected-class-name (10.2
+     [class.member.lookup]) can result in an ambiguity in certain cases
+     (for example, if it is found in more than one base class). If all of
+     the injected-class-names that are found refer to specializations of
+     the same class template, and if the name is followed by a
+     template-argument-list, the reference refers to the class template
+     itself and not a specialization thereof, and is not ambiguous.  */
+  if (TREE_CODE (decl) == TREE_LIST)
+    {
+      tree t, tmpl = NULL_TREE;
+      for (t = decl; t; t = TREE_CHAIN (t))
+       {
+         tree elt = maybe_get_template_decl_from_type_decl (TREE_VALUE (t));
+         if (!tmpl)
+           tmpl = elt;
+         else if (tmpl != elt)
+           break;
+       }
+      if (tmpl && t == NULL_TREE)
+       return tmpl;
+      else
+       return decl;
+    }
+
   return (decl != NULL_TREE
-         && TREE_CODE (decl) == TYPE_DECL
-         && DECL_ARTIFICIAL (decl)
-         && CLASS_TYPE_P (TREE_TYPE (decl))
+         && DECL_SELF_REFERENCE_P (decl)
          && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
     ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl;
 }
@@ -5609,6 +6099,10 @@ lookup_template_class (tree d1,
 {
   tree templ = NULL_TREE, parmlist;
   tree t;
+  spec_entry **slot;
+  spec_entry *entry;
+  spec_entry elt;
+  hashval_t hash;
 
   timevar_push (TV_NAME_LOOKUP);
 
@@ -5774,7 +6268,6 @@ lookup_template_class (tree d1,
 
       /* From here on, we're only interested in the most general
         template.  */
-      templ = gen_tmpl;
 
       /* Calculate the BOUND_ARGS.  These will be the args that are
         actually tsubst'd into the definition to create the
@@ -5788,12 +6281,12 @@ lookup_template_class (tree d1,
          tree bound_args = make_tree_vec (parm_depth);
 
          for (i = saved_depth,
-                t = DECL_TEMPLATE_PARMS (templ);
+                t = DECL_TEMPLATE_PARMS (gen_tmpl);
               i > 0 && t != NULL_TREE;
               --i, t = TREE_CHAIN (t))
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
-                                             arglist, templ,
+                                             arglist, gen_tmpl,
                                              complain,
                                              /*require_all_args=*/true,
                                              /*use_default_args=*/true);
@@ -5824,7 +6317,7 @@ lookup_template_class (tree d1,
        arglist
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
-                                  templ,
+                                  gen_tmpl,
                                   complain,
                                   /*require_all_args=*/true,
                                   /*use_default_args=*/true);
@@ -5841,37 +6334,23 @@ lookup_template_class (tree d1,
 
         the `C<T>' is just the same as `C'.  Outside of the
         class, however, such a reference is an instantiation.  */
-      if (comp_template_args (TYPE_TI_ARGS (template_type),
-                             arglist))
-       {
-         found = template_type;
-
-         if (!entering_scope && PRIMARY_TEMPLATE_P (templ))
-           {
-             tree ctx;
-
-             for (ctx = current_class_type;
-                  ctx && TREE_CODE (ctx) != NAMESPACE_DECL;
-                  ctx = (TYPE_P (ctx)
-                         ? TYPE_CONTEXT (ctx)
-                         : DECL_CONTEXT (ctx)))
-               if (TYPE_P (ctx) && same_type_p (ctx, template_type))
-                 goto found_ctx;
-
-             /* We're not in the scope of the class, so the
-                TEMPLATE_TYPE is not the type we want after all.  */
-             found = NULL_TREE;
-           found_ctx:;
-           }
-       }
-      if (found)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
+      if ((entering_scope
+          || !PRIMARY_TEMPLATE_P (gen_tmpl)
+          || currently_open_class (template_type))
+         /* comp_template_args is expensive, check it last.  */
+         && comp_template_args (TYPE_TI_ARGS (template_type),
+                                arglist))
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, template_type);
 
       /* If we already have this specialization, return it.  */
-      found = retrieve_specialization (templ, arglist,
-                                      /*class_specializations_p=*/false);
-      if (found)
-       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
+      elt.tmpl = gen_tmpl;
+      elt.args = arglist;
+      hash = hash_specialization (&elt);
+      entry = (spec_entry *) htab_find_with_hash (type_specializations,
+                                                 &elt, hash);
+
+      if (entry)
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec);
 
       /* This type is a "partial instantiation" if any of the template
         arguments still involve template parameters.  Note that we set
@@ -5882,22 +6361,23 @@ lookup_template_class (tree d1,
       /* If the deduced arguments are invalid, then the binding
         failed.  */
       if (!is_partial_instantiation
-         && check_instantiated_args (templ,
+         && check_instantiated_args (gen_tmpl,
                                      INNERMOST_TEMPLATE_ARGS (arglist),
                                      complain))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
       if (!is_partial_instantiation
-         && !PRIMARY_TEMPLATE_P (templ)
-         && TREE_CODE (CP_DECL_CONTEXT (templ)) == NAMESPACE_DECL)
+         && !PRIMARY_TEMPLATE_P (gen_tmpl)
+         && !LAMBDA_TYPE_P (TREE_TYPE (gen_tmpl))
+         && TREE_CODE (CP_DECL_CONTEXT (gen_tmpl)) == NAMESPACE_DECL)
        {
-         found = xref_tag_from_type (TREE_TYPE (templ),
-                                     DECL_NAME (templ),
+         found = xref_tag_from_type (TREE_TYPE (gen_tmpl),
+                                     DECL_NAME (gen_tmpl),
                                      /*tag_scope=*/ts_global);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
        }
 
-      context = tsubst (DECL_CONTEXT (templ), arglist,
+      context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
                        complain, in_decl);
       if (!context)
        context = global_namespace;
@@ -5919,7 +6399,7 @@ lookup_template_class (tree d1,
                  the values for the enumeration constants may involve
                  template parameters.  And, no one should be interested
                  in the enumeration constants for such a type.  */
-              t = make_node (ENUMERAL_TYPE);
+              t = cxx_make_type (ENUMERAL_TYPE);
               SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
             }
        }
@@ -5933,7 +6413,7 @@ lookup_template_class (tree d1,
 
          /* A local class.  Make sure the decl gets registered properly.  */
          if (context == current_function_decl)
-           pushtag (DECL_NAME (templ), t, /*tag_scope=*/ts_current);
+           pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current);
 
          if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
            /* This instantiation is another name for the primary
@@ -5953,9 +6433,8 @@ lookup_template_class (tree d1,
        {
          TYPE_CONTEXT (t) = FROB_CONTEXT (context);
 
-         type_decl = create_implicit_typedef (DECL_NAME (templ), t);
+         type_decl = create_implicit_typedef (DECL_NAME (gen_tmpl), t);
          DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
-         TYPE_STUB_DECL (t) = type_decl;
          DECL_SOURCE_LOCATION (type_decl)
            = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (template_type));
        }
@@ -5976,65 +6455,32 @@ lookup_template_class (tree d1,
         template is the immediate parent if this is a full
         instantiation.  */
       if (parm_depth == 1 || is_partial_instantiation
-         || !PRIMARY_TEMPLATE_P (templ))
+         || !PRIMARY_TEMPLATE_P (gen_tmpl))
        /* This case is easy; there are no member templates involved.  */
-       found = templ;
+       found = gen_tmpl;
       else
        {
-         /* This is a full instantiation of a member template.  Look
-            for a partial instantiation of which this is an instance.  */
-
-         for (found = DECL_TEMPLATE_INSTANTIATIONS (templ);
-              found; found = TREE_CHAIN (found))
-           {
-             int success;
-             tree tmpl = CLASSTYPE_TI_TEMPLATE (TREE_VALUE (found));
-
-             /* We only want partial instantiations, here, not
-                specializations or full instantiations.  */
-             if (CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_VALUE (found))
-                 || !uses_template_parms (TREE_VALUE (found)))
-               continue;
-
-             /* Temporarily reduce by one the number of levels in the
-                ARGLIST and in FOUND so as to avoid comparing the
-                last set of arguments.  */
-             TREE_VEC_LENGTH (arglist)--;
-             TREE_VEC_LENGTH (TREE_PURPOSE (found)) --;
-
-             /* See if the arguments match.  If they do, then TMPL is
-                the partial instantiation we want.  */
-             success = comp_template_args (TREE_PURPOSE (found), arglist);
-
-             /* Restore the argument vectors to their full size.  */
-             TREE_VEC_LENGTH (arglist)++;
-             TREE_VEC_LENGTH (TREE_PURPOSE (found))++;
-
-             if (success)
-               {
-                 found = tmpl;
-                 break;
-               }
-           }
-
-         if (!found)
-           {
-             /* There was no partial instantiation. This happens
-                where C<T> is a member template of A<T> and it's used
-                in something like
+         /* This is a full instantiation of a member template.  Find
+            the partial instantiation of which this is an instance.  */
+
+         /* Temporarily reduce by one the number of levels in the ARGLIST
+            so as to avoid comparing the last set of arguments.  */
+         TREE_VEC_LENGTH (arglist)--;
+         found = tsubst (gen_tmpl, arglist, complain, NULL_TREE);
+         TREE_VEC_LENGTH (arglist)++;
+         found = CLASSTYPE_TI_TEMPLATE (found);
+       }
 
-                 template <typename T> struct B { A<T>::C<int> m; };
-                 B<float>;
+      SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
 
-                Create the partial instantiation.
-              */
-             TREE_VEC_LENGTH (arglist)--;
-             found = tsubst (templ, arglist, complain, NULL_TREE);
-             TREE_VEC_LENGTH (arglist)++;
-           }
-       }
+      elt.spec = t;
+      slot = (spec_entry **) htab_find_slot_with_hash (type_specializations,
+                                                      &elt, hash, INSERT);
+      *slot = GGC_NEW (spec_entry);
+      **slot = elt;
 
-      SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
+      /* Note this use of the partial instantiation so we can check it
+        later in maybe_process_partial_specialization.  */
       DECL_TEMPLATE_INSTANTIATIONS (templ)
        = tree_cons (arglist, t,
                     DECL_TEMPLATE_INSTANTIATIONS (templ));
@@ -6101,7 +6547,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case ENUMERAL_TYPE:
       if (!TYPE_TEMPLATE_INFO (t))
        *walk_subtrees = 0;
-      else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
+      else if (for_each_template_parm (TI_ARGS (TYPE_TEMPLATE_INFO (t)),
                                       fn, data, pfd->visited, 
                                       pfd->include_nondeduced_p))
        return error_mark_node;
@@ -6642,46 +7088,58 @@ tsubst_friend_function (tree decl, tree args)
            ;
          else
            {
+             tree new_template = TI_TEMPLATE (new_friend_template_info);
+             tree new_args = TI_ARGS (new_friend_template_info);
+
              /* Overwrite whatever template info was there before, if
                 any, with the new template information pertaining to
                 the declaration.  */
              DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
 
              if (TREE_CODE (old_decl) != TEMPLATE_DECL)
-               reregister_specialization (new_friend,
-                                          most_general_template (old_decl),
-                                          old_decl);
+               /* We should have called reregister_specialization in
+                  duplicate_decls.  */
+               gcc_assert (retrieve_specialization (new_template,
+                                                    new_args, 0)
+                           == old_decl);
              else
                {
                  tree t;
-                 tree new_friend_args;
 
+                 /* Indicate that the old function template is a partial
+                    instantiation.  */
                  DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (old_decl))
                    = new_friend_result_template_info;
 
-                 new_friend_args = TI_ARGS (new_friend_template_info);
-                 for (t = DECL_TEMPLATE_SPECIALIZATIONS (old_decl);
+                 gcc_assert (new_template
+                             == most_general_template (new_template));
+                 gcc_assert (new_template != old_decl);
+
+                 /* Reassign any specializations already in the hash table
+                    to the new more general template, and add the
+                    additional template args.  */
+                 for (t = DECL_TEMPLATE_INSTANTIATIONS (old_decl);
                       t != NULL_TREE;
                       t = TREE_CHAIN (t))
                    {
                      tree spec = TREE_VALUE (t);
+                     spec_entry elt;
+
+                     elt.tmpl = old_decl;
+                     elt.args = DECL_TI_ARGS (spec);
+                     elt.spec = NULL_TREE;
+
+                     htab_remove_elt (decl_specializations, &elt);
 
                      DECL_TI_ARGS (spec)
-                       = add_outermost_template_args (new_friend_args,
+                       = add_outermost_template_args (new_args,
                                                       DECL_TI_ARGS (spec));
-                   }
 
-                 /* Now, since specializations are always supposed to
-                    hang off of the most general template, we must move
-                    them.  */
-                 t = most_general_template (old_decl);
-                 if (t != old_decl)
-                   {
-                     DECL_TEMPLATE_SPECIALIZATIONS (t)
-                       = chainon (DECL_TEMPLATE_SPECIALIZATIONS (t),
-                                  DECL_TEMPLATE_SPECIALIZATIONS (old_decl));
-                     DECL_TEMPLATE_SPECIALIZATIONS (old_decl) = NULL_TREE;
+                     register_specialization
+                       (spec, new_template, DECL_TI_ARGS (spec), true, 0);
+
                    }
+                 DECL_TEMPLATE_INSTANTIATIONS (old_decl) = NULL_TREE;
                }
            }
 
@@ -6945,17 +7403,24 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
 static void
 perform_typedefs_access_check (tree tmpl, tree targs)
 {
-  tree t;
+  location_t saved_location;
+  int i;
+  qualified_typedef_usage_t *iter;
 
   if (!tmpl
-      || (TREE_CODE (tmpl) != RECORD_TYPE
+      || (!CLASS_TYPE_P (tmpl)
          && TREE_CODE (tmpl) != FUNCTION_DECL))
     return;
 
-  for (t = get_types_needing_access_check (tmpl); t; t = TREE_CHAIN (t))
+  saved_location = input_location;
+  for (i = 0;
+       VEC_iterate (qualified_typedef_usage_t,
+                   get_types_needing_access_check (tmpl),
+                   i, iter);
+       ++i)
     {
-      tree type_decl = TREE_PURPOSE (t);
-      tree type_scope = TREE_VALUE (t);
+      tree type_decl = iter->typedef_decl;
+      tree type_scope = iter->context;
 
       if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
        continue;
@@ -6965,9 +7430,13 @@ perform_typedefs_access_check (tree tmpl, tree targs)
       if (uses_template_parms (type_scope))
        type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
 
+      /* Make access check error messages point to the location
+         of the use of the typedef.  */
+      input_location = iter->locus;
       perform_or_defer_access_check (TYPE_BINFO (type_scope),
                                     type_decl, type_decl);
     }
+    input_location = saved_location;
 }
 
 tree
@@ -6977,13 +7446,14 @@ instantiate_class_template (tree type)
   tree typedecl;
   tree pbinfo;
   tree base_list;
+  unsigned int saved_maximum_field_alignment;
 
   if (type == error_mark_node)
     return error_mark_node;
 
   if (TYPE_BEING_DEFINED (type)
       || COMPLETE_TYPE_P (type)
-      || dependent_type_p (type))
+      || uses_template_parms (type))
     return type;
 
   /* Figure out which template is being instantiated.  */
@@ -7037,6 +7507,9 @@ instantiate_class_template (tree type)
   push_deferring_access_checks (dk_no_deferred);
 
   push_to_top_level ();
+  /* Use #pragma pack from the template context.  */
+  saved_maximum_field_alignment = maximum_field_alignment;
+  maximum_field_alignment = TYPE_PRECISION (pattern);
 
   SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
 
@@ -7452,6 +7925,7 @@ instantiate_class_template (tree type)
   perform_typedefs_access_check (pattern, args);
   perform_deferred_access_checks ();
   pop_nested_class ();
+  maximum_field_alignment = saved_maximum_field_alignment;
   pop_from_top_level ();
   pop_deferring_access_checks ();
   pop_tinst_level ();
@@ -7495,7 +7969,7 @@ make_fnparm_pack (tree spec_parm)
   tree parmvec;
   tree parmtypevec;
   tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
-  tree argtypepack = make_node (TYPE_ARGUMENT_PACK);
+  tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
   int i, len = list_length (spec_parm);
 
   /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters.  */
@@ -7553,7 +8027,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
              /* This can happen for a parameter name used later in a function
                 declaration (such as in a late-specified return type).  Just
                 make a dummy decl, since it's only used for its type.  */
-             gcc_assert (skip_evaluation);
+             gcc_assert (cp_unevaluated_operand != 0);
              arg_pack = tsubst_decl (parm_pack, args, complain);
              arg_pack = make_fnparm_pack (arg_pack);
            }
@@ -7616,6 +8090,10 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
             }
           else if (len != my_len)
             {
+             if (incomplete)
+               /* We got explicit args for some packs but not others;
+                  do nothing now and try again after deduction.  */
+               return t;
               if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
                 error ("mismatched argument pack lengths while expanding "
                        "%<%T%>",
@@ -7644,8 +8122,15 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
      and return a PACK_EXPANSION_*. The caller will need to deal with
      that.  */
   if (unsubstituted_packs)
-    return make_pack_expansion (tsubst (pattern, args, complain, 
-                                       in_decl));
+    {
+      tree new_pat;
+      if (TREE_CODE (t) == EXPR_PACK_EXPANSION)
+       new_pat = tsubst_expr (pattern, args, complain, in_decl,
+                              /*integral_constant_expression_p=*/false);
+      else
+       new_pat = tsubst (pattern, args, complain, in_decl);
+      return make_pack_expansion (new_pat);
+    }
 
   /* We could not find any argument packs that work.  */
   if (len < 0)
@@ -7755,6 +8240,36 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
   return result;
 }
 
+/* Given PARM_DECL PARM, find the corresponding PARM_DECL in the template
+   TMPL.  We do this using DECL_PARM_INDEX, which should work even with
+   parameter packs; all parms generated from a function parameter pack will
+   have the same DECL_PARM_INDEX.  */
+
+tree
+get_pattern_parm (tree parm, tree tmpl)
+{
+  tree pattern = DECL_TEMPLATE_RESULT (tmpl);
+  tree patparm;
+
+  if (DECL_ARTIFICIAL (parm))
+    {
+      for (patparm = DECL_ARGUMENTS (pattern);
+          patparm; patparm = TREE_CHAIN (patparm))
+       if (DECL_ARTIFICIAL (patparm)
+           && DECL_NAME (parm) == DECL_NAME (patparm))
+         break;
+    }
+  else
+    {
+      patparm = FUNCTION_FIRST_USER_PARM (DECL_TEMPLATE_RESULT (tmpl));
+      patparm = chain_index (DECL_PARM_INDEX (parm)-1, patparm);
+      gcc_assert (DECL_PARM_INDEX (patparm)
+                 == DECL_PARM_INDEX (parm));
+    }
+
+  return patparm;
+}
+
 /* Substitute ARGS into the vector or list of template arguments T.  */
 
 static tree
@@ -7789,7 +8304,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       else if (ARGUMENT_PACK_P (orig_arg))
         {
           /* Substitute into each of the arguments.  */
-          new_arg = make_node (TREE_CODE (orig_arg));
+          new_arg = TYPE_P (orig_arg)
+            ? cxx_make_type (TREE_CODE (orig_arg))
+            : make_node (TREE_CODE (orig_arg));
           
           SET_ARGUMENT_PACK_ARGS (
             new_arg,
@@ -7944,11 +8461,14 @@ tsubst_aggr_type (tree t,
          tree argvec;
          tree context;
          tree r;
-         bool saved_skip_evaluation;
+         int saved_unevaluated_operand;
+         int saved_inhibit_evaluation_warnings;
 
          /* In "sizeof(X<I>)" we need to evaluate "I".  */
-         saved_skip_evaluation = skip_evaluation;
-         skip_evaluation = false;
+         saved_unevaluated_operand = cp_unevaluated_operand;
+         cp_unevaluated_operand = 0;
+         saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+         c_inhibit_evaluation_warnings = 0;
 
          /* First, determine the context for the type we are looking
             up.  */
@@ -7983,7 +8503,8 @@ tsubst_aggr_type (tree t,
              r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
            }
 
-         skip_evaluation = saved_skip_evaluation;
+         cp_unevaluated_operand = saved_unevaluated_operand;
+         c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
          return r;
        }
@@ -8047,11 +8568,11 @@ tsubst_default_argument (tree fn, tree type, tree arg)
       cp_function_chain->x_current_class_ref = saved_class_ref;
     }
 
-  pop_access_scope (fn);
-
   /* Make sure the default argument is reasonable.  */
   arg = check_default_argument (type, arg);
 
+  pop_access_scope (fn);
+
   return arg;
 }
 
@@ -8086,9 +8607,11 @@ tsubst_default_arguments (tree fn)
 static tree
 tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 {
+#define RETURN(EXP) do { r = (EXP); goto out; } while(0)
   location_t saved_loc;
   tree r = NULL_TREE;
   tree in_decl = t;
+  hashval_t hash = 0;
 
   /* Set the filename and linenumber to improve error-reporting.  */
   saved_loc = input_location;
@@ -8099,8 +8622,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
     case TEMPLATE_DECL:
       {
        /* We can get here when processing a member function template,
-          member class template, and template template parameter of
-          a template class.  */
+          member class template, or template template parameter.  */
        tree decl = DECL_TEMPLATE_RESULT (t);
        tree spec;
        tree tmpl_args;
@@ -8111,7 +8633,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            /* Template template parameter is treated here.  */
            tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            if (new_type == error_mark_node)
-             return error_mark_node;
+             RETURN (error_mark_node);
 
            r = copy_decl (t);
            TREE_CHAIN (r) = NULL_TREE;
@@ -8142,15 +8664,15 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                                          complain, in_decl);
        --processing_template_decl;
        if (full_args == error_mark_node)
-         return error_mark_node;
+         RETURN (error_mark_node);
 
-       /* tsubst_template_args doesn't copy the vector if
-          nothing changed.  But, *something* should have
-          changed.  */
-       gcc_assert (full_args != tmpl_args);
+       /* If this is a default template template argument,
+          tsubst might not have changed anything.  */
+       if (full_args == tmpl_args)
+         RETURN (t);
 
-       spec = retrieve_specialization (t, full_args,
-                                       /*class_specializations_p=*/true);
+       hash = hash_tmpl_and_args (t, full_args);
+       spec = retrieve_specialization (t, full_args, hash);
        if (spec != NULL_TREE)
          {
            r = spec;
@@ -8166,7 +8688,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
        TREE_CHAIN (r) = NULL_TREE;
 
-       DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
+       DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
 
        if (TREE_CODE (decl) == TYPE_DECL)
          {
@@ -8175,7 +8697,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            --processing_template_decl;
            if (new_type == error_mark_node)
-             return error_mark_node;
+             RETURN (error_mark_node);
 
            TREE_TYPE (r) = new_type;
            CLASSTYPE_TI_TEMPLATE (new_type) = r;
@@ -8190,7 +8712,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            new_decl = tsubst (decl, args, complain, in_decl);
            --processing_template_decl;
            if (new_decl == error_mark_node)
-             return error_mark_node;
+             RETURN (error_mark_node);
 
            DECL_TEMPLATE_RESULT (r) = new_decl;
            DECL_TI_TEMPLATE (new_decl) = r;
@@ -8217,7 +8739,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          /* Record this non-type partial instantiation.  */
          register_specialization (r, t,
                                   DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)),
-                                  false);
+                                  false, hash);
       }
       break;
 
@@ -8248,7 +8770,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            dependent_p = value_dependent_expression_p (t);
            --processing_template_decl;
            if (!dependent_p)
-             return t;
+             RETURN (t);
 
            /* Calculate the most general template of which R is a
               specialization, and the complete set of arguments used to
@@ -8259,8 +8781,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                                           args, complain, in_decl);
 
            /* Check to see if we already have this specialization.  */
-           spec = retrieve_specialization (gen_tmpl, argvec,
-                                           /*class_specializations_p=*/false);
+           hash = hash_tmpl_and_args (gen_tmpl, argvec);
+           spec = retrieve_specialization (gen_tmpl, argvec, hash);
 
            if (spec)
              {
@@ -8339,7 +8861,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          }
        type = tsubst (TREE_TYPE (t), args, complain, in_decl);
        if (type == error_mark_node)
-         return error_mark_node;
+         RETURN (error_mark_node);
 
        /* We do NOT check for matching decls pushed separately at this
           point, as they may not represent instantiations of this
@@ -8379,13 +8901,15 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        DECL_SAVED_TREE (r) = NULL_TREE;
        DECL_STRUCT_FUNCTION (r) = NULL;
        TREE_USED (r) = 0;
-       if (DECL_CLONED_FUNCTION (r))
-         {
-           DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t),
-                                              args, complain, t);
-           TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r));
-           TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
-         }
+       /* We'll re-clone as appropriate in instantiate_template.  */
+       DECL_CLONED_FUNCTION (r) = NULL_TREE;
+
+       /* If we aren't complaining now, return on error before we register
+          the specialization so that we'll complain eventually.  */
+       if ((complain & tf_error) == 0
+           && IDENTIFIER_OPNAME_P (DECL_NAME (r))
+           && !grok_op_properties (r, /*complain=*/false))
+         RETURN (error_mark_node);
 
        /* Set up the DECL_TEMPLATE_INFO for R.  There's no need to do
           this in the special friend case mentioned above where
@@ -8393,9 +8917,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (gen_tmpl)
          {
            DECL_TEMPLATE_INFO (r)
-             = tree_cons (gen_tmpl, argvec, NULL_TREE);
+             = build_template_info (gen_tmpl, argvec);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
-           register_specialization (r, gen_tmpl, argvec, false);
+           register_specialization (r, gen_tmpl, argvec, false, hash);
 
            /* We're not supposed to instantiate default arguments
               until they are called, for a template.  But, for a
@@ -8438,9 +8962,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            if (PRIMARY_TEMPLATE_P (gen_tmpl))
              clone_function_decl (r, /*update_method_vec_p=*/0);
          }
-       else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))
-                && !grok_op_properties (r, (complain & tf_error) != 0))
-         return error_mark_node;
+       else if ((complain & tf_error) != 0
+                && IDENTIFIER_OPNAME_P (DECL_NAME (r))
+                && !grok_op_properties (r, /*complain=*/true))
+         RETURN (error_mark_node);
 
        if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
          SET_DECL_FRIEND_CONTEXT (r,
@@ -8456,6 +8981,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              = remove_attribute ("visibility", DECL_ATTRIBUTES (r));
          }
        determine_visibility (r);
+       if (DECL_DEFAULTED_OUTSIDE_CLASS_P (r)
+           && !processing_template_decl)
+         defaulted_late_check (r);
 
        apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
                                        args, complain, in_decl);
@@ -8481,7 +9009,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
             if (spec 
                 && TREE_CODE (spec) == PARM_DECL
                 && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION)
-              return spec;
+              RETURN (spec);
 
             /* Expand the TYPE_PACK_EXPANSION that provides the types for
                the parameters in this function parameter pack.  */
@@ -8494,8 +9022,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                 /* Zero-length parameter packs are boring. Just substitute
                    into the chain.  */
                 if (len == 0)
-                  return tsubst (TREE_CHAIN (t), args, complain, 
-                                 TREE_CHAIN (t));
+                  RETURN (tsubst (TREE_CHAIN (t), args, complain,
+                                 TREE_CHAIN (t)));
               }
             else
               {
@@ -8516,6 +9044,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
             if (DECL_TEMPLATE_PARM_P (t))
               SET_DECL_TEMPLATE_PARM_P (r);
 
+           /* An argument of a function parameter pack is not a parameter
+              pack.  */
+           FUNCTION_PARAMETER_PACK_P (r) = false;
+
             if (expanded_types)
               /* We're on the Ith parameter of the function parameter
                  pack.  */
@@ -8581,7 +9113,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        r = copy_decl (t);
        type = tsubst (TREE_TYPE (t), args, complain, in_decl);
        if (type == error_mark_node)
-         return error_mark_node;
+         RETURN (error_mark_node);
        TREE_TYPE (r) = type;
        cp_apply_type_quals_to_decl (cp_type_quals (type), r);
 
@@ -8644,7 +9176,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               we've copied the type for a typedef.  */
            type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            if (type == error_mark_node)
-             return error_mark_node;
+             RETURN (error_mark_node);
            r = TYPE_NAME (type);
            break;
          }
@@ -8685,9 +9217,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                tmpl = DECL_TI_TEMPLATE (t);
                gen_tmpl = most_general_template (tmpl);
                argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
-               spec = (retrieve_specialization 
-                       (gen_tmpl, argvec,
-                        /*class_specializations_p=*/false));
+               hash = hash_tmpl_and_args (gen_tmpl, argvec);
+               spec = retrieve_specialization (gen_tmpl, argvec, hash);
              }
          }
        else
@@ -8718,7 +9249,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_INITIALIZED_P (r) = 0;
            DECL_TEMPLATE_INSTANTIATED (r) = 0;
            if (type == error_mark_node)
-             return error_mark_node;
+             RETURN (error_mark_node);
            if (TREE_CODE (type) == FUNCTION_TYPE)
              {
                /* It may seem that this case cannot occur, since:
@@ -8738,7 +9269,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                       /* R is not yet sufficiently initialized, so we
                          just use its name.  */
                       DECL_NAME (r));
-               return error_mark_node;
+               RETURN (error_mark_node);
              }
            type = complete_type (type);
            DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
@@ -8799,10 +9330,26 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               processing here.  */
            DECL_EXTERNAL (r) = 1;
 
-           register_specialization (r, gen_tmpl, argvec, false);
-           DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE);
+           register_specialization (r, gen_tmpl, argvec, false, hash);
+           DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
          }
+       else if (cp_unevaluated_operand)
+         {
+           /* We're substituting this var in a decltype outside of its
+              scope, such as for a lambda return type.  Don't add it to
+              local_specializations, do perform auto deduction.  */
+           tree auto_node = type_uses_auto (type);
+           tree init
+             = tsubst_expr (DECL_INITIAL (t), args, complain, in_decl,
+                            /*constant_expression_p=*/false);
+
+           if (auto_node && init && describable_type (init))
+             {
+               type = do_auto_deduction (type, init, auto_node);
+               TREE_TYPE (r) = type;
+             }
+         }
        else
          register_local_specialization (r, t);
 
@@ -8818,7 +9365,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
     default:
       gcc_unreachable ();
     }
+#undef RETURN
 
+ out:
   /* Restore the file and line information.  */
   input_location = saved_loc;
 
@@ -9129,7 +9678,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        {
          tree tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
          tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl);
-         r = retrieve_specialization (tmpl, gen_args, false);
+         r = retrieve_specialization (tmpl, gen_args, 0);
        }
       else if (DECL_FUNCTION_SCOPE_P (decl)
               && DECL_TEMPLATE_INFO (DECL_CONTEXT (decl))
@@ -9391,7 +9940,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                      return error_mark_node;
 
                    TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
-                     = tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
+                     = build_template_info (TYPE_TI_TEMPLATE (t), argvec);
                  }
              }
            break;
@@ -9560,13 +10109,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          {
            /* The type of the implicit object parameter gets its
               cv-qualifiers from the FUNCTION_TYPE. */
-           tree method_type;
-           tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
-                                                     cp_type_quals (type));
            tree memptr;
-           method_type = build_method_type_directly (this_type,
-                                                     TREE_TYPE (type),
-                                                     TYPE_ARG_TYPES (type));
+           tree method_type = build_memfn_type (type, r, cp_type_quals (type));
            memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
            return cp_build_qualified_type_real (memptr, cp_type_quals (t),
                                                 complain);
@@ -9650,7 +10194,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return fold_build2 (TREE_CODE (t), TREE_TYPE (t), e1, e2);
+       return fold_build2_loc (input_location,
+                           TREE_CODE (t), TREE_TYPE (t), e1, e2);
       }
 
     case NEGATE_EXPR:
@@ -9660,7 +10205,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e == error_mark_node)
          return error_mark_node;
 
-       return fold_build1 (TREE_CODE (t), TREE_TYPE (t), e);
+       return fold_build1_loc (input_location, TREE_CODE (t), TREE_TYPE (t), e);
       }
 
     case TYPENAME_TYPE:
@@ -9689,7 +10234,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               But, such constructs have already been resolved by this
               point, so here CTX really should have complete type, unless
               it's a partial instantiation.  */
-           ctx = complete_type (ctx);
+           if (!(complain & tf_no_class_instantiations))
+             ctx = complete_type (ctx);
            if (!COMPLETE_TYPE_P (ctx))
              {
                if (complain & tf_error)
@@ -9768,10 +10314,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree type;
 
-       type = finish_typeof (tsubst_expr 
-                             (TYPEOF_TYPE_EXPR (t), args,
-                              complain, in_decl,
-                              /*integral_constant_expression_p=*/false));
+       ++cp_unevaluated_operand;
+       ++c_inhibit_evaluation_warnings;
+
+       type = tsubst_expr (TYPEOF_TYPE_EXPR (t), args,
+                           complain, in_decl,
+                           /*integral_constant_expression_p=*/false);
+
+       --cp_unevaluated_operand;
+       --c_inhibit_evaluation_warnings;
+
+       type = finish_typeof (type);
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
                                             | cp_type_quals (type),
@@ -9782,17 +10335,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree type;
 
-       ++skip_evaluation;
+       ++cp_unevaluated_operand;
+       ++c_inhibit_evaluation_warnings;
 
        type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args,
                            complain, in_decl,
                            /*integral_constant_expression_p=*/false);
 
-       --skip_evaluation;
+       --cp_unevaluated_operand;
+       --c_inhibit_evaluation_warnings;
 
-       type =
-          finish_decltype_type (type,
-                                DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
+       if (DECLTYPE_FOR_LAMBDA_CAPTURE (t))
+         type = lambda_capture_field_type (type);
+       else if (DECLTYPE_FOR_LAMBDA_RETURN (t))
+         type = lambda_return_type (type);
+       else
+         type = finish_decltype_type
+           (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
                                             | cp_type_quals (type),
@@ -9802,7 +10361,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
-        tree r = make_node (TREE_CODE (t));
+        tree r = TYPE_P (t)
+          ? cxx_make_type (TREE_CODE (t))
+          : make_node (TREE_CODE (t));
         tree packed_out = 
           tsubst_template_args (ARGUMENT_PACK_ARGS (t), 
                                 args,
@@ -9851,7 +10412,7 @@ tsubst_baselink (tree baselink, tree object_type,
     qualifying_scope = tsubst (qualifying_scope, args,
                               complain, in_decl);
     fns = BASELINK_FUNCTIONS (baselink);
-    optype = BASELINK_OPTYPE (baselink);
+    optype = tsubst (BASELINK_OPTYPE (baselink), args, complain, in_decl);
     if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
       {
        template_id_p = true;
@@ -9862,6 +10423,8 @@ tsubst_baselink (tree baselink, tree object_type,
                                                complain, in_decl);
       }
     name = DECL_NAME (get_first_fn (fns));
+    if (IDENTIFIER_TYPENAME_P (name))
+      name = mangle_conv_op_name_for_type (optype);
     baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
 
     /* If lookup found a single function, mark it as used at this
@@ -9880,8 +10443,7 @@ tsubst_baselink (tree baselink, tree object_type,
                    BASELINK_FUNCTIONS (baselink),
                    template_args);
     /* Update the conversion operator type.  */
-    BASELINK_OPTYPE (baselink) 
-      = tsubst (optype, args, complain, in_decl);
+    BASELINK_OPTYPE (baselink) = optype;
 
     if (!object_type)
       object_type = current_class_type;
@@ -10047,7 +10609,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          /* This can happen for a parameter name used later in a function
             declaration (such as in a late-specified return type).  Just
             make a dummy decl, since it's only used for its type.  */
-         gcc_assert (skip_evaluation);   
+         gcc_assert (cp_unevaluated_operand != 0);
          /* We copy T because want to tsubst the PARM_DECL only,
             not the following PARM_DECLs that are chained to T.  */
          c = copy_node (t);
@@ -10538,7 +11100,7 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
   if (purpose)
     purpose = RECUR (purpose);
   value = TREE_VALUE (t);
-  if (value)
+  if (value && TREE_CODE (value) != LABEL_DECL)
     value = RECUR (value);
   chain = TREE_CHAIN (t);
   if (chain && chain != void_type_node)
@@ -10809,7 +11371,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                          init = t;
                      }
 
-                   finish_decl (decl, init, NULL_TREE, NULL_TREE);
+                   cp_finish_decl (decl, init, false, NULL_TREE, 0);
                  }
              }
          }
@@ -10930,7 +11492,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
         RECUR (ASM_STRING (t)),
         tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
         tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
-        tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl));
+        tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl),
+        tsubst_copy_asm_operands (ASM_LABELS (t), args, complain, in_decl));
       {
        tree asm_expr = tmp;
        if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
@@ -11407,11 +11970,13 @@ tsubst_copy_and_build (tree t,
        }
       else
        {
-         ++skip_evaluation;
+         ++cp_unevaluated_operand;
+         ++c_inhibit_evaluation_warnings;
          op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
                                       /*function_p=*/false,
                                       /*integral_constant_expression_p=*/false);
-         --skip_evaluation;
+         --cp_unevaluated_operand;
+         --c_inhibit_evaluation_warnings;
        }
       if (TYPE_P (op1))
        return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), 
@@ -11993,6 +12558,39 @@ tsubst_copy_and_build (tree t,
        }
       return t;
 
+    case LAMBDA_EXPR:
+      {
+       tree r = build_lambda_expr ();
+
+       tree type = tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
+       TREE_TYPE (r) = type;
+       CLASSTYPE_LAMBDA_EXPR (type) = r;
+
+       LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (r)
+         = LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (t);
+       LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t);
+       LAMBDA_EXPR_DISCRIMINATOR (r)
+         = (LAMBDA_EXPR_DISCRIMINATOR (t));
+       LAMBDA_EXPR_CAPTURE_LIST (r)
+         = RECUR (LAMBDA_EXPR_CAPTURE_LIST (t));
+       LAMBDA_EXPR_THIS_CAPTURE (r)
+         = RECUR (LAMBDA_EXPR_THIS_CAPTURE (t));
+       LAMBDA_EXPR_EXTRA_SCOPE (r)
+         = RECUR (LAMBDA_EXPR_EXTRA_SCOPE (t));
+
+       /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
+       determine_visibility (TYPE_NAME (type));
+       /* Now that we know visibility, instantiate the type so we have a
+          declaration of the op() for later calls to lambda_function.  */
+       complete_type (type);
+
+       type = tsubst (LAMBDA_EXPR_RETURN_TYPE (t), args, complain, in_decl);
+       if (type)
+         apply_lambda_return_type (r, type);
+
+       return build_lambda_object (r);
+      }
+
     default:
       /* Handle Objective-C++ constructs, if appropriate.  */
       {
@@ -12034,8 +12632,11 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain)
         of a class or enumeration declared in a local scope)
         shall not be used to declare an entity with linkage.
         This implies that names with no linkage cannot be used as
-        template arguments.  */
-      tree nt = no_linkage_check (t, /*relaxed_p=*/false);
+        template arguments
+
+        DR 757 relaxes this restriction for C++0x.  */
+      tree nt = (cxx_dialect > cxx98 ? NULL_TREE
+                : no_linkage_check (t, /*relaxed_p=*/false));
 
       if (nt)
        {
@@ -12093,8 +12694,9 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
    the template arguments in TARG_PTR.  */
 
 tree
-instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
+instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
 {
+  tree targ_ptr = orig_args;
   tree fndecl;
   tree gen_tmpl;
   tree spec;
@@ -12111,8 +12713,10 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
       tree spec;
       tree clone;
 
-      spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr,
-                                  complain);
+      /* Use DECL_ABSTRACT_ORIGIN because only FUNCTION_DECLs have
+        DECL_CLONED_FUNCTION.  */
+      spec = instantiate_template (DECL_ABSTRACT_ORIGIN (tmpl),
+                                  targ_ptr, complain);
       if (spec == error_mark_node)
        return error_mark_node;
 
@@ -12126,26 +12730,25 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
     }
 
   /* Check to see if we already have this specialization.  */
-  spec = retrieve_specialization (tmpl, targ_ptr,
-                                 /*class_specializations_p=*/false);
-  if (spec != NULL_TREE)
-    return spec;
-
   gen_tmpl = most_general_template (tmpl);
   if (tmpl != gen_tmpl)
-    {
-      /* The TMPL is a partial instantiation.  To get a full set of
-        arguments we must add the arguments used to perform the
-        partial instantiation.  */
-      targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl),
-                                             targ_ptr);
+    /* The TMPL is a partial instantiation.  To get a full set of
+       arguments we must add the arguments used to perform the
+       partial instantiation.  */
+    targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl),
+                                           targ_ptr);
 
-      /* Check to see if we already have this specialization.  */
-      spec = retrieve_specialization (gen_tmpl, targ_ptr,
-                                     /*class_specializations_p=*/false);
-      if (spec != NULL_TREE)
-       return spec;
-    }
+  /* It would be nice to avoid hashing here and then again in tsubst_decl,
+     but it doesn't seem to be on the hot path.  */
+  spec = retrieve_specialization (gen_tmpl, targ_ptr, 0);
+
+  gcc_assert (tmpl == gen_tmpl
+             || ((fndecl = retrieve_specialization (tmpl, orig_args, 0))
+                 == spec)
+             || fndecl == NULL_TREE);
+
+  if (spec != NULL_TREE)
+    return spec;
 
   if (check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (targ_ptr),
                               complain))
@@ -12481,7 +13084,17 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
       }
 
     case DEDUCE_EXACT:
-      /* There is nothing to do in this case.  */
+      /* Core issue #873: Do the DR606 thing (see below) for these cases,
+        too, but here handle it by stripping the reference from PARM
+        rather than by adding it to ARG.  */
+      if (TREE_CODE (*parm) == REFERENCE_TYPE
+         && TYPE_REF_IS_RVALUE (*parm)
+         && TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
+         && cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
+         && TREE_CODE (*arg) == REFERENCE_TYPE
+         && !TYPE_REF_IS_RVALUE (*arg))
+       *parm = TREE_TYPE (*parm);
+      /* Nothing else to do in this case.  */
       return 0;
 
     default:
@@ -12743,8 +13356,11 @@ type_unification_real (tree tparms,
             to explicitly check cxx_dialect here.  */
           if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
             {
-              tree arg = tsubst (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)), 
-                                 targs, tf_none, NULL_TREE);
+             tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+             tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
+              arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE);
+             arg = convert_template_argument (parm, arg, targs, tf_none,
+                                              i, NULL_TREE);
               if (arg == error_mark_node)
                 return 1;
               else
@@ -12767,7 +13383,7 @@ type_unification_real (tree tparms,
                   TREE_CONSTANT (arg) = 1;
                 }
               else
-                arg = make_node (TYPE_ARGUMENT_PACK);
+                arg = cxx_make_type (TYPE_ARGUMENT_PACK);
 
               SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0));
 
@@ -12892,6 +13508,105 @@ resolve_overloaded_unification (tree tparms,
   return false;
 }
 
+/* Core DR 115: In contexts where deduction is done and fails, or in
+   contexts where deduction is not done, if a template argument list is
+   specified and it, along with any default template arguments, identifies
+   a single function template specialization, then the template-id is an
+   lvalue for the function template specialization.  */
+
+tree
+resolve_nondeduced_context (tree orig_expr)
+{
+  tree expr, offset, baselink;
+  bool addr;
+
+  if (!type_unknown_p (orig_expr))
+    return orig_expr;
+
+  expr = orig_expr;
+  addr = false;
+  offset = NULL_TREE;
+  baselink = NULL_TREE;
+
+  if (TREE_CODE (expr) == ADDR_EXPR)
+    {
+      expr = TREE_OPERAND (expr, 0);
+      addr = true;
+    }
+  if (TREE_CODE (expr) == OFFSET_REF)
+    {
+      offset = expr;
+      expr = TREE_OPERAND (expr, 1);
+    }
+  if (TREE_CODE (expr) == BASELINK)
+    {
+      baselink = expr;
+      expr = BASELINK_FUNCTIONS (expr);
+    }
+
+  if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
+    {
+      int good = 0;
+      tree goodfn = NULL_TREE;
+
+      /* If we got some explicit template args, we need to plug them into
+        the affected templates before we try to unify, in case the
+        explicit args will completely resolve the templates in question.  */
+
+      tree expl_subargs = TREE_OPERAND (expr, 1);
+      tree arg = TREE_OPERAND (expr, 0);
+      tree badfn = NULL_TREE;
+      tree badargs = NULL_TREE;
+
+      for (; arg; arg = OVL_NEXT (arg))
+       {
+         tree fn = OVL_CURRENT (arg);
+         tree subargs, elem;
+
+         if (TREE_CODE (fn) != TEMPLATE_DECL)
+           continue;
+
+         ++processing_template_decl;
+         subargs = get_bindings (fn, DECL_TEMPLATE_RESULT (fn),
+                                 expl_subargs, /*check_ret=*/false);
+         if (subargs && !any_dependent_template_arguments_p (subargs))
+           {
+             elem = instantiate_template (fn, subargs, tf_none);
+             if (elem == error_mark_node)
+               {
+                 badfn = fn;
+                 badargs = subargs;
+               }
+             else if (elem && (!goodfn || !decls_match (goodfn, elem)))
+               {
+                 goodfn = elem;
+                 ++good;
+               }
+           }
+         --processing_template_decl;
+       }
+      if (good == 1)
+       {
+         expr = goodfn;
+         if (baselink)
+           expr = build_baselink (BASELINK_BINFO (baselink),
+                                  BASELINK_ACCESS_BINFO (baselink),
+                                  expr, BASELINK_OPTYPE (baselink));
+         if (offset)
+           expr = build2 (OFFSET_REF, TREE_TYPE (expr),
+                          TREE_OPERAND (offset, 0), expr);
+         if (addr)
+           expr = build_address (expr);
+         return expr;
+       }
+      else if (good == 0 && badargs)
+       /* There were no good options and at least one bad one, so let the
+          user know what the problem is.  */
+       instantiate_template (badfn, badargs, tf_warning_or_error);
+    }
+  return orig_expr;
+}
+
 /* Subroutine of resolve_overloaded_unification; does deduction for a single
    overload.  Fills TARGS with any deduced arguments, or error_mark_node if
    different overloads deduce different arguments for a given parm.
@@ -13344,7 +14059,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
               TREE_CONSTANT (result) = 1;
             }
           else
-            result = make_node (TYPE_ARGUMENT_PACK);
+            result = cxx_make_type (TYPE_ARGUMENT_PACK);
 
           SET_ARGUMENT_PACK_ARGS (result, new_args);
 
@@ -13464,6 +14179,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
     {
       tree elt, elttype;
       unsigned i;
+      tree orig_parm = parm;
+
+      /* Replace T with std::initializer_list<T> for deduction.  */
+      if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+         && flag_deduce_init_list)
+       parm = listify (parm);
 
       if (!is_std_init_list (parm))
        /* We can only deduce from an initializer list argument if the
@@ -13489,6 +14210,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          if (unify (tparms, targs, elttype, elt, elt_strict))
            return 1;
        }
+
+      /* If the std::initializer_list<T> deduction worked, replace the
+        deduced A with std::initializer_list<A>.  */
+      if (orig_parm != parm)
+       {
+         idx = TEMPLATE_TYPE_IDX (orig_parm);
+         targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
+         targ = listify (targ);
+         TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = targ;
+       }
       return 0;
     }
 
@@ -13866,12 +14597,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          /* If only one of the bounds used a MINUS_EXPR, compensate
             by adding one to the other bound.  */
          if (parm_cst && !arg_cst)
-           parm_max = fold_build2 (PLUS_EXPR,
+           parm_max = fold_build2_loc (input_location, PLUS_EXPR,
                                    integer_type_node,
                                    parm_max,
                                    integer_one_node);
          else if (arg_cst && !parm_cst)
-           arg_max = fold_build2 (PLUS_EXPR,
+           arg_max = fold_build2_loc (input_location, PLUS_EXPR,
                                   integer_type_node,
                                   arg_max,
                                   integer_one_node);
@@ -14225,6 +14956,35 @@ mark_decl_instantiated (tree result, int extern_p)
   DECL_INTERFACE_KNOWN (result) = 1;
 }
 
+/* Subroutine of more_specialized_fn: check whether TARGS is missing any
+   important template arguments.  If any are missing, we check whether
+   they're important by using error_mark_node for substituting into any
+   args that were used for partial ordering (the ones between ARGS and END)
+   and seeing if it bubbles up.  */
+
+static bool
+check_undeduced_parms (tree targs, tree args, tree end)
+{
+  bool found = false;
+  int i;
+  for (i = TREE_VEC_LENGTH (targs) - 1; i >= 0; --i)
+    if (TREE_VEC_ELT (targs, i) == NULL_TREE)
+      {
+       found = true;
+       TREE_VEC_ELT (targs, i) = error_mark_node;
+      }
+  if (found)
+    {
+      for (; args != end; args = TREE_CHAIN (args))
+       {
+         tree substed = tsubst (TREE_VALUE (args), targs, tf_none, NULL_TREE);
+         if (substed == error_mark_node)
+           return true;
+       }
+    }
+  return false;
+}
+
 /* Given two function templates PAT1 and PAT2, return:
 
    1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
@@ -14248,8 +15008,12 @@ mark_decl_instantiated (tree result, int extern_p)
    neither is more cv-qualified, they both are equal).  Unlike regular
    deduction, after all the arguments have been deduced in this way,
    we do *not* verify the deduced template argument values can be
-   substituted into non-deduced contexts, nor do we have to verify
-   that all template arguments have been deduced.  */
+   substituted into non-deduced contexts.
+
+   The logic can be a bit confusing here, because we look at deduce1 and
+   targs1 to see if pat2 is at least as specialized, and vice versa; if we
+   can find template arguments for pat1 to make arg1 look like arg2, that
+   means that arg2 is at least as specialized as arg1.  */
 
 int
 more_specialized_fn (tree pat1, tree pat2, int len)
@@ -14262,8 +15026,9 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   tree tparms2 = DECL_INNERMOST_TEMPLATE_PARMS (pat2);
   tree args1 = TYPE_ARG_TYPES (TREE_TYPE (decl1));
   tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2));
-  int better1 = 0;
-  int better2 = 0;
+  tree origs1, origs2;
+  bool lose1 = false;
+  bool lose2 = false;
 
   /* Remove the this parameter from non-static member functions.  If
      one is a non-static member function and the other is not a static
@@ -14302,6 +15067,9 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
   processing_template_decl++;
 
+  origs1 = args1;
+  origs2 = args2;
+
   while (len--
         /* Stop when an ellipsis is seen.  */
         && args1 != NULL_TREE && args2 != NULL_TREE)
@@ -14436,28 +15204,37 @@ more_specialized_fn (tree pat1, tree pat2, int len)
           deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE);
         }
 
+      /* If we couldn't deduce arguments for tparms1 to make arg1 match
+        arg2, then arg2 is not as specialized as arg1.  */
       if (!deduce1)
-       better2 = -1;
+       lose2 = true;
       if (!deduce2)
-       better1 = -1;
-      if (better1 < 0 && better2 < 0)
-       /* We've failed to deduce something in either direction.
-          These must be unordered.  */
-       break;
-
-      if (deduce1 && deduce2 && quals1 >= 0 && quals2 >= 0)
+       lose1 = true;
+
+      /* "If, for a given type, deduction succeeds in both directions
+        (i.e., the types are identical after the transformations above)
+        and if the type from the argument template is more cv-qualified
+        than the type from the parameter template (as described above)
+        that type is considered to be more specialized than the other. If
+        neither type is more cv-qualified than the other then neither type
+        is more specialized than the other."
+
+         We check same_type_p explicitly because deduction can also succeed
+         in both directions when there is a nondeduced context.  */
+      if (deduce1 && deduce2
+         && quals1 != quals2 && quals1 >= 0 && quals2 >= 0
+         && same_type_p (arg1, arg2))
        {
-         /* Deduces in both directions, see if quals can
-            disambiguate.  Pretend the worse one failed to deduce. */
          if ((quals1 & quals2) == quals2)
-           deduce1 = 0;
+           lose2 = true;
          if ((quals1 & quals2) == quals1)
-           deduce2 = 0;
+           lose1 = true;
        }
-      if (deduce1 && !deduce2 && !better2)
-       better2 = 1;
-      if (deduce2 && !deduce1 && !better1)
-       better1 = 1;
+
+      if (lose1 && lose2)
+       /* We've failed to deduce something in either direction.
+          These must be unordered.  */
+       break;
 
       if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION
           || TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
@@ -14469,22 +15246,38 @@ more_specialized_fn (tree pat1, tree pat2, int len)
       args2 = TREE_CHAIN (args2);
     }
 
+  /* "In most cases, all template parameters must have values in order for
+     deduction to succeed, but for partial ordering purposes a template
+     parameter may remain without a value provided it is not used in the
+     types being used for partial ordering."
+
+     Thus, if we are missing any of the targs1 we need to substitute into
+     origs1, then pat2 is not as specialized as pat1.  This can happen when
+     there is a nondeduced context.  */
+  if (!lose2 && check_undeduced_parms (targs1, origs1, args1))
+    lose2 = true;
+  if (!lose1 && check_undeduced_parms (targs2, origs2, args2))
+    lose1 = true;
+
   processing_template_decl--;
 
   /* All things being equal, if the next argument is a pack expansion
      for one function but not for the other, prefer the
-     non-variadic function.  */
-  if ((better1 > 0) - (better2 > 0) == 0
+     non-variadic function.  FIXME this is bogus; see c++/41958.  */
+  if (lose1 == lose2
       && args1 && TREE_VALUE (args1)
       && args2 && TREE_VALUE (args2))
     {
-      if (TREE_CODE (TREE_VALUE (args1)) == TYPE_PACK_EXPANSION)
-        return TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION ? 0 : -1;
-      else if (TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION)
-        return 1;
+      lose1 = TREE_CODE (TREE_VALUE (args1)) == TYPE_PACK_EXPANSION;
+      lose2 = TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION;
     }
 
-  return (better1 > 0) - (better2 > 0);
+  if (lose1 == lose2)
+    return 0;
+  else if (!lose1)
+    return 1;
+  else
+    return -1;
 }
 
 /* Determine which of two partial specializations is more specialized.
@@ -15449,6 +16242,27 @@ template_for_substitution (tree decl)
   return tmpl;
 }
 
+/* Returns true if we need to instantiate this template instance even if we
+   know we aren't going to emit it..  */
+
+bool
+always_instantiate_p (tree decl)
+{
+  /* We always instantiate inline functions so that we can inline them.  An
+     explicit instantiation declaration prohibits implicit instantiation of
+     non-inline functions.  With high levels of optimization, we would
+     normally inline non-inline functions -- but we're not allowed to do
+     that for "extern template" functions.  Therefore, we check
+     DECL_DECLARED_INLINE_P, rather than possibly_inlined_p.  */
+  return ((TREE_CODE (decl) == FUNCTION_DECL
+          && DECL_DECLARED_INLINE_P (decl))
+         /* And we need to instantiate static data members so that
+            their initializers are available in integral constant
+            expressions.  */
+         || (TREE_CODE (decl) == VAR_DECL
+             && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)));
+}
+
 /* Produce the definition of D, a _DECL generated from a template.  If
    DEFER_OK is nonzero, then we don't have to actually do the
    instantiation now; we just have to do it sometime.  Normally it is
@@ -15490,25 +16304,37 @@ instantiate_decl (tree d, int defer_ok,
   if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d))
     d = DECL_CLONED_FUNCTION (d);
 
-  if (DECL_TEMPLATE_INSTANTIATED (d))
-    /* D has already been instantiated.  It might seem reasonable to
-       check whether or not D is an explicit instantiation, and, if so,
-       stop here.  But when an explicit instantiation is deferred
-       until the end of the compilation, DECL_EXPLICIT_INSTANTIATION
-       is set, even though we still need to do the instantiation.  */
+  if (DECL_TEMPLATE_INSTANTIATED (d)
+      || DECL_TEMPLATE_SPECIALIZATION (d))
+    /* D has already been instantiated or explicitly specialized, so
+       there's nothing for us to do here.
+
+       It might seem reasonable to check whether or not D is an explicit
+       instantiation, and, if so, stop here.  But when an explicit
+       instantiation is deferred until the end of the compilation,
+       DECL_EXPLICIT_INSTANTIATION is set, even though we still need to do
+       the instantiation.  */
+    return d;
+
+  /* Check to see whether we know that this template will be
+     instantiated in some other file, as with "extern template"
+     extension.  */
+  external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
+
+  /* In general, we do not instantiate such templates.  */
+  if (external_p && !always_instantiate_p (d))
     return d;
 
-  /* If we already have a specialization of this declaration, then
-     there's no reason to instantiate it.  Note that
-     retrieve_specialization gives us both instantiations and
-     specializations, so we must explicitly check
-     DECL_TEMPLATE_SPECIALIZATION.  */
   gen_tmpl = most_general_template (tmpl);
   gen_args = DECL_TI_ARGS (d);
-  spec = retrieve_specialization (gen_tmpl, gen_args,
-                                 /*class_specializations_p=*/false);
-  if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec))
-    return spec;
+
+  if (tmpl != gen_tmpl)
+    /* We should already have the extra args.  */
+    gcc_assert (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl))
+               == TMPL_ARGS_DEPTH (gen_args));
+  /* And what's in the hash table should match D.  */
+  gcc_assert ((spec = retrieve_specialization (gen_tmpl, gen_args, 0)) == d
+             || spec == NULL_TREE);
 
   /* This needs to happen before any tsubsting.  */
   if (! push_tinst_level (d))
@@ -15564,10 +16390,11 @@ instantiate_decl (tree d, int defer_ok,
       SET_DECL_IMPLICIT_INSTANTIATION (d);
     }
 
-  if (!defer_ok)
+  /* Recheck the substitutions to obtain any warning messages
+     about ignoring cv qualifiers.  Don't do this for artificial decls,
+     as it breaks the context-sensitive substitution for lambda op(). */
+  if (!defer_ok && !DECL_ARTIFICIAL (d))
     {
-      /* Recheck the substitutions to obtain any warning messages
-        about ignoring cv qualifiers.  */
       tree gen = DECL_TEMPLATE_RESULT (gen_tmpl);
       tree type = TREE_TYPE (gen);
 
@@ -15592,26 +16419,6 @@ instantiate_decl (tree d, int defer_ok,
       pop_access_scope (d);
     }
 
-  /* Check to see whether we know that this template will be
-     instantiated in some other file, as with "extern template"
-     extension.  */
-  external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
-  /* In general, we do not instantiate such templates...  */
-  if (external_p
-      /* ... but we instantiate inline functions so that we can inline
-        them.  An explicit instantiation declaration prohibits implicit
-        instantiation of non-inline functions.  With high levels of
-        optimization, we would normally inline non-inline functions
-        -- but we're not allowed to do that for "extern template" functions.
-        Therefore, we check DECL_DECLARED_INLINE_P, rather than
-        possibly_inlined_p.  And ...  */
-      && ! (TREE_CODE (d) == FUNCTION_DECL
-           && DECL_DECLARED_INLINE_P (d))
-      /* ... we instantiate static data members whose values are
-        needed in integral constant expressions.  */
-      && ! (TREE_CODE (d) == VAR_DECL
-           && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d)))
-    goto out;
   /* Defer all other templates, unless we have been explicitly
      forbidden from doing so.  */
   if (/* If there is no definition, we cannot instantiate the
@@ -15715,7 +16522,7 @@ instantiate_decl (tree d, int defer_ok,
 
       /* The initializer is placed in DECL_INITIAL by
         regenerate_decl_from_template.  Pull it out so that
-        finish_decl can process it.  */
+        cp_finish_decl can process it.  */
       init = DECL_INITIAL (d);
       DECL_INITIAL (d) = NULL_TREE;
       DECL_INITIALIZED_P (d) = 0;
@@ -15727,7 +16534,7 @@ instantiate_decl (tree d, int defer_ok,
 
       /* Enter the scope of D so that access-checking works correctly.  */
       push_nested_class (DECL_CONTEXT (d));
-      finish_decl (d, init, NULL_TREE, NULL_TREE);
+      cp_finish_decl (d, init, false, NULL_TREE, 0);
       pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
@@ -16977,6 +17784,9 @@ resolve_typename_type (tree type, bool only_current_p)
      to look inside it.  */
   if (only_current_p && !currently_open_class (scope))
     return type;
+  /* If this is a typedef, we don't want to look inside (c++/11987).  */
+  if (typedef_variant_p (type))
+    return type;
   /* If SCOPE isn't the template itself, it will not have a valid
      TYPE_FIELDS list.  */
   if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope)))
@@ -17153,10 +17963,7 @@ make_args_non_dependent (VEC(tree,gc) *args)
 tree
 make_auto (void)
 {
-  tree au;
-
-  /* ??? Is it worth caching this for multiple autos at the same level?  */
-  au = cxx_make_type (TEMPLATE_TYPE_PARM);
+  tree au = cxx_make_type (TEMPLATE_TYPE_PARM);
   TYPE_NAME (au) = build_decl (BUILTINS_LOCATION,
                               TYPE_DECL, get_identifier ("auto"), au);
   TYPE_STUB_DECL (au) = TYPE_NAME (au);
@@ -17170,26 +17977,33 @@ make_auto (void)
   return au;
 }
 
-/* Replace auto in TYPE with std::initializer_list<auto>.  */
+/* Given type ARG, return std::initializer_list<ARG>.  */
 
 static tree
-listify_autos (tree type, tree auto_node)
+listify (tree arg)
 {
   tree std_init_list = namespace_binding
     (get_identifier ("initializer_list"), std_node);
   tree argvec;
-  tree init_auto;
   if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
     {    
-      error ("deducing auto from brace-enclosed initializer list requires "
+      error ("deducing from brace-enclosed initializer list requires "
             "#include <initializer_list>");
       return error_mark_node;
     }
   argvec = make_tree_vec (1);
-  TREE_VEC_ELT (argvec, 0) = auto_node;
-  init_auto = lookup_template_class (std_init_list, argvec, NULL_TREE,
-                                    NULL_TREE, 0, tf_warning_or_error);
+  TREE_VEC_ELT (argvec, 0) = arg;
+  return lookup_template_class (std_init_list, argvec, NULL_TREE,
+                               NULL_TREE, 0, tf_warning_or_error);
+}
+
+/* Replace auto in TYPE with std::initializer_list<auto>.  */
 
+static tree
+listify_autos (tree type, tree auto_node)
+{
+  tree init_auto = listify (auto_node);
+  tree argvec = make_tree_vec (1);
   TREE_VEC_ELT (argvec, 0) = init_auto;
   if (processing_template_decl)
     argvec = add_to_template_args (current_template_args (), argvec);
@@ -17227,6 +18041,19 @@ do_auto_deduction (tree type, tree init, tree auto_node)
       return error_mark_node;
     }
 
+  /* If the list of declarators contains more than one declarator, the type
+     of each declared variable is determined as described above. If the
+     type deduced for the template parameter U is not the same in each
+     deduction, the program is ill-formed.  */
+  if (TREE_TYPE (auto_node)
+      && !same_type_p (TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0)))
+    {
+      error ("inconsistent deduction for %qT: %qT and then %qT",
+            auto_node, TREE_TYPE (auto_node), TREE_VEC_ELT (targs, 0));
+      return error_mark_node;
+    }
+  TREE_TYPE (auto_node) = TREE_VEC_ELT (targs, 0);
+
   if (processing_template_decl)
     targs = add_to_template_args (current_template_args (), targs);
   return tsubst (type, targs, tf_warning_or_error, NULL_TREE);
@@ -17286,27 +18113,29 @@ type_uses_auto (tree type)
   return NULL_TREE;
 }
 
-/* For a given template T, return the list of typedefs referenced
+/* For a given template T, return the vector of typedefs referenced
    in T for which access check is needed at T instantiation time.
    T is either  a FUNCTION_DECL or a RECORD_TYPE.
    Those typedefs were added to T by the function
    append_type_to_template_for_access_check.  */
 
-tree
+VEC(qualified_typedef_usage_t,gc)*
 get_types_needing_access_check (tree t)
 {
-  tree ti, result = NULL_TREE;
+  tree ti;
+  VEC(qualified_typedef_usage_t,gc) *result = NULL;
 
   if (!t || t == error_mark_node)
-    return t;
+    return NULL;
 
   if (!(ti = get_template_info (t)))
-    return NULL_TREE;
+    return NULL;
 
-  if (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == FUNCTION_DECL)
+  if (CLASS_TYPE_P (t)
+      || TREE_CODE (t) == FUNCTION_DECL)
     {
       if (!TI_TEMPLATE (ti))
-       return NULL_TREE;
+       return NULL;
 
       result = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti);
     }
@@ -17320,6 +18149,7 @@ get_types_needing_access_check (tree t)
    T is either a FUNCTION_DECL or a RECORD_TYPE.
    TYPE_DECL is a TYPE_DECL node representing a typedef.
    SCOPE is the scope through which TYPE_DECL is accessed.
+   LOCATION is the location of the usage point of TYPE_DECL.
 
    This function is a subroutine of
    append_type_to_template_for_access_check.  */
@@ -17327,15 +18157,17 @@ get_types_needing_access_check (tree t)
 static void
 append_type_to_template_for_access_check_1 (tree t,
                                            tree type_decl,
-                                           tree scope)
+                                           tree scope,
+                                           location_t location)
 {
+  qualified_typedef_usage_t typedef_usage;
   tree ti;
 
   if (!t || t == error_mark_node)
     return;
 
   gcc_assert ((TREE_CODE (t) == FUNCTION_DECL
-              || TREE_CODE (t) == RECORD_TYPE)
+              || CLASS_TYPE_P (t))
              && type_decl
              && TREE_CODE (type_decl) == TYPE_DECL
              && scope);
@@ -17345,14 +18177,20 @@ append_type_to_template_for_access_check_1 (tree t,
 
   gcc_assert (TI_TEMPLATE (ti));
 
-  TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti) =
-    tree_cons (type_decl, scope, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti));
+  typedef_usage.typedef_decl = type_decl;
+  typedef_usage.context = scope;
+  typedef_usage.locus = location;
+
+  VEC_safe_push (qualified_typedef_usage_t, gc,
+                TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti),
+                &typedef_usage);
 }
 
 /* Append TYPE_DECL to the template TEMPL.
    TEMPL is either a class type, a FUNCTION_DECL or a a TEMPLATE_DECL.
    At TEMPL instanciation time, TYPE_DECL will be checked to see
    if it can be accessed through SCOPE.
+   LOCATION is the location of the usage point of TYPE_DECL.
 
    e.g. consider the following code snippet:
 
@@ -17363,7 +18201,7 @@ append_type_to_template_for_access_check_1 (tree t,
 
      template<class U> struct S
      {
-       C::myint mi;
+       C::myint mi; // <-- usage point of the typedef C::myint
      };
 
      S<char> s;
@@ -17380,25 +18218,40 @@ append_type_to_template_for_access_check_1 (tree t,
 void
 append_type_to_template_for_access_check (tree templ,
                                           tree type_decl,
-                                         tree scope)
+                                         tree scope,
+                                         location_t location)
 {
-  tree node;
+  qualified_typedef_usage_t *iter;
+  int i;
 
   gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL));
 
   /* Make sure we don't append the type to the template twice.  */
-  for (node = get_types_needing_access_check (templ);
-       node;
-       node = TREE_CHAIN (node))
-    {
-      tree decl = TREE_PURPOSE (node);
-      tree type_scope = TREE_VALUE (node);
+  for (i = 0;
+       VEC_iterate (qualified_typedef_usage_t,
+                   get_types_needing_access_check (templ),
+                   i, iter);
+       ++i)
+    if (iter->typedef_decl == type_decl && scope == iter->context)
+      return;
 
-      if (decl == type_decl && type_scope == scope)
-       return;
-    }
+  append_type_to_template_for_access_check_1 (templ, type_decl,
+                                             scope, location);
+}
 
-  append_type_to_template_for_access_check_1 (templ, type_decl, scope);
+/* Set up the hash tables for template instantiations.  */
+
+void
+init_template_processing (void)
+{
+  decl_specializations = htab_create_ggc (37,
+                                         hash_specialization,
+                                         eq_specializations,
+                                         ggc_free);
+  type_specializations = htab_create_ggc (37,
+                                         hash_specialization,
+                                         eq_specializations,
+                                         ggc_free);
 }
 
 #include "gt-cp-pt.h"