OSDN Git Service

gcc
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index bf82f8c..ade17a5 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle parameterized types (templates) for GNU C++.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2007, 2008  Free Software Foundation, Inc.
    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
    Rewritten by Jason Merrill (jason@cygnus.com).
 
@@ -8,7 +8,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -17,9 +17,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* Known bugs or deficiencies include:
 
@@ -53,12 +52,14 @@ typedef int (*tree_fn_t) (tree, void*);
 
 /* The PENDING_TEMPLATES is a TREE_LIST of templates whose
    instantiations have been deferred, either because their definitions
-   were not yet available, or because we were putting off doing the work.
-   The TREE_PURPOSE of each entry is either a DECL (for a function or
-   static data member), or a TYPE (for a class) indicating what we are
-   hoping to instantiate.  The TREE_VALUE is not used.  */
-static GTY(()) tree pending_templates;
-static GTY(()) tree last_pending_template;
+   were not yet available, or because we were putting off doing the work.  */
+struct pending_template GTY (()) {
+  struct pending_template *next;
+  struct tinst_level *tinst;
+};
+
+static GTY(()) struct pending_template *pending_templates;
+static GTY(()) struct pending_template *last_pending_template;
 
 int processing_template_parmlist;
 static int template_header_count;
@@ -66,7 +67,7 @@ static int template_header_count;
 static GTY(()) tree saved_trees;
 static VEC(int,heap) *inline_parm_levels;
 
-static GTY(()) tree current_tinst_level;
+static GTY(()) struct tinst_level *current_tinst_level;
 
 static GTY(()) tree saved_access_scope;
 
@@ -97,15 +98,15 @@ static GTY(()) VEC(tree,gc) *canonical_template_parms;
 
 static void push_access_scope (tree);
 static void pop_access_scope (tree);
-static int resolve_overloaded_unification (tree, tree, tree, tree,
-                                          unification_kind_t, int);
+static bool resolve_overloaded_unification (tree, tree, tree, tree,
+                                           unification_kind_t, int);
 static int try_one_overload (tree, tree, tree, tree, tree,
                             unification_kind_t, int, bool);
 static int unify (tree, tree, tree, tree, int);
 static void add_pending_template (tree);
 static int push_tinst_level (tree);
 static void pop_tinst_level (void);
-static void reopen_tinst_level (tree);
+static tree reopen_tinst_level (struct tinst_level *);
 static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree);
 static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
@@ -114,7 +115,8 @@ static void tsubst_enum     (tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
 static bool check_instantiated_args (tree, tree, tsubst_flags_t);
-static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
+static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
+                                            tree);
 static int  type_unification_real (tree, tree, tree, tree,
                                   int, unification_kind_t, int);
 static void note_template_header (int);
@@ -123,14 +125,14 @@ static tree convert_nontype_argument (tree, tree);
 static tree convert_template_argument (tree, tree, tree,
                                       tsubst_flags_t, int, tree);
 static int for_each_template_parm (tree, tree_fn_t, void*,
-                                  struct pointer_set_t*);
+                                  struct pointer_set_t*, bool);
 static tree expand_template_argument_pack (tree);
 static tree build_template_parm_index (int, int, int, tree, tree);
-static int inline_needs_template_parms (tree);
+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 tree reduce_template_parm_level (tree, tree, int);
+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 *);
 static tree tsubst_friend_function (tree, tree);
@@ -152,11 +154,11 @@ static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
 static bool check_specialization_scope (void);
 static tree process_partial_specialization (tree);
 static void set_current_access_from_decl (tree);
-static void check_default_tmpl_args (tree, tree, int, int);
 static tree get_template_base (tree, tree, tree, tree);
 static tree try_class_unification (tree, tree, tree, tree);
 static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
                                           tree, tree);
+static bool template_template_parm_bindings_ok_p (tree, tree);
 static int template_args_equal (tree, tree);
 static void tsubst_default_arguments (tree);
 static tree for_each_template_parm_r (tree *, int *, void *);
@@ -234,6 +236,8 @@ finish_member_template_decl (tree decl)
       tree type;
 
       type = TREE_TYPE (decl);
+      if (type == error_mark_node)
+       return error_mark_node;
       if (IS_AGGR_TYPE (type)
          && CLASSTYPE_TEMPLATE_INFO (type)
          && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
@@ -262,6 +266,25 @@ finish_member_template_decl (tree decl)
   return error_mark_node;
 }
 
+/* Return the template info node corresponding to T, whatever T is.  */
+
+tree
+get_template_info (tree t)
+{
+  tree tinfo = NULL_TREE;
+
+  if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+    tinfo = DECL_TEMPLATE_INFO (t);
+
+  if (!tinfo && TREE_CODE (t) == TYPE_DECL)
+    t = TREE_TYPE (t);
+
+  if (TAGGED_TYPE_P (t))
+    tinfo = TYPE_TEMPLATE_INFO (t);
+
+  return tinfo;
+}
+
 /* Returns the template nesting level of the indicated class TYPE.
 
    For example, in:
@@ -290,33 +313,24 @@ template_class_depth (tree type)
        type = (TREE_CODE (type) == FUNCTION_DECL)
         ? CP_DECL_CONTEXT (type) : TYPE_CONTEXT (type))
     {
-      if (TREE_CODE (type) != FUNCTION_DECL)
-       {
-         if (CLASSTYPE_TEMPLATE_INFO (type)
-             && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
-             && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
-           ++depth;
-       }
-      else
-       {
-         if (DECL_TEMPLATE_INFO (type)
-             && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type))
-             && uses_template_parms (DECL_TI_ARGS (type)))
-           ++depth;
-       }
+      tree tinfo = get_template_info (type);
+
+      if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
+         && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo))))
+       ++depth;
     }
 
   return depth;
 }
 
-/* Returns 1 if processing DECL as part of do_pending_inlines
-   needs us to push template parms.  */
+/* Subroutine of maybe_begin_member_template_processing.
+   Returns true if processing DECL needs us to push template parms.  */
 
-static int
+static bool
 inline_needs_template_parms (tree decl)
 {
   if (! DECL_TEMPLATE_INFO (decl))
-    return 0;
+    return false;
 
   return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl)))
          > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl)));
@@ -518,6 +532,37 @@ get_innermost_template_args (tree args, int n)
   return new_args;
 }
 
+/* The inverse of get_innermost_template_args: Return all but the innermost
+   EXTRA_LEVELS levels of template arguments from the ARGS.  */
+
+static tree
+strip_innermost_template_args (tree args, int extra_levels)
+{
+  tree new_args;
+  int n = TMPL_ARGS_DEPTH (args) - extra_levels;
+  int i;
+
+  gcc_assert (n >= 0);
+
+  /* If N is 1, just return the outermost set of template arguments.  */
+  if (n == 1)
+    return TMPL_ARGS_LEVEL (args, 1);
+
+  /* If we're not removing anything, just return the arguments we were
+     given.  */
+  gcc_assert (extra_levels >= 0);
+  if (extra_levels == 0)
+    return args;
+
+  /* Make a new set of arguments, not containing the inner arguments.  */
+  new_args = make_tree_vec (n);
+  for (i = 1; i <= n; ++i)
+    SET_TMPL_ARGS_LEVEL (new_args, i,
+                        TMPL_ARGS_LEVEL (args, i));
+
+  return new_args;
+}
+
 /* We've got a template header coming up; push to a new level for storing
    the parms.  */
 
@@ -898,7 +943,8 @@ retrieve_specialization (tree tmpl, tree args,
         DECL_TEMPLATE_INSTANTIATIONS list; other templates use the
         DECL_TEMPLATE_SPECIALIZATIONS list.  */
       if (!class_specializations_p
-         && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL)
+         && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL
+         && TAGGED_TYPE_P (TREE_TYPE (tmpl)))
        sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl);
       else
        sp = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
@@ -932,8 +978,13 @@ retrieve_specialization (tree tmpl, tree args,
 static tree
 retrieve_local_specialization (tree tmpl)
 {
-  tree spec = (tree) htab_find_with_hash (local_specializations, tmpl,
-                                         htab_hash_pointer (tmpl));
+  tree spec;
+
+  if (local_specializations == NULL)
+    return NULL_TREE;
+
+  spec = (tree) htab_find_with_hash (local_specializations, tmpl,
+                                    htab_hash_pointer (tmpl));
   return spec ? TREE_PURPOSE (spec) : NULL_TREE;
 }
 
@@ -1302,7 +1353,7 @@ reregister_specialization (tree spec, tree tmpl, tree new_spec)
 static int
 eq_local_specializations (const void *p1, const void *p2)
 {
-  return TREE_VALUE ((tree) p1) == (tree) p2;
+  return TREE_VALUE ((const_tree) p1) == (const_tree) p2;
 }
 
 /* Hash P1, an entry in the local specializations table.  */
@@ -1310,7 +1361,7 @@ eq_local_specializations (const void *p1, const void *p2)
 static hashval_t
 hash_local_specialization (const void* p1)
 {
-  return htab_hash_pointer (TREE_VALUE ((tree) p1));
+  return htab_hash_pointer (TREE_VALUE ((const_tree) p1));
 }
 
 /* Like register_specialization, but for local declarations.  We are
@@ -1981,7 +2032,7 @@ check_explicit_specialization (tree declarator,
                 context.  */
              fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
                                           false, true);
-             if (!fns || !is_overloaded_fn (fns))
+             if (fns == error_mark_node || !is_overloaded_fn (fns))
                {
                  error ("%qD is not a template function", dname);
                  fns = error_mark_node;
@@ -2042,7 +2093,7 @@ check_explicit_specialization (tree declarator,
            {
              int is_constructor = DECL_CONSTRUCTOR_P (decl);
 
-             if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype)
+             if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
                  : !CLASSTYPE_DESTRUCTORS (ctype))
                {
                  /* From [temp.expl.spec]:
@@ -2193,6 +2244,42 @@ check_explicit_specialization (tree declarator,
          TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
          TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
 
+          /* 7.1.1-1 [dcl.stc]
+
+             A storage-class-specifier shall not be specified in an
+             explicit specialization...
+
+             The parser rejects these, so unless action is taken here,
+             explicit function specializations will always appear with
+             global linkage.
+
+             The action recommended by the C++ CWG in response to C++
+             defect report 605 is to make the storage class and linkage
+             of the explicit specialization match the templated function:
+
+             http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#605
+           */
+          if (tsk == tsk_expl_spec && DECL_FUNCTION_TEMPLATE_P (gen_tmpl))
+            {
+              tree tmpl_func = DECL_TEMPLATE_RESULT (gen_tmpl);
+              gcc_assert (TREE_CODE (tmpl_func) == FUNCTION_DECL);
+
+              /* This specialization has the same linkage and visibility as
+                 the function template it specializes.  */
+              TREE_PUBLIC (decl) = TREE_PUBLIC (tmpl_func);
+             if (! TREE_PUBLIC (decl))
+               {
+                 DECL_INTERFACE_KNOWN (decl) = 1;
+                 DECL_NOT_REALLY_EXTERN (decl) = 1;
+               }
+              DECL_THIS_STATIC (decl) = DECL_THIS_STATIC (tmpl_func);
+              if (DECL_VISIBILITY_SPECIFIED (tmpl_func))
+                {
+                  DECL_VISIBILITY_SPECIFIED (decl) = 1;
+                  DECL_VISIBILITY (decl) = DECL_VISIBILITY (tmpl_func);
+                }
+            }
+
          /* If DECL is a friend declaration, declared using an
             unqualified name, the namespace associated with DECL may
             have been set incorrectly.  For example, in:
@@ -2232,10 +2319,10 @@ check_explicit_specialization (tree declarator,
    DECL_TEMPLATE_PARMS.  */
 
 int
-comp_template_parms (tree parms1, tree parms2)
+comp_template_parms (const_tree parms1, const_tree parms2)
 {
-  tree p1;
-  tree p2;
+  const_tree p1;
+  const_tree p2;
 
   if (parms1 == parms2)
     return 1;
@@ -2286,7 +2373,7 @@ comp_template_parms (tree parms1, tree parms2)
 
 /* Determine whether PARM is a parameter pack.  */
 bool 
-template_parameter_pack_p (tree parm)
+template_parameter_pack_p (const_tree parm)
 {
   /* Determine if we have a non-type template parameter pack.  */
   if (TREE_CODE (parm) == PARM_DECL)
@@ -2303,17 +2390,6 @@ template_parameter_pack_p (tree parm)
          && TEMPLATE_TYPE_PARAMETER_PACK (parm));
 }
 
-/* Determine whether PARMS describes a variadic template parameter
-   list, i.e., one that is terminated by a template parameter pack.  */
-bool 
-template_parms_variadic_p (tree parms)
-{
-  int nparms = TREE_VEC_LENGTH (parms);
-  tree last_parm = TREE_VALUE (TREE_VEC_ELT (parms, nparms - 1));
-  
-  return template_parameter_pack_p (last_parm);
-}
-
 /* Determine whether ARGS describes a variadic template args list,
    i.e., one that is terminated by a template argument pack.  */
 static bool 
@@ -2351,16 +2427,20 @@ make_ith_pack_parameter_name (tree name, int i)
   return get_identifier (newname);
 }
 
-/* Structure used to track the progress of find_parameter_pack_r.  */
+/* Structure used to track the progress of find_parameter_packs_r.  */
 struct find_parameter_pack_data 
 {
+  /* TREE_LIST that will contain all of the parameter packs found by
+     the traversal.  */
   tree* parameter_packs;
+
+  /* Set of AST nodes that have been visited by the traversal.  */
   struct pointer_set_t *visited;
 };
 
-/* Identifiers all of the argument packs that occur in a template
+/* Identifies all of the argument packs that occur in a template
    argument and appends them to the TREE_LIST inside DATA, which is a
-   find_parameter_pack_Data structure. This is a subroutine of
+   find_parameter_pack_data structure. This is a subroutine of
    make_pack_expansion and uses_parameter_packs.  */
 static tree
 find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
@@ -2368,49 +2448,69 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
   tree t = *tp;
   struct find_parameter_pack_data* ppd = 
     (struct find_parameter_pack_data*)data;
+  bool parameter_pack_p = false;
 
-  if (TYPE_P (t))
+  /* Identify whether this is a parameter pack or not.  */
+  switch (TREE_CODE (t))
     {
-      tree context = TYPE_CONTEXT (t);
-      walk_tree (&context, &find_parameter_packs_r, ppd, ppd->visited);
+    case TEMPLATE_PARM_INDEX:
+      if (TEMPLATE_PARM_PARAMETER_PACK (t))
+        parameter_pack_p = true;
+      break;
+
+    case TEMPLATE_TYPE_PARM:
+    case TEMPLATE_TEMPLATE_PARM:
+      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+        parameter_pack_p = true;
+      break;
+
+    case PARM_DECL:
+      if (FUNCTION_PARAMETER_PACK_P (t))
+        {
+          /* We don't want to walk into the type of a PARM_DECL,
+             because we don't want to see the type parameter pack.  */
+          *walk_subtrees = 0;
+         parameter_pack_p = true;
+        }
+      break;
+
+    default:
+      /* Not a parameter pack.  */
+      break;
     }
 
+  if (parameter_pack_p)
+    {
+      /* Add this parameter pack to the list.  */
+      *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
+    }
+
+  if (TYPE_P (t))
+    cp_walk_tree (&TYPE_CONTEXT (t), 
+                 &find_parameter_packs_r, ppd, ppd->visited);
+
   /* This switch statement will return immediately if we don't find a
      parameter pack.  */
   switch (TREE_CODE (t)) 
     {
     case TEMPLATE_PARM_INDEX:
-      if (TEMPLATE_PARM_PARAMETER_PACK (t))
-        break;
       return NULL_TREE;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
+      /* Check the template itself.  */
+      cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)), 
+                   &find_parameter_packs_r, ppd, ppd->visited);
       /* Check the template arguments.  */
-      walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, 
-                ppd->visited);
-
-      /* Dig out the underlying TEMPLATE_TEMPLATE_PARM.  */
-      t = TYPE_TI_TEMPLATE (t);
-      if (DECL_P (t) && TREE_TYPE (t))
-        t = TREE_TYPE (t);
+      cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, 
+                   ppd->visited);
       *walk_subtrees = 0;
-      
-      /* Fall through.  */
+      return NULL_TREE;
 
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
-      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
-        break;
       return NULL_TREE;
 
     case PARM_DECL:
-      if (FUNCTION_PARAMETER_PACK_P (t))
-        {
-          /* We don't want to walk into the type of a PARM_DECL,
-             because we don't want to see the type parameter pack.*/
-          *walk_subtrees = 0;
-          break;
-        }
       return NULL_TREE;
 
     case RECORD_TYPE:
@@ -2421,33 +2521,43 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case UNION_TYPE:
     case ENUMERAL_TYPE:
       if (TYPE_TEMPLATE_INFO (t))
-        {
-          tree args = TREE_VALUE (TYPE_TEMPLATE_INFO (t));
-          walk_tree (&args, &find_parameter_packs_r, ppd, ppd->visited);
-        }
+       cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), 
+                     &find_parameter_packs_r, ppd, ppd->visited);
 
       *walk_subtrees = 0;
       return NULL_TREE;
 
     case TEMPLATE_DECL:
-      if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
-         && TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
-       break;
-      
+      cp_walk_tree (&TREE_TYPE (t),
+                   &find_parameter_packs_r, ppd, ppd->visited);
+      return NULL_TREE;
+    case TYPENAME_TYPE:
+      cp_walk_tree (&TYPENAME_TYPE_FULLNAME (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
       *walk_subtrees = 0;
       return NULL_TREE;
-       
+      
     case TYPE_PACK_EXPANSION:
     case EXPR_PACK_EXPANSION:
       *walk_subtrees = 0;
       return NULL_TREE;
 
+    case INTEGER_TYPE:
+      cp_walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r, 
+                   ppd, ppd->visited);
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
+    case IDENTIFIER_NODE:
+      cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, 
+                   ppd->visited);
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
     default:
       return NULL_TREE;
     }
-  
-  /* Add this parameter pack to the list.  */
-  *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
 
   return NULL_TREE;
 }
@@ -2460,7 +2570,8 @@ uses_parameter_packs (tree t)
   struct find_parameter_pack_data ppd;
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = pointer_set_create ();
-  walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+  cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+  pointer_set_destroy (ppd.visited);
   return parameter_packs != NULL_TREE;
 }
 
@@ -2509,12 +2620,13 @@ make_pack_expansion (tree arg)
          class expansion.  */
       ppd.visited = pointer_set_create ();
       ppd.parameter_packs = &parameter_packs;
-      walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r, 
-                 &ppd, ppd.visited);
+      cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r, 
+                    &ppd, ppd.visited);
 
       if (parameter_packs == NULL_TREE)
         {
           error ("base initializer expansion %<%T%> contains no parameter packs", arg);
+          pointer_set_destroy (ppd.visited);
           return error_mark_node;
         }
 
@@ -2526,11 +2638,13 @@ make_pack_expansion (tree arg)
             {
               /* Determine which parameter packs will be expanded in this
                  argument.  */
-              walk_tree (&TREE_VALUE (value), &find_parameter_packs_r, 
-                         &ppd, ppd.visited);
+              cp_walk_tree (&TREE_VALUE (value), &find_parameter_packs_r, 
+                            &ppd, ppd.visited);
             }
         }
 
+      pointer_set_destroy (ppd.visited);
+
       /* Create the pack expansion type for the base type.  */
       purpose = make_node (TYPE_PACK_EXPANSION);
       SET_PACK_EXPANSION_PATTERN (purpose, TREE_PURPOSE (arg));
@@ -2563,7 +2677,8 @@ make_pack_expansion (tree arg)
   /* Determine which parameter packs will be expanded.  */
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = pointer_set_create ();
-  walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
+  cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
+  pointer_set_destroy (ppd.visited);
 
   /* Make sure we found some parameter packs.  */
   if (parameter_packs == NULL_TREE)
@@ -2589,40 +2704,55 @@ make_pack_expansion (tree arg)
    where "args" is a parameter pack. check_for_bare_parameter_packs
    should not be called for the subexpressions args, h(args),
    g(h(args)), or f(g(h(args))), because we would produce erroneous
-   error messages.  */
-void 
+   error messages. 
+
+   Returns TRUE and emits an error if there were bare parameter packs,
+   returns FALSE otherwise.  */
+bool 
 check_for_bare_parameter_packs (tree t)
 {
   tree parameter_packs = NULL_TREE;
   struct find_parameter_pack_data ppd;
 
   if (!processing_template_decl || !t || t == error_mark_node)
-    return;
+    return false;
 
   if (TREE_CODE (t) == TYPE_DECL)
     t = TREE_TYPE (t);
 
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = pointer_set_create ();
-  walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+  cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+  pointer_set_destroy (ppd.visited);
 
-  if (parameter_packs) {
-    error ("parameter packs not expanded with `...':");
-    while (parameter_packs)
-      {
-        tree pack = TREE_VALUE (parameter_packs);
-        tree name = NULL_TREE;
+  if (parameter_packs) 
+    {
+      error ("parameter packs not expanded with `...':");
+      while (parameter_packs)
+        {
+          tree pack = TREE_VALUE (parameter_packs);
+          tree name = NULL_TREE;
+
+          if (TREE_CODE (pack) == TEMPLATE_TYPE_PARM
+              || TREE_CODE (pack) == TEMPLATE_TEMPLATE_PARM)
+            name = TYPE_NAME (pack);
+          else if (TREE_CODE (pack) == TEMPLATE_PARM_INDEX)
+            name = DECL_NAME (TEMPLATE_PARM_DECL (pack));
+          else
+            name = DECL_NAME (pack);
 
-        if (TREE_CODE (pack) == TEMPLATE_TYPE_PARM
-            || TREE_CODE (pack) == TEMPLATE_TEMPLATE_PARM)
-          name = TYPE_NAME (pack);
-        else
-          name = DECL_NAME (pack);
-        inform ("        %qD", name);
+         if (name)
+           inform ("        %qD", name);
+         else
+           inform ("        <anonymous>");
 
-        parameter_packs = TREE_CHAIN (parameter_packs);
-      }
-  }
+          parameter_packs = TREE_CHAIN (parameter_packs);
+        }
+
+      return true;
+    }
+
+  return false;
 }
 
 /* Expand any parameter packs that occur in the template arguments in
@@ -2761,7 +2891,7 @@ canonical_type_parameter (tree type)
     VEC_safe_push (tree, gc, canonical_template_parms, NULL_TREE);
 
   list = VEC_index (tree, canonical_template_parms, idx);
-  while (list && !comptypes (type, TREE_VALUE (list), COMPARE_STRUCTURAL))
+  while (list && !cp_comptypes (type, TREE_VALUE (list), COMPARE_STRUCTURAL))
     list = TREE_CHAIN (list);
 
   if (list)
@@ -2781,7 +2911,8 @@ canonical_type_parameter (tree type)
    new one is created.  */
 
 static tree
-reduce_template_parm_level (tree index, tree type, int levels)
+reduce_template_parm_level (tree index, tree type, int levels, tree args,
+                           tsubst_flags_t complain)
 {
   if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
       || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
@@ -2806,9 +2937,10 @@ reduce_template_parm_level (tree index, tree type, int levels)
        = TEMPLATE_PARM_PARAMETER_PACK (index);
 
        /* Template template parameters need this.  */
-      if (TREE_CODE (decl) != CONST_DECL)
-       DECL_TEMPLATE_PARMS (decl)
-         = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
+      if (TREE_CODE (decl) == TEMPLATE_DECL)
+       DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms
+         (DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)),
+          args, complain);
     }
 
   return TEMPLATE_PARM_DESCENDANTS (index);
@@ -2985,8 +3117,10 @@ end_template_decl (void)
   current_template_parms = TREE_CHAIN (current_template_parms);
 }
 
-/* Given a template argument vector containing the template PARMS.
-   The innermost PARMS are given first.  */
+/* Within the declaration of a template, return all levels of template
+   parameters that apply.  The template parameters are represented as
+   a TREE_VEC, in the form documented in cp-tree.h for template
+   arguments.  */
 
 static tree
 current_template_args (void)
@@ -3019,7 +3153,7 @@ current_template_args (void)
            {
              t = TREE_VALUE (t);
 
-             if (t != error_mark_node)
+             if (!error_operand_p (t))
                {
                  if (TREE_CODE (t) == TYPE_DECL
                      || TREE_CODE (t) == TEMPLATE_DECL)
@@ -3054,8 +3188,8 @@ current_template_args (void)
                           TREE_TYPE (t) = type;
                         }
                     }
+                 TREE_VEC_ELT (a, i) = t;
                 }
-             TREE_VEC_ELT (a, i) = t;
            }
        }
 
@@ -3210,7 +3344,8 @@ process_partial_specialization (tree decl)
       for_each_template_parm (TREE_VEC_ELT (inner_args, i),
                              &mark_template_parm,
                              &tpd,
-                             NULL);
+                             NULL,
+                             /*include_nondeduced_p=*/false);
     }
   for (i = 0; i < ntparms; ++i)
     if (tpd.parms[i] == 0)
@@ -3281,7 +3416,10 @@ process_partial_specialization (tree decl)
                   if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
                     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);                   
+                    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;
                 }
             }
 
@@ -3330,7 +3468,8 @@ process_partial_specialization (tree decl)
                   for_each_template_parm (type,
                                           &mark_template_parm,
                                           &tpd2,
-                                          NULL);
+                                          NULL,
+                                         /*include_nondeduced_p=*/false);
 
                   if (tpd2.arg_uses_template_parms [i])
                     {
@@ -3361,22 +3500,33 @@ process_partial_specialization (tree decl)
 
   DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
     = tree_cons (specargs, inner_parms,
-                DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
+                 DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
   TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
   return decl;
 }
 
-/* Check that a template declaration's use of default arguments is not
-   invalid.  Here, PARMS are the template parameters.  IS_PRIMARY is
-   nonzero if DECL is the thing declared by a primary template.
-   IS_PARTIAL is nonzero if DECL is a partial specialization.  */
+/* Check that a template declaration's use of default arguments and
+   parameter packs is not invalid.  Here, PARMS are the template
+   parameters.  IS_PRIMARY is nonzero if DECL is the thing declared by
+   a primary template.  IS_PARTIAL is nonzero if DECL is a partial
+   specialization.
+   
 
-static void
-check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
+   IS_FRIEND_DECL is nonzero if DECL is a friend function template
+   declaration (but not a definition); 1 indicates a declaration, 2
+   indicates a redeclaration. When IS_FRIEND_DECL=2, no errors are
+   emitted for extraneous default arguments.
+
+   Returns TRUE if there were no errors found, FALSE otherwise. */
+
+bool
+check_default_tmpl_args (tree decl, tree parms, int is_primary, 
+                         int is_partial, int is_friend_decl)
 {
   const char *msg;
   int last_level_to_check;
   tree parm_level;
+  bool no_errors = true;
 
   /* [temp.param]
 
@@ -3389,7 +3539,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
     /* You can't have a function template declaration in a local
        scope, nor you can you define a member of a class template in a
        local scope.  */
-    return;
+    return true;
 
   if (current_class_type
       && !TYPE_BEING_DEFINED (current_class_type)
@@ -3409,40 +3559,72 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
        declared, so there's no need to do it again now.  This function
        was defined in class scope, but we're processing it's body now
        that the class is complete.  */
-    return;
-
-  /* [temp.param]
+    return true;
 
-     If a template-parameter has a default template-argument, all
-     subsequent template-parameters shall have a default
-     template-argument supplied.  */
-  for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level))
+  /* Core issue 226 (C++0x only): the following only applies to class
+     templates.  */
+  if ((cxx_dialect == cxx98) || TREE_CODE (decl) != FUNCTION_DECL)
     {
-      tree inner_parms = TREE_VALUE (parm_level);
-      int ntparms = TREE_VEC_LENGTH (inner_parms);
-      int seen_def_arg_p = 0;
-      int i;
+      /* [temp.param]
 
-      for (i = 0; i < ntparms; ++i)
-       {
-         tree parm = TREE_VEC_ELT (inner_parms, i);
+         If a template-parameter has a default template-argument, all
+         subsequent template-parameters shall have a default
+         template-argument supplied.  */
+      for (parm_level = parms; parm_level; parm_level = TREE_CHAIN (parm_level))
+        {
+          tree inner_parms = TREE_VALUE (parm_level);
+          int ntparms = TREE_VEC_LENGTH (inner_parms);
+          int seen_def_arg_p = 0;
+          int i;
 
-          if (parm == error_mark_node)
-            continue;
+          for (i = 0; i < ntparms; ++i)
+            {
+              tree parm = TREE_VEC_ELT (inner_parms, i);
 
-         if (TREE_PURPOSE (parm))
-           seen_def_arg_p = 1;
-         else if (seen_def_arg_p)
-           {
-             error ("no default argument for %qD", TREE_VALUE (parm));
-             /* For better subsequent error-recovery, we indicate that
-                there should have been a default argument.  */
-             TREE_PURPOSE (parm) = error_mark_node;
-           }
-       }
+              if (parm == error_mark_node)
+                continue;
+
+              if (TREE_PURPOSE (parm))
+                seen_def_arg_p = 1;
+              else if (seen_def_arg_p)
+                {
+                  error ("no default argument for %qD", TREE_VALUE (parm));
+                  /* For better subsequent error-recovery, we indicate that
+                     there should have been a default argument.  */
+                  TREE_PURPOSE (parm) = error_mark_node;
+                  no_errors = false;
+                }
+             else if (is_primary
+                      && !is_partial
+                      && !is_friend_decl
+                      && TREE_CODE (decl) == TYPE_DECL
+                      && i < ntparms - 1
+                      && template_parameter_pack_p (TREE_VALUE (parm)))
+               {
+                 /* A primary class template can only have one
+                    parameter pack, at the end of the template
+                    parameter list.  */
+
+                 if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL)
+                   error ("parameter pack %qE must be at the end of the"
+                          " template parameter list", TREE_VALUE (parm));
+                 else
+                   error ("parameter pack %qT must be at the end of the"
+                          " template parameter list", 
+                          TREE_TYPE (TREE_VALUE (parm)));
+
+                 TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) 
+                   = error_mark_node;
+                 no_errors = false;
+               }
+            }
+        }
     }
 
-  if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary)
+  if (((cxx_dialect == cxx98) && TREE_CODE (decl) != TYPE_DECL)
+      || is_partial 
+      || !is_primary
+      || is_friend_decl)
     /* For an ordinary class template, default template arguments are
        allowed at the innermost level, e.g.:
         template <class T = int>
@@ -3453,8 +3635,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
         The template parameter list of a specialization shall not
         contain default template argument values.
 
-       So, for a partial specialization, or for a function template,
-       we look at all of them.  */
+       So, for a partial specialization, or for a function template
+       (in C++98/C++03), we look at all of them.  */
     ;
   else
     /* But, for a primary class template that is not a partial
@@ -3463,7 +3645,11 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
     parms = TREE_CHAIN (parms);
 
   /* Figure out what error message to issue.  */
-  if (TREE_CODE (decl) == FUNCTION_DECL)
+  if (is_friend_decl == 2)
+    msg = "default template arguments may not be used in function template friend re-declaration";
+  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";
   else if (is_partial)
     msg = "default template arguments may not be used in partial specializations";
@@ -3502,6 +3688,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
            {
              if (msg)
                {
+                  no_errors = false;
+                  if (is_friend_decl == 2)
+                    return no_errors;
+
                  error (msg, decl);
                  msg = 0;
                }
@@ -3517,6 +3707,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
       if (msg)
        msg = "default argument for template parameter for class enclosing %qD";
     }
+
+  return no_errors;
 }
 
 /* Worker for push_template_decl_real, called via
@@ -3644,38 +3836,54 @@ push_template_decl_real (tree decl, bool is_friend)
   /* Check to see that the rules regarding the use of default
      arguments are not being violated.  */
   check_default_tmpl_args (decl, current_template_parms,
-                          primary, is_partial);
+                          primary, is_partial, /*is_friend_decl=*/0);
 
   /* Ensure that there are no parameter packs in the type of this
      declaration that have not been expanded.  */
-  check_for_bare_parameter_packs (TREE_TYPE (decl));
-
-  if (is_partial)
-    return process_partial_specialization (decl);
-
-  /* A primary class template can only have one parameter pack, at the
-     end of the template parameter list.  */
-  if (primary && TREE_CODE (decl) == TYPE_DECL)
+  if (TREE_CODE (decl) == FUNCTION_DECL)
     {
-      tree inner_parms 
-       = INNERMOST_TEMPLATE_PARMS (current_template_parms);
-      int i, len = TREE_VEC_LENGTH (inner_parms);
-      for (i = 0; i < len - 1; i++)
+      /* Check each of the arguments individually to see if there are
+         any bare parameter packs.  */
+      tree type = TREE_TYPE (decl);
+      tree arg = DECL_ARGUMENTS (decl);
+      tree argtype = TYPE_ARG_TYPES (type);
+
+      while (arg && argtype)
         {
-          tree parm = TREE_VALUE (TREE_VEC_ELT (inner_parms, i));
+          if (!FUNCTION_PARAMETER_PACK_P (arg)
+              && check_for_bare_parameter_packs (TREE_TYPE (arg)))
+            {
+            /* This is a PARM_DECL that contains unexpanded parameter
+               packs. We have already complained about this in the
+               check_for_bare_parameter_packs call, so just replace
+               these types with ERROR_MARK_NODE.  */
+              TREE_TYPE (arg) = error_mark_node;
+              TREE_VALUE (argtype) = error_mark_node;
+            }
 
-         if (template_parameter_pack_p (parm))
-           {
-             if (TREE_CODE (parm) == PARM_DECL)
-               error ("parameter pack %qE must be at the end of the"
-                      " template parameter list", parm);
-             else
-               error ("parameter pack %qT must be at the end of the"
-                      " template parameter list", TREE_TYPE (parm));
-           }
+          arg = TREE_CHAIN (arg);
+          argtype = TREE_CHAIN (argtype);
         }
+
+      /* Check for bare parameter packs in the return type and the
+         exception specifiers.  */
+      if (check_for_bare_parameter_packs (TREE_TYPE (type)))
+       /* Errors were already issued, set return type to int
+          as the frontend doesn't expect error_mark_node as
+          the return type.  */
+       TREE_TYPE (type) = integer_type_node;
+      if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type)))
+       TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE;
+    }
+  else if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
+    {
+      TREE_TYPE (decl) = error_mark_node;
+      return error_mark_node;
     }
 
+  if (is_partial)
+    return process_partial_specialization (decl);
+
   args = current_template_args ();
 
   if (!ctx
@@ -3724,27 +3932,15 @@ push_template_decl_real (tree decl, bool is_friend)
     {
       tree a, t, current, parms;
       int i;
+      tree tinfo = get_template_info (decl);
 
-      if (TREE_CODE (decl) == TYPE_DECL)
-       {
-         if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl)))
-              || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
-             && TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
-             && TYPE_TI_TEMPLATE (TREE_TYPE (decl)))
-           tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl));
-         else
-           {
-             error ("%qD does not declare a template type", decl);
-             return decl;
-           }
-       }
-      else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl))
+      if (!tinfo)
        {
          error ("template definition of non-template %q#D", decl);
-         return decl;
+         return error_mark_node;
        }
-      else
-       tmpl = DECL_TI_TEMPLATE (decl);
+
+      tmpl = TI_TEMPLATE (tinfo);
 
       if (DECL_FUNCTION_TEMPLATE_P (tmpl)
          && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
@@ -3804,14 +4000,29 @@ push_template_decl_real (tree decl, bool is_friend)
                return error_mark_node;
              }
 
-           /* Perhaps we should also check that the parms are used in the
-              appropriate qualifying scopes in the declarator?  */
-
            if (current == decl)
              current = ctx;
            else
-             current = TYPE_CONTEXT (current);
+             current = (TYPE_P (current)
+                        ? TYPE_CONTEXT (current)
+                        : DECL_CONTEXT (current));
          }
+
+      /* Check that the parms are used in the appropriate qualifying scopes
+        in the declarator.  */
+      if (!comp_template_args
+         (TI_ARGS (tinfo),
+          TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl)))))
+       {
+         error ("\
+template arguments to %qD do not match original template %qD",
+                decl, DECL_TEMPLATE_RESULT (tmpl));
+         if (!uses_template_parms (TI_ARGS (tinfo)))
+           inform ("use template<> for an explicit specialization");
+         /* Avoid crash in import_export_decl.  */
+         DECL_INTERFACE_KNOWN (decl) = 1;
+         return error_mark_node;
+       }
     }
 
   DECL_TEMPLATE_RESULT (tmpl) = decl;
@@ -3838,10 +4049,13 @@ push_template_decl_real (tree decl, bool is_friend)
 
   if (primary)
     {
+      tree parms = DECL_TEMPLATE_PARMS (tmpl);
+      int i;
+
       DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
       if (DECL_CONV_FN_P (tmpl))
        {
-         int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
+         int depth = TMPL_PARMS_DEPTH (parms);
 
          /* It is a conversion operator. See if the type converted to
             depends on innermost template operands.  */
@@ -3850,6 +4064,16 @@ push_template_decl_real (tree decl, bool is_friend)
                                         depth))
            DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
        }
+
+      /* Give template template parms a DECL_CONTEXT of the template
+        for which they are a parameter.  */
+      parms = INNERMOST_TEMPLATE_PARMS (parms);
+      for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
+       {
+         tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+         if (TREE_CODE (parm) == TEMPLATE_DECL)
+           DECL_CONTEXT (parm) = tmpl;
+       }
     }
 
   /* The DECL_TI_ARGS of DECL contains full set of arguments referring
@@ -3913,10 +4137,10 @@ redeclare_class_template (tree type, tree parms)
 
   if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
     {
-      error ("previous declaration %q+D", tmpl);
-      error ("used %d template parameter(s) instead of %d",
-            TREE_VEC_LENGTH (tmpl_parms),
-            TREE_VEC_LENGTH (parms));
+      error ("redeclared with %d template parameter(s)", 
+             TREE_VEC_LENGTH (parms));
+      inform ("previous declaration %q+D used %d template parameter(s)", 
+             tmpl, TREE_VEC_LENGTH (tmpl_parms));
       return false;
     }
 
@@ -3939,9 +4163,15 @@ redeclare_class_template (tree type, tree parms)
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
         TEMPLATE_DECL.  */
       if (tmpl_parm != error_mark_node
-          && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-          || (TREE_CODE (tmpl_parm) != TYPE_DECL
-              && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
+         && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+             || (TREE_CODE (tmpl_parm) != TYPE_DECL
+                 && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))
+             || (TREE_CODE (tmpl_parm) != PARM_DECL
+                 && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (tmpl_parm))
+                     != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm))))
+             || (TREE_CODE (tmpl_parm) == PARM_DECL
+                 && (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (tmpl_parm))
+                     != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))))))
        {
          error ("template parameter %q+#D", tmpl_parm);
          error ("redeclared here as %q#D", parm);
@@ -3955,7 +4185,7 @@ 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);
-         error ("%J  original definition appeared here", tmpl_parm);
+         inform ("%Joriginal definition appeared here", tmpl_parm);
          return false;
        }
 
@@ -4498,6 +4728,77 @@ coerce_template_template_parms (tree parm_parms,
   return 1;
 }
 
+/* Verifies that the deduced template arguments (in TARGS) for the
+   template template parameters (in TPARMS) represent valid bindings,
+   by comparing the template parameter list of each template argument
+   to the template parameter list of its corresponding template
+   template parameter, in accordance with DR150. This
+   routine can only be called after all template arguments have been
+   deduced. It will return TRUE if all of the template template
+   parameter bindings are okay, FALSE otherwise.  */
+bool 
+template_template_parm_bindings_ok_p (tree tparms, tree targs)
+{
+  int i, ntparms = TREE_VEC_LENGTH (tparms);
+
+  targs = INNERMOST_TEMPLATE_ARGS (targs);
+
+  for (i = 0; i < ntparms; ++i)
+    {
+      tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+      tree targ = TREE_VEC_ELT (targs, i);
+
+      if (TREE_CODE (tparm) == TEMPLATE_DECL && targ)
+       {
+         tree packed_args = NULL_TREE;
+         int idx, len = 1;
+
+         if (ARGUMENT_PACK_P (targ))
+           {
+             /* Look inside the argument pack.  */
+             packed_args = ARGUMENT_PACK_ARGS (targ);
+             len = TREE_VEC_LENGTH (packed_args);
+           }
+
+         for (idx = 0; idx < len; ++idx)
+           {
+             tree targ_parms = NULL_TREE;
+
+             if (packed_args)
+               /* Extract the next argument from the argument
+                  pack.  */
+               targ = TREE_VEC_ELT (packed_args, idx);
+
+             if (PACK_EXPANSION_P (targ))
+               /* Look at the pattern of the pack expansion.  */
+               targ = PACK_EXPANSION_PATTERN (targ);
+
+             /* Extract the template parameters from the template
+                argument.  */
+             if (TREE_CODE (targ) == TEMPLATE_DECL)
+               targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (targ);
+             else if (TREE_CODE (targ) == TEMPLATE_TEMPLATE_PARM)
+               targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_NAME (targ));
+
+             /* Verify that we can coerce the template template
+                parameters from the template argument to the template
+                parameter.  This requires an exact match.  */
+             if (targ_parms
+                 && !coerce_template_template_parms
+                      (DECL_INNERMOST_TEMPLATE_PARMS (tparm),
+                       targ_parms,
+                       tf_none,
+                       tparm,
+                       targs))
+               return false;
+           }
+       }
+    }
+
+  /* Everything is okay.  */
+  return true;
+}
+
 /* Convert the indicated template ARG as necessary to match the
    indicated template PARM.  Returns the converted ARG, or
    error_mark_node if the conversion was unsuccessful.  Error and
@@ -4513,9 +4814,9 @@ convert_template_argument (tree parm,
                           int i,
                           tree in_decl)
 {
+  tree orig_arg;
   tree val;
   int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
-  tree check_arg = arg;
 
   if (TREE_CODE (arg) == TREE_LIST
       && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
@@ -4525,24 +4826,26 @@ convert_template_argument (tree parm,
         invalid, but static members are OK.  In any
         case, grab the underlying fields/functions
         and issue an error later if required.  */
-      arg = TREE_VALUE (arg);
+      orig_arg = TREE_VALUE (arg);
       TREE_TYPE (arg) = unknown_type_node;
     }
 
+  orig_arg = arg;
+
   requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
   requires_type = (TREE_CODE (parm) == TYPE_DECL
                   || requires_tmpl_type);
 
-  /* When determining whether a argument pack expansion is a template,
+  /* When determining whether an argument pack expansion is a template,
      look at the pattern.  */
-  if (TREE_CODE (check_arg) == TYPE_PACK_EXPANSION)
-    check_arg = PACK_EXPANSION_PATTERN (check_arg);
+  if (TREE_CODE (arg) == TYPE_PACK_EXPANSION)
+    arg = PACK_EXPANSION_PATTERN (arg);
 
   is_tmpl_type = 
-    ((TREE_CODE (check_arg) == TEMPLATE_DECL
-      && TREE_CODE (DECL_TEMPLATE_RESULT (check_arg)) == TYPE_DECL)
-     || TREE_CODE (check_arg) == TEMPLATE_TEMPLATE_PARM
-     || TREE_CODE (check_arg) == UNBOUND_CLASS_TEMPLATE);
+    ((TREE_CODE (arg) == TEMPLATE_DECL
+      && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+     || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+     || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
 
   if (is_tmpl_type
       && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
@@ -4555,12 +4858,13 @@ convert_template_argument (tree parm,
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
       pedwarn ("to refer to a type member of a template parameter, "
-              "use %<typename %E%>", arg);
+              "use %<typename %E%>", orig_arg);
 
-      arg = make_typename_type (TREE_OPERAND (arg, 0),
-                               TREE_OPERAND (arg, 1),
-                               typename_type,
-                               complain & tf_error);
+      orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
+                                    TREE_OPERAND (arg, 1),
+                                    typename_type,
+                                    complain & tf_error);
+      arg = orig_arg;
       is_type = 1;
     }
   if (is_type != requires_type)
@@ -4575,11 +4879,11 @@ convert_template_argument (tree parm,
              if (is_type)
                error ("  expected a constant of type %qT, got %qT",
                       TREE_TYPE (parm),
-                      (is_tmpl_type ? DECL_NAME (arg) : arg));
+                      (DECL_P (arg) ? DECL_NAME (arg) : orig_arg));
              else if (requires_tmpl_type)
-               error ("  expected a class template, got %qE", arg);
+               error ("  expected a class template, got %qE", orig_arg);
              else
-               error ("  expected a type, got %qE", arg);
+               error ("  expected a type, got %qE", orig_arg);
            }
        }
       return error_mark_node;
@@ -4594,7 +4898,7 @@ convert_template_argument (tree parm,
          if (is_tmpl_type)
            error ("  expected a type, got %qT", DECL_NAME (arg));
          else
-           error ("  expected a class template, got %qT", arg);
+           error ("  expected a class template, got %qT", orig_arg);
        }
       return error_mark_node;
     }
@@ -4612,19 +4916,13 @@ convert_template_argument (tree parm,
              tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
              tree argparm;
 
-              check_arg = arg;
-              /* When determining whether a pack expansion is a template,
-                 look at the pattern.  */
-              if (TREE_CODE (check_arg) == TYPE_PACK_EXPANSION)
-                check_arg = PACK_EXPANSION_PATTERN (check_arg);
-
-              argparm = DECL_INNERMOST_TEMPLATE_PARMS (check_arg);
+              argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
 
              if (coerce_template_template_parms (parmparm, argparm,
                                                  complain, in_decl,
                                                  args))
                {
-                 val = arg;
+                 val = orig_arg;
 
                  /* TEMPLATE_TEMPLATE_PARM node is preferred over
                     TEMPLATE_DECL.  */
@@ -4633,9 +4931,9 @@ 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 (check_arg))
+                               && DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
                         {
-                          val = TREE_TYPE (check_arg);
+                          val = TREE_TYPE (arg);
                           val = make_pack_expansion (val);
                         }
                     }
@@ -4648,7 +4946,7 @@ convert_template_argument (tree parm,
                             "template parameter list for %qD",
                             i + 1, in_decl);
                      error ("  expected a template of type %qD, got %qD",
-                            parm, arg);
+                            parm, orig_arg);
                    }
 
                  val = error_mark_node;
@@ -4656,7 +4954,7 @@ convert_template_argument (tree parm,
            }
        }
       else
-       val = arg;
+       val = orig_arg;
       /* We only form one instance of each template specialization.
         Therefore, if we use a non-canonical variant (i.e., a
         typedef), any future messages referring to the type will use
@@ -4672,7 +4970,7 @@ convert_template_argument (tree parm,
       if (invalid_nontype_parm_type_p (t, complain))
        return error_mark_node;
 
-      if (!uses_template_parms (arg) && !uses_template_parms (t))
+      if (!uses_template_parms (orig_arg) && !uses_template_parms (t))
        /* We used to call digest_init here.  However, digest_init
           will report errors, which we don't want when complain
           is zero.  More importantly, digest_init will try too
@@ -4683,19 +4981,136 @@ convert_template_argument (tree parm,
           conversions can occur is part of determining which
           function template to call, or whether a given explicit
           argument specification is valid.  */
-       val = convert_nontype_argument (t, arg);
+       val = convert_nontype_argument (t, orig_arg);
       else
-       val = arg;
+       val = orig_arg;
 
       if (val == NULL_TREE)
        val = error_mark_node;
       else if (val == error_mark_node && (complain & tf_error))
-       error ("could not convert template argument %qE to %qT",  arg, t);
+       error ("could not convert template argument %qE to %qT",  orig_arg, t);
     }
 
   return val;
 }
 
+/* Coerces the remaining template arguments in INNER_ARGS (from
+   ARG_IDX to the end) into the parameter pack at PARM_IDX in PARMS.
+   Returns the coerced argument pack. PARM_IDX is the position of this
+   parameter in the template parameter list. ARGS is the original
+   template argument list.  */
+static tree
+coerce_template_parameter_pack (tree parms,
+                                int parm_idx,
+                                tree args,
+                                tree inner_args,
+                                int arg_idx,
+                                tree new_args,
+                                int* lost,
+                                tree in_decl,
+                                tsubst_flags_t complain)
+{
+  tree parm = TREE_VEC_ELT (parms, parm_idx);
+  int nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
+  tree packed_args;
+  tree argument_pack;
+  tree packed_types = NULL_TREE;
+
+  if (arg_idx > nargs)
+    arg_idx = nargs;
+
+  packed_args = make_tree_vec (nargs - arg_idx);
+
+  if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL
+      && uses_parameter_packs (TREE_TYPE (TREE_VALUE (parm))))
+    {
+      /* When the template parameter is a non-type template
+         parameter pack whose type uses parameter packs, we need
+         to look at each of the template arguments
+         separately. Build a vector of the types for these
+         non-type template parameters in PACKED_TYPES.  */
+      tree expansion 
+        = make_pack_expansion (TREE_TYPE (TREE_VALUE (parm)));
+      packed_types = tsubst_pack_expansion (expansion, args,
+                                            complain, in_decl);
+
+      if (packed_types == error_mark_node)
+        return error_mark_node;
+
+      /* Check that we have the right number of arguments.  */
+      if (arg_idx < nargs
+          && !PACK_EXPANSION_P (TREE_VEC_ELT (inner_args, arg_idx))
+          && nargs - arg_idx != TREE_VEC_LENGTH (packed_types))
+        {
+          int needed_parms 
+            = TREE_VEC_LENGTH (parms) - 1 + TREE_VEC_LENGTH (packed_types);
+          error ("wrong number of template arguments (%d, should be %d)",
+                 nargs, needed_parms);
+          return error_mark_node;
+        }
+
+      /* If we aren't able to check the actual arguments now
+         (because they haven't been expanded yet), we can at least
+         verify that all of the types used for the non-type
+         template parameter pack are, in fact, valid for non-type
+         template parameters.  */
+      if (arg_idx < nargs 
+          && PACK_EXPANSION_P (TREE_VEC_ELT (inner_args, arg_idx)))
+        {
+          int j, len = TREE_VEC_LENGTH (packed_types);
+          for (j = 0; j < len; ++j)
+            {
+              tree t = TREE_VEC_ELT (packed_types, j);
+              if (invalid_nontype_parm_type_p (t, complain))
+                return error_mark_node;
+            }
+        }
+    }
+
+  /* Convert the remaining arguments, which will be a part of the
+     parameter pack "parm".  */
+  for (; arg_idx < nargs; ++arg_idx)
+    {
+      tree arg = TREE_VEC_ELT (inner_args, arg_idx);
+      tree actual_parm = TREE_VALUE (parm);
+
+      if (packed_types && !PACK_EXPANSION_P (arg))
+        {
+          /* When we have a vector of types (corresponding to the
+             non-type template parameter pack that uses parameter
+             packs in its type, as mention above), and the
+             argument is not an expansion (which expands to a
+             currently unknown number of arguments), clone the
+             parm and give it the next type in PACKED_TYPES.  */
+          actual_parm = copy_node (actual_parm);
+          TREE_TYPE (actual_parm) = 
+            TREE_VEC_ELT (packed_types, arg_idx - parm_idx);
+        }
+
+      if (arg != error_mark_node)
+       arg = convert_template_argument (actual_parm, 
+                                        arg, new_args, complain, parm_idx,
+                                        in_decl);
+      if (arg == error_mark_node)
+        (*lost)++;
+      TREE_VEC_ELT (packed_args, arg_idx - parm_idx) = arg; 
+    }
+
+  if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL
+      || TREE_CODE (TREE_VALUE (parm)) == TEMPLATE_DECL)
+    argument_pack = make_node (TYPE_ARGUMENT_PACK);
+  else
+    {
+      argument_pack = make_node (NONTYPE_ARGUMENT_PACK);
+      TREE_TYPE (argument_pack) 
+        = tsubst (TREE_TYPE (TREE_VALUE (parm)), new_args, complain, in_decl);
+      TREE_CONSTANT (argument_pack) = 1;
+    }
+
+  SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
+  return argument_pack;
+}
+
 /* Convert all template arguments to their appropriate types, and
    return a vector containing the innermost resulting template
    arguments.  If any error occurs, return error_mark_node. Error and
@@ -4716,7 +5131,7 @@ coerce_template_parms (tree parms,
                       bool require_all_args,
                       bool use_default_args)
 {
-  int nparms, nargs, i, lost = 0;
+  int nparms, nargs, parm_idx, arg_idx, lost = 0;
   tree inner_args;
   tree new_args;
   tree new_inner_args;
@@ -4726,7 +5141,7 @@ coerce_template_parms (tree parms,
      variadic template parameter list. Since it's an int, we can also
      subtract it from nparms to get the number of non-variadic
      parameters.  */
-  int variadic_p = template_parms_variadic_p (parms) ? 1 : 0;
+  int variadic_p = 0;
 
   inner_args 
     = expand_template_argument_pack (INNERMOST_TEMPLATE_ARGS (args));
@@ -4734,6 +5149,17 @@ coerce_template_parms (tree parms,
   nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
   nparms = TREE_VEC_LENGTH (parms);
 
+  /* Determine if there are any parameter packs.  */
+  for (parm_idx = 0; parm_idx < nparms; ++parm_idx)
+    {
+      tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx));
+      if (template_parameter_pack_p (tparm))
+        {
+          variadic_p = 1;
+          break;
+        }
+    }
+
   if ((nargs > nparms - variadic_p && !variadic_p)
       || (nargs < nparms - variadic_p
          && require_all_args
@@ -4766,164 +5192,92 @@ coerce_template_parms (tree parms,
   skip_evaluation = false;
   new_inner_args = make_tree_vec (nparms);
   new_args = add_outermost_template_args (args, new_inner_args);
-  for (i = 0; i < nparms - variadic_p; i++)
+  for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
     {
       tree arg;
       tree parm;
 
       /* Get the Ith template parameter.  */
-      parm = TREE_VEC_ELT (parms, i);
+      parm = TREE_VEC_ELT (parms, parm_idx);
  
       if (parm == error_mark_node)
       {
-        TREE_VEC_ELT (new_inner_args, i) = error_mark_node;
+        TREE_VEC_ELT (new_inner_args, arg_idx) = error_mark_node;
         continue;
       }
 
-      /* Calculate the Ith argument.  */
-      if (i < nargs)
+      /* Calculate the next argument.  */
+      if (template_parameter_pack_p (TREE_VALUE (parm)))
         {
-          arg = TREE_VEC_ELT (inner_args, i);
-        
-          if (PACK_EXPANSION_P (arg))
+          /* All remaining arguments will be placed in the
+             template parameter pack PARM.  */
+          arg = coerce_template_parameter_pack (parms, parm_idx, args, 
+                                                inner_args, arg_idx,
+                                                new_args, &lost,
+                                                in_decl, complain);
+          
+          /* Store this argument.  */
+          if (arg == error_mark_node)
+            lost++;
+          TREE_VEC_ELT (new_inner_args, parm_idx) = arg;
+
+          /* We are done with all of the arguments.  */
+          arg_idx = nargs;
+
+          continue;
+        }
+      else if (arg_idx < nargs)
+        {
+          arg = TREE_VEC_ELT (inner_args, arg_idx);
+
+          if (arg && PACK_EXPANSION_P (arg))
             {
-              /* If ARG is a pack expansion, then PARM must be
-                 a template parameter pack. We can't expand into a
-                 fixed-length argument list.  */
-              tree actual_parm = TREE_VALUE (parm);
-              bool parm_is_parameter_pack 
-               = template_parameter_pack_p (actual_parm);
-
-              if (!parm_is_parameter_pack)
-                {
-                  if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
-                    error ("cannot expand %<%E%> into a fixed-length "
-                           "argument list", arg);
-                  else
-                    error ("cannot expand %<%T%> into a fixed-length "
-                           "argument list", arg);
-                }
+             if (complain & tf_error)
+               {
+                 /* If ARG is a pack expansion, but PARM is not a
+                    template parameter pack (if it were, we would have
+                    handled it above), we're trying to expand into a
+                    fixed-length argument list.  */
+                 if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
+                   error ("cannot expand %<%E%> into a fixed-length "
+                          "argument list", arg);
+                 else
+                   error ("cannot expand %<%T%> into a fixed-length "
+                          "argument list", arg);
+               }
+             return error_mark_node;
             }
         }
       else if (require_all_args)
-       /* There must be a default arg in this case.  */
-       arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
-                                  complain, in_decl);
+        /* There must be a default arg in this case.  */
+        arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
+                                   complain, in_decl);
       else
        break;
 
-      gcc_assert (arg);
       if (arg == error_mark_node)
        {
          if (complain & tf_error)
-           error ("template argument %d is invalid", i + 1);
-       }
+           error ("template argument %d is invalid", arg_idx + 1);
+       }
+      else if (!arg)
+        /* This only occurs if there was an error in the template
+           parameter list itself (which we would already have
+           reported) that we are trying to recover from, e.g., a class
+           template with a parameter list such as
+           template<typename..., typename>.  */
+        return error_mark_node;
       else
        arg = convert_template_argument (TREE_VALUE (parm),
-                                        arg, new_args, complain, i,
-                                        in_decl);
+                                        arg, new_args, complain, 
+                                         parm_idx, in_decl);
 
       if (arg == error_mark_node)
        lost++;
-      TREE_VEC_ELT (new_inner_args, i) = arg;
+      TREE_VEC_ELT (new_inner_args, arg_idx) = arg;
     }
   skip_evaluation = saved_skip_evaluation;
 
-  if (variadic_p)
-    {
-      int expected_len = nargs - nparms + 1;
-      tree parm = TREE_VEC_ELT (parms, nparms - 1);
-      tree packed_args;
-      tree argument_pack;
-      tree packed_types = NULL_TREE;
-      
-      packed_args = make_tree_vec (expected_len >= 0 ? expected_len : 0);
-
-      if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL
-         && uses_parameter_packs (TREE_TYPE (TREE_VALUE (parm))))
-       {
-         /* When the template parameter is a non-type template
-            parameter pack whose type uses parameter packs, we need
-            to look at each of the template arguments
-            separately. Build a vector of the types for these
-            non-type template parameters in PACKED_TYPES.  */
-         tree expansion 
-           = make_pack_expansion (TREE_TYPE (TREE_VALUE (parm)));
-         packed_types = tsubst_pack_expansion (expansion, args,
-                                               complain, in_decl);
-
-         if (packed_types == error_mark_node)
-           return error_mark_node;
-
-         /* Check that we have the right number of arguments.  */
-         if (i < nargs
-             && !PACK_EXPANSION_P (TREE_VEC_ELT (inner_args, i))
-             && nargs - i != TREE_VEC_LENGTH (packed_types))
-           {
-             error ("wrong number of template arguments (%d, should be %d)",
-                    nargs, nparms - 1 + TREE_VEC_LENGTH (packed_types));
-             return error_mark_node;
-           }
-
-         /* If we aren't able to check the actual arguments now
-            (because they haven't been expanded yet), we can at least
-            verify that all of the types used for the non-type
-            template parameter pack are, in fact, valid for non-type
-            template parameters.  */
-         if (i < nargs && PACK_EXPANSION_P (TREE_VEC_ELT (inner_args, i)))
-           {
-             int j, len = TREE_VEC_LENGTH (packed_types);
-             for (j = 0; j < len; ++j)
-               {
-                 tree t = TREE_VEC_ELT (packed_types, j);
-                 if (invalid_nontype_parm_type_p (t, complain))
-                   return error_mark_node;
-               }
-           }
-       }
-
-      /* Convert the remaining arguments, which will be a part of the
-         parameter pack "parm".  */
-      for (; i < nargs; ++i)
-        {
-          tree arg = TREE_VEC_ELT (inner_args, i);
-         tree actual_parm = TREE_VALUE (parm);
-
-         if (packed_types && !PACK_EXPANSION_P (arg))
-           {
-             /* When we have a vector of types (corresponding to the
-                non-type template parameter pack that uses parameter
-                packs in its type, as mention above), and the
-                argument is not an expansion (which expands to a
-                currently unknown number of arguments), clone the
-                parm and give it the next type in PACKED_TYPES.  */
-             actual_parm = copy_node (actual_parm);
-             TREE_TYPE (actual_parm) = 
-               TREE_VEC_ELT (packed_types, i - nparms + 1);
-           }
-
-          arg = convert_template_argument (actual_parm, 
-                                           arg, new_args, complain, i,
-                                           in_decl);
-          if (arg == error_mark_node)
-            lost++;
-          TREE_VEC_ELT (packed_args, i - nparms + 1) = arg; 
-        }
-
-      if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL
-          || TREE_CODE (TREE_VALUE (parm)) == TEMPLATE_DECL)
-          argument_pack = make_node (TYPE_ARGUMENT_PACK);
-      else
-        {
-          argument_pack = make_node (NONTYPE_ARGUMENT_PACK);
-          TREE_TYPE (argument_pack) = TREE_TYPE (TREE_VALUE (parm));
-          TREE_CONSTANT (argument_pack) = 1;
-        }
-
-      SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
-      TREE_VEC_ELT (new_inner_args, nparms - 1) = argument_pack;
-    }
-
   if (lost)
     return error_mark_node;
 
@@ -4984,7 +5338,7 @@ add_pending_template (tree d)
   tree ti = (TYPE_P (d)
             ? CLASSTYPE_TEMPLATE_INFO (d)
             : DECL_TEMPLATE_INFO (d));
-  tree pt;
+  struct pending_template *pt;
   int level;
 
   if (TI_PENDING_TEMPLATE_FLAG (ti))
@@ -4993,14 +5347,16 @@ add_pending_template (tree d)
   /* We are called both from instantiate_decl, where we've already had a
      tinst_level pushed, and instantiate_template, where we haven't.
      Compensate.  */
-  level = !(current_tinst_level && TINST_DECL (current_tinst_level) == d);
+  level = !current_tinst_level || current_tinst_level->decl != d;
 
   if (level)
     push_tinst_level (d);
 
-  pt = tree_cons (current_tinst_level, d, NULL_TREE);
+  pt = GGC_NEW (struct pending_template);
+  pt->next = NULL;
+  pt->tinst = current_tinst_level;
   if (last_pending_template)
-    TREE_CHAIN (last_pending_template) = pt;
+    last_pending_template->next = pt;
   else
     pending_templates = pt;
 
@@ -5178,6 +5534,7 @@ lookup_template_class (tree d1,
 
       tree parm;
       tree arglist2;
+      tree outer;
 
       parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
 
@@ -5190,15 +5547,23 @@ lookup_template_class (tree d1,
         instantiation `TT<int>' is seen, we need to build the full
         arguments containing {int} as the innermost level.  Outer levels,
         available when not appearing as default template argument, can be
-        obtained from `current_template_args ()'.
+        obtained from the arguments of the enclosing template.
 
         Suppose that TT is later substituted with std::vector.  The above
         instantiation is `TT<int, std::allocator<T> >' with TT at
         level 1, and T at level 2, while the template arguments at level 1
         becomes {std::vector} and the inner level 2 is {int}.  */
 
-      if (current_template_parms)
-       arglist = add_to_template_args (current_template_args (), arglist);
+      outer = DECL_CONTEXT (template);
+      if (outer)
+       outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
+      else if (current_template_parms)
+       /* This is an argument of the current template, so we haven't set
+          DECL_CONTEXT yet.  */
+       outer = current_template_args ();
+
+      if (outer)
+       arglist = add_to_template_args (outer, arglist);
 
       arglist2 = coerce_template_parms (parmlist, arglist, template,
                                        complain,
@@ -5542,6 +5907,9 @@ struct pair_fn_data
 {
   tree_fn_t fn;
   void *data;
+  /* True when we should also visit template parameters that occur in
+     non-deduced contexts.  */
+  bool include_nondeduced_p;
   struct pointer_set_t *visited;
 };
 
@@ -5556,7 +5924,9 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
   void *data = pfd->data;
 
   if (TYPE_P (t)
-      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited))
+      && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE)
+      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited,
+                                pfd->include_nondeduced_p))
     return error_mark_node;
 
   switch (TREE_CODE (t))
@@ -5571,15 +5941,18 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       if (!TYPE_TEMPLATE_INFO (t))
        *walk_subtrees = 0;
       else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
-                                      fn, data, pfd->visited))
+                                      fn, data, pfd->visited, 
+                                      pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case INTEGER_TYPE:
       if (for_each_template_parm (TYPE_MIN_VALUE (t),
-                                 fn, data, pfd->visited)
+                                 fn, data, pfd->visited, 
+                                 pfd->include_nondeduced_p)
          || for_each_template_parm (TYPE_MAX_VALUE (t),
-                                    fn, data, pfd->visited))
+                                    fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5587,13 +5960,14 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       /* Since we're not going to walk subtrees, we have to do this
         explicitly here.  */
       if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
-                                 pfd->visited))
+                                 pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
     case FUNCTION_TYPE:
       /* Check the return type.  */
-      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
+      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+                                 pfd->include_nondeduced_p))
        return error_mark_node;
 
       /* Check the parameter types.  Since default arguments are not
@@ -5607,7 +5981,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
 
        for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
          if (for_each_template_parm (TREE_VALUE (parm), fn, data,
-                                     pfd->visited))
+                                     pfd->visited, pfd->include_nondeduced_p))
            return error_mark_node;
 
        /* Since we've already handled the TYPE_ARG_TYPES, we don't
@@ -5617,8 +5991,10 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       break;
 
     case TYPEOF_TYPE:
-      if (for_each_template_parm (TYPE_FIELDS (t), fn, data,
-                                 pfd->visited))
+      if (pfd->include_nondeduced_p
+         && for_each_template_parm (TYPE_FIELDS (t), fn, data,
+                                    pfd->visited, 
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5626,7 +6002,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case VAR_DECL:
       if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
          && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
@@ -5634,17 +6010,19 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case CONST_DECL:
       if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
          && for_each_template_parm (DECL_INITIAL (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       if (DECL_CONTEXT (t)
+         && pfd->include_nondeduced_p
          && for_each_template_parm (DECL_CONTEXT (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Record template parameters such as `T' inside `TT<T>'.  */
-      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited))
+      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
+                                 pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
@@ -5660,7 +6038,8 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case TEMPLATE_DECL:
       /* A template template parameter is encountered.  */
       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
-         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
+         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
 
       /* Already substituted template template parameter */
@@ -5670,15 +6049,17 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case TYPENAME_TYPE:
       if (!fn
          || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
-                                    data, pfd->visited))
+                                    data, pfd->visited, 
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case CONSTRUCTOR:
       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
+         && pfd->include_nondeduced_p
          && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
                                     (TREE_TYPE (t)), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5719,11 +6100,16 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
    for_each_template_parm returns 1.  Otherwise, the iteration
    continues.  If FN never returns a nonzero value, the value
    returned by for_each_template_parm is 0.  If FN is NULL, it is
-   considered to be the function which always returns 1.  */
+   considered to be the function which always returns 1.
+
+   If INCLUDE_NONDEDUCED_P, then this routine will also visit template
+   parameters that occur in non-deduced contexts.  When false, only
+   visits those template parameters that can be deduced.  */
 
 static int
 for_each_template_parm (tree t, tree_fn_t fn, void* data,
-                       struct pointer_set_t *visited)
+                       struct pointer_set_t *visited,
+                       bool include_nondeduced_p)
 {
   struct pair_fn_data pfd;
   int result;
@@ -5731,6 +6117,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
   /* Set up.  */
   pfd.fn = fn;
   pfd.data = data;
+  pfd.include_nondeduced_p = include_nondeduced_p;
 
   /* Walk the tree.  (Conceptually, we would like to walk without
      duplicates, but for_each_template_parm_r recursively calls
@@ -5741,10 +6128,10 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
     pfd.visited = visited;
   else
     pfd.visited = pointer_set_create ();
-  result = walk_tree (&t,
-                     for_each_template_parm_r,
-                     &pfd,
-                     pfd.visited) != NULL_TREE;
+  result = cp_walk_tree (&t,
+                        for_each_template_parm_r,
+                        &pfd,
+                        pfd.visited) != NULL_TREE;
 
   /* Clean up.  */
   if (!visited)
@@ -5782,6 +6169,7 @@ uses_template_parms (tree t)
           || TREE_CODE (t) == OVERLOAD
           || TREE_CODE (t) == BASELINK
           || TREE_CODE (t) == IDENTIFIER_NODE
+          || TREE_CODE (t) == TRAIT_EXPR
           || CONSTANT_CLASS_P (t))
     dependent_p = (type_dependent_expression_p (t)
                   || value_dependent_expression_p (t));
@@ -5801,7 +6189,8 @@ uses_template_parms (tree t)
 int
 uses_template_parms_level (tree t, int level)
 {
-  return for_each_template_parm (t, template_parm_this_level_p, &level, NULL);
+  return for_each_template_parm (t, template_parm_this_level_p, &level, NULL,
+                                /*include_nondeduced_p=*/true);
 }
 
 static int tinst_depth;
@@ -5818,7 +6207,7 @@ static int last_template_error_tick;
 static int
 push_tinst_level (tree d)
 {
-  tree new;
+  struct tinst_level *new;
 
   if (tinst_depth >= max_tinst_depth)
     {
@@ -5838,11 +6227,11 @@ push_tinst_level (tree d)
       return 0;
     }
 
-  new = make_node (TINST_LEVEL);
-  TINST_DECL (new) = d;
-  TINST_LOCATION (new) = input_location;
-  TINST_IN_SYSTEM_HEADER_P (new) = in_system_header;
-  TREE_CHAIN (new) = current_tinst_level;
+  new = GGC_NEW (struct tinst_level);
+  new->decl = d;
+  new->locus = input_location;
+  new->in_system_header_p = in_system_header;
+  new->next = current_tinst_level;
   current_tinst_level = new;
 
   ++tinst_depth;
@@ -5861,32 +6250,44 @@ push_tinst_level (tree d)
 static void
 pop_tinst_level (void)
 {
-  tree old = current_tinst_level;
-
   /* Restore the filename and line number stashed away when we started
      this instantiation.  */
-  input_location = TINST_LOCATION (old);
-  in_system_header = TINST_IN_SYSTEM_HEADER_P (old);
-  current_tinst_level = TREE_CHAIN (old);
+  input_location = current_tinst_level->locus;
+  in_system_header = current_tinst_level->in_system_header_p;
+  current_tinst_level = current_tinst_level->next;
   --tinst_depth;
   ++tinst_level_tick;
 }
 
 /* We're instantiating a deferred template; restore the template
    instantiation context in which the instantiation was requested, which
-   is one step out from LEVEL.  */
+   is one step out from LEVEL.  Return the corresponding DECL or TYPE.  */
 
-static void
-reopen_tinst_level (tree level)
+static tree
+reopen_tinst_level (struct tinst_level *level)
 {
-  tree t;
+  struct tinst_level *t;
 
   tinst_depth = 0;
-  for (t = level; t; t = TREE_CHAIN (t))
+  for (t = level; t; t = t->next)
     ++tinst_depth;
 
   current_tinst_level = level;
   pop_tinst_level ();
+  return level->decl;
+}
+
+/* Returns the TINST_LEVEL which gives the original instantiation
+   context.  */
+
+struct tinst_level *
+outermost_tinst_level (void)
+{
+  struct tinst_level *level = current_tinst_level;
+  if (level)
+    while (level->next)
+      level = level->next;
+  return level;
 }
 
 /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL.  ARGS is the
@@ -6209,9 +6610,15 @@ tsubst_friend_class (tree friend_tmpl, tree args)
          > TMPL_ARGS_DEPTH (args))
        {
          tree parms;
+          location_t saved_input_location;
          parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
                                         args, tf_warning_or_error);
+
+          saved_input_location = input_location;
+          input_location = DECL_SOURCE_LOCATION (friend_tmpl);
          redeclare_class_template (TREE_TYPE (tmpl), parms);
+          input_location = saved_input_location;
+          
        }
 
       friend_type = TREE_TYPE (tmpl);
@@ -6269,6 +6676,61 @@ can_complete_type_without_circularity (tree type)
     return 1;
 }
 
+/* Apply any attributes which had to be deferred until instantiation
+   time.  DECL_P, ATTRIBUTES and ATTR_FLAGS are as cplus_decl_attributes;
+   ARGS, COMPLAIN, IN_DECL are as tsubst.  */
+
+static void
+apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
+                               tree args, tsubst_flags_t complain, tree in_decl)
+{
+  tree last_dep = NULL_TREE;
+  tree t;
+  tree *p;
+
+  for (t = attributes; t; t = TREE_CHAIN (t))
+    if (ATTR_IS_DEPENDENT (t))
+      {
+       last_dep = t;
+       attributes = copy_list (attributes);
+       break;
+      }
+
+  if (DECL_P (*decl_p))
+    {
+      if (TREE_TYPE (*decl_p) == error_mark_node)
+       return;
+      p = &DECL_ATTRIBUTES (*decl_p);
+    }
+  else
+    p = &TYPE_ATTRIBUTES (*decl_p);
+
+  if (last_dep)
+    {
+      tree late_attrs = NULL_TREE;
+      tree *q = &late_attrs;
+
+      for (*p = attributes; *p; )
+       {
+         t = *p;
+         if (ATTR_IS_DEPENDENT (t))
+           {
+             *p = TREE_CHAIN (t);
+             TREE_CHAIN (t) = NULL_TREE;
+             TREE_VALUE (t)
+               = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
+                              /*integral_constant_expression_p=*/false);
+             *q = t;
+             q = &TREE_CHAIN (t);
+           }
+         else
+           p = &TREE_CHAIN (t);
+       }
+
+      cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+    }
+}
+
 tree
 instantiate_class_template (tree type)
 {
@@ -6345,7 +6807,7 @@ instantiate_class_template (tree type)
   input_location = DECL_SOURCE_LOCATION (typedecl);
   in_system_header = DECL_IN_SYSTEM_HEADER (typedecl);
 
-  TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
+  TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
   TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
   TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
   TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
@@ -6439,13 +6901,16 @@ instantiate_class_template (tree type)
      information.  */
   xref_basetypes (type, base_list);
 
+  apply_late_template_attributes (&type, TYPE_ATTRIBUTES (pattern),
+                                 (int) ATTR_FLAG_TYPE_IN_PLACE,
+                                 args, tf_error, NULL_TREE);
 
   /* Now that our base classes are set up, enter the scope of the
      class, so that name lookups into base classes, etc. will work
      correctly.  This is precisely analogous to what we do in
      begin_class_definition when defining an ordinary non-template
-     class.  */
-  pushclass (type);
+     class, except we also need to push the enclosing classes.  */
+  push_nested_class (type);
 
   /* Now members are processed in the order of declaration.  */
   for (member = CLASSTYPE_DECL_LIST (pattern);
@@ -6742,7 +7207,7 @@ instantiate_class_template (tree type)
          && DECL_TEMPLATE_INFO (t))
        tsubst_default_arguments (t);
 
-  popclass ();
+  pop_nested_class ();
   pop_from_top_level ();
   pop_deferring_access_checks ();
   pop_tinst_level ();
@@ -6805,10 +7270,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
       tree orig_arg = NULL_TREE;
 
       if (TREE_CODE (parm_pack) == PARM_DECL)
-        {
-          if (local_specializations)
-            arg_pack = retrieve_local_specialization (parm_pack);
-        }
+       arg_pack = retrieve_local_specialization (parm_pack);
       else
         {
           int level, idx, levels;
@@ -6823,6 +7285,31 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
       if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT)
        arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack);
       
+      if (arg_pack && !ARGUMENT_PACK_P (arg_pack))
+       /* This can only happen if we forget to expand an argument
+          pack somewhere else. Just return an error, silently.  */
+       {
+         result = make_tree_vec (1);
+         TREE_VEC_ELT (result, 0) = error_mark_node;
+         return result;
+       }
+
+      if (arg_pack
+          && TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack)) == 1
+          && PACK_EXPANSION_P (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0)))
+        {
+          tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0);
+          tree pattern = PACK_EXPANSION_PATTERN (expansion);
+          if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack))
+              || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern)))
+            /* The argument pack that the parameter maps to is just an
+               expansion of the parameter itself, such as one would
+               find in the implicit typedef of a class inside the
+               class itself.  Consider this parameter "unsubstituted",
+               so that we will maintain the outer pack expansion.  */
+            arg_pack = NULL_TREE;
+        }
+          
       if (arg_pack)
         {
           int my_len = 
@@ -7148,7 +7635,7 @@ tsubst_aggr_type (tree t,
       /* Else fall through.  */
     case ENUMERAL_TYPE:
     case UNION_TYPE:
-      if (TYPE_TEMPLATE_INFO (t))
+      if (TYPE_TEMPLATE_INFO (t) && uses_template_parms (t))
        {
          tree argvec;
          tree context;
@@ -7163,8 +7650,14 @@ tsubst_aggr_type (tree t,
             up.  */
          context = TYPE_CONTEXT (t);
          if (context)
-           context = tsubst_aggr_type (context, args, complain,
-                                       in_decl, /*entering_scope=*/1);
+           {
+             context = tsubst_aggr_type (context, args, complain,
+                                         in_decl, /*entering_scope=*/1);
+             /* If context is a nested class inside a class template,
+                it may still need to be instantiated (c++/33959).  */
+             if (TYPE_P (context))
+               context = complete_type (context);
+           }
 
          /* Then, figure out what arguments are appropriate for the
             type we are trying to find.  For example, given:
@@ -7655,6 +8148,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              = remove_attribute ("visibility", DECL_ATTRIBUTES (r));
          }
        determine_visibility (r);
+
+       apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
+                                       args, complain, in_decl);
       }
       break;
 
@@ -7671,11 +8167,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
             /* If there is a local specialization that isn't a
                parameter pack, it means that we're doing a "simple"
                substitution from inside tsubst_pack_expansion. Just
-               return the local specialiation (which will be a single
+               return the local specialization (which will be a single
                parm).  */
-            tree spec = NULL_TREE;
-            if (local_specializations)
-              spec = retrieve_local_specialization (t);
+            tree spec = retrieve_local_specialization (t);
             if (spec 
                 && TREE_CODE (spec) == PARM_DECL
                 && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION)
@@ -7748,6 +8242,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
             if (!DECL_TEMPLATE_PARM_P (r))
               DECL_ARG_TYPE (r) = type_passed_as (type);
 
+           apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
+                                           args, complain, in_decl);
+
             /* Keep track of the first new parameter we
                generate. That's what will be returned to the
                caller.  */
@@ -7790,6 +8287,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        TREE_CHAIN (r) = NULL_TREE;
        if (VOID_TYPE_P (type))
          error ("instantiation of %q+D as type %qT", r, type);
+
+       apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
+                                       args, complain, in_decl);
       }
       break;
 
@@ -7821,20 +8321,19 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        tree type = NULL_TREE;
        bool local_p;
 
-       if (TREE_CODE (t) == TYPE_DECL)
+       if (TREE_CODE (t) == TYPE_DECL
+           && t == TYPE_MAIN_DECL (TREE_TYPE (t)))
          {
+           /* If this is the canonical decl, we don't have to
+              mess with instantiations, and often we can't (for
+              typename, template type parms and such).  Note that
+              TYPE_NAME is not correct for the above test if
+              we've copied the type for a typedef.  */
            type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-           if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
-               || t == TYPE_MAIN_DECL (TREE_TYPE (t)))
-             {
-               /* If this is the canonical decl, we don't have to
-                  mess with instantiations, and often we can't (for
-                  typename, template type parms and such).  Note that
-                  TYPE_NAME is not correct for the above test if
-                  we've copied the type for a typedef.  */
-               r = TYPE_NAME (type);
-               break;
-             }
+           if (type == error_mark_node)
+             return error_mark_node;
+           r = TYPE_NAME (type);
+           break;
          }
 
        /* Check to see if we already have the specialization we
@@ -7896,6 +8395,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 
        /* Create a new node for the specialization we need.  */
        r = copy_decl (t);
+       if (type == NULL_TREE)
+         type = tsubst (TREE_TYPE (t), args, complain, in_decl);
        if (TREE_CODE (r) == VAR_DECL)
          {
            /* Even if the original location is out of scope, the
@@ -7903,7 +8404,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_DEAD_FOR_LOCAL (r) = 0;
            DECL_INITIALIZED_P (r) = 0;
            DECL_TEMPLATE_INSTANTIATED (r) = 0;
-           type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            if (type == error_mark_node)
              return error_mark_node;
            if (TREE_CODE (type) == FUNCTION_TYPE)
@@ -7967,6 +8467,16 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              }
            determine_visibility (r);
          }
+       /* Preserve a typedef that names a type.  */
+       else if (TREE_CODE (r) == TYPE_DECL
+                && DECL_ORIGINAL_TYPE (t)
+                && type != error_mark_node)
+         {
+           DECL_ORIGINAL_TYPE (r) = tsubst (DECL_ORIGINAL_TYPE (t),
+                                            args, complain, in_decl);
+           TREE_TYPE (r) = type = build_variant_type_copy (type);
+           TYPE_NAME (type) = r;
+         }
 
        if (!local_p)
          {
@@ -7984,6 +8494,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          register_local_specialization (r, t);
 
        TREE_CHAIN (r) = NULL_TREE;
+
+       apply_late_template_attributes (&r, DECL_ATTRIBUTES (r),
+                                       (int) ATTR_FLAG_TYPE_IN_PLACE,
+                                       args, complain, in_decl);
        layout_decl (r, 0);
       }
       break;
@@ -8150,7 +8664,7 @@ tsubst_function_type (tree t,
       && in_decl != NULL_TREE
       && !TREE_NO_WARNING (in_decl)
       && (SCALAR_TYPE_P (return_type) || VOID_TYPE_P (return_type)))
-    warning (OPT_Wreturn_type,
+    warning (OPT_Wignored_qualifiers,
             "type qualifiers ignored on function return type");
 
   /* Construct a new type node and return it.  */
@@ -8215,7 +8729,24 @@ tsubst_exception_specification (tree fntype,
                 expanded_specs = tsubst_pack_expansion (TREE_VALUE (specs),
                                                        args, complain,
                                                        in_decl);
-                len = TREE_VEC_LENGTH (expanded_specs);
+
+               if (expanded_specs == error_mark_node)
+                 return error_mark_node;
+               else if (TREE_CODE (expanded_specs) == TREE_VEC)
+                 len = TREE_VEC_LENGTH (expanded_specs);
+               else
+                 {
+                   /* We're substituting into a member template, so
+                      we got a TYPE_PACK_EXPANSION back.  Add that
+                      expansion and move on.  */
+                   gcc_assert (TREE_CODE (expanded_specs) 
+                               == TYPE_PACK_EXPANSION);
+                   new_specs = add_exception_specifier (new_specs,
+                                                        expanded_specs,
+                                                        complain);
+                   specs = TREE_CHAIN (specs);
+                   continue;
+                 }
               }
 
             for (i = 0; i < len; ++i)
@@ -8275,6 +8806,41 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
   gcc_assert (type != unknown_type_node);
 
+  /* Reuse typedefs.  We need to do this to handle dependent attributes,
+     such as attribute aligned.  */
+  if (TYPE_P (t)
+      && TYPE_NAME (t)
+      && TYPE_NAME (t) != TYPE_MAIN_DECL (t))
+    {
+      tree decl = TYPE_NAME (t);
+      
+      if (DECL_CLASS_SCOPE_P (decl)
+         && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+         && uses_template_parms (DECL_CONTEXT (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);
+       }
+      else if (DECL_FUNCTION_SCOPE_P (decl)
+              && DECL_TEMPLATE_INFO (DECL_CONTEXT (decl))
+              && uses_template_parms (DECL_TI_ARGS (DECL_CONTEXT (decl))))
+       r = retrieve_local_specialization (decl);
+      else
+       /* The typedef is from a non-template context.  */
+       return t;
+
+      if (r)
+       {
+         r = TREE_TYPE (r);
+         r = cp_build_qualified_type_real
+           (r, cp_type_quals (t) | cp_type_quals (r),
+            complain | tf_ignore_bad_quals);
+         return r;
+       }
+      /* Else we must be instantiating the typedef, so fall through.  */
+    }
+
   if (type
       && TREE_CODE (t) != TYPENAME_TYPE
       && TREE_CODE (t) != IDENTIFIER_NODE
@@ -8319,9 +8885,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                           /*integral_constant_expression_p=*/false);
        max = fold_decl_constant_value (max);
 
-       if (TREE_CODE (max) != INTEGER_CST 
-           && TREE_CODE (max) != TEMPLATE_PARM_INDEX
-           && !at_function_scope_p ())
+       if (TREE_CODE (max) != INTEGER_CST
+           && !at_function_scope_p ()
+           && !value_dependent_expression_p (max))
          {
            if (complain & tf_error)
              error ("array bound is not an integer constant");
@@ -8365,18 +8931,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        r = NULL_TREE;
 
        gcc_assert (TREE_VEC_LENGTH (args) > 0);
-       if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
-           || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
-           || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
-         {
-           idx = TEMPLATE_TYPE_IDX (t);
-           level = TEMPLATE_TYPE_LEVEL (t);
-         }
-       else
-         {
-           idx = TEMPLATE_PARM_IDX (t);
-           level = TEMPLATE_PARM_LEVEL (t);
-         }
+       template_parm_level_and_index (t, &level, &idx); 
 
        levels = TMPL_ARGS_DEPTH (args);
        if (level <= levels)
@@ -8480,7 +9035,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                r = copy_type (t);
                TEMPLATE_TYPE_PARM_INDEX (r)
                  = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
-                                               r, levels);
+                                               r, levels, args, complain);
                TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
                TYPE_MAIN_VARIANT (r) = r;
                TYPE_POINTER_TO (r) = NULL_TREE;
@@ -8514,7 +9069,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            break;
 
          case TEMPLATE_PARM_INDEX:
-           r = reduce_template_parm_level (t, type, levels);
+           r = reduce_template_parm_level (t, type, levels, args, complain);
            break;
 
          default:
@@ -8586,8 +9141,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
           -- Attempting to create a pointer to reference type.
           -- Attempting to create a reference to a reference type or
-             a reference to void.  */
-       if (TREE_CODE (type) == REFERENCE_TYPE
+             a reference to void.
+
+         Core issue 106 says that creating a reference to a reference
+         during instantiation is no longer a cause for failure. We
+         only enforce this check in strict C++98 mode.  */
+       if ((TREE_CODE (type) == REFERENCE_TYPE
+            && (((cxx_dialect == cxx98) && flag_iso) || code != REFERENCE_TYPE))
            || (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE))
          {
            static location_t last_loc;
@@ -8596,13 +9156,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               message to avoid spewing a ton of messages during a
               single bad template instantiation.  */
            if (complain & tf_error
-#ifdef USE_MAPPED_LOCATION
-               && last_loc != input_location
-#else
-               && (last_loc.line != input_line
-                   || last_loc.file != input_filename)
-#endif
-                 )
+               && last_loc != input_location)
              {
                if (TREE_CODE (type) == VOID_TYPE)
                  error ("forming reference to void");
@@ -8621,8 +9175,22 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            if (TREE_CODE (type) == METHOD_TYPE)
              r = build_ptrmemfunc_type (r);
          }
+       else if (TREE_CODE (type) == REFERENCE_TYPE)
+         /* In C++0x, during template argument substitution, when there is an
+            attempt to create a reference to a reference type, reference
+            collapsing is applied as described in [14.3.1/4 temp.arg.type]:
+
+            "If a template-argument for a template-parameter T names a type
+            that is a reference to a type A, an attempt to create the type
+            'lvalue reference to cv T' creates the type 'lvalue reference to
+            A,' while an attempt to create the type type rvalue reference to
+            cv T' creates the type T"
+         */
+         r = cp_build_reference_type
+             (TREE_TYPE (type),
+              TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
        else
-         r = build_reference_type (type);
+         r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
        r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
 
        if (r != error_mark_node)
@@ -8735,6 +9303,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          }
 
        r = build_cplus_array_type (type, domain);
+
+       if (TYPE_USER_ALIGN (t))
+         {
+           TYPE_ALIGN (r) = TYPE_ALIGN (t);
+           TYPE_USER_ALIGN (r) = 1;
+         }
+
        return r;
       }
 
@@ -8875,6 +9450,22 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                             complain);
       }
 
+    case DECLTYPE_TYPE:
+      {
+       tree type;
+
+       type = 
+          finish_decltype_type (tsubst_expr 
+                                (DECLTYPE_TYPE_EXPR (t), args,
+                                 complain, in_decl,
+                                 /*integral_constant_expression_p=*/false),
+                                DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
+       return cp_build_qualified_type_real (type,
+                                            cp_type_quals (t)
+                                            | cp_type_quals (type),
+                                            complain);
+      }
+
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
@@ -9231,6 +9822,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
           /* We only want to compute the number of arguments.  */
           tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
                                                 complain, in_decl);
+         if (expanded == error_mark_node)
+           return error_mark_node;
           return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
         }
       /* Fall through */
@@ -9438,6 +10031,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case TYPENAME_TYPE:
     case UNBOUND_CLASS_TEMPLATE:
     case TYPEOF_TYPE:
+    case DECLTYPE_TYPE:
     case TYPE_DECL:
       return tsubst (t, args, complain, in_decl);
 
@@ -9663,7 +10257,23 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                        init = cp_fname_init (name, &TREE_TYPE (decl));
                      }
                    else
-                     init = RECUR (init);
+                     {
+                       tree t = RECUR (init);
+
+                       if (init && !t)
+                         /* If we had an initializer but it
+                            instantiated to nothing,
+                            value-initialize the object.  This will
+                            only occur when the initializer was a
+                            pack expansion where the parameter packs
+                            used in that expansion were of length
+                            zero.  */
+                         init = build_default_init (TREE_TYPE (decl),
+                                                     NULL_TREE);
+                       else
+                         init = t;
+                     }
+
                    finish_decl (decl, init, NULL_TREE);
                  }
              }
@@ -9924,13 +10534,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case OMP_ATOMIC:
-      if (OMP_ATOMIC_DEPENDENT_P (t))
-        {
-         tree op1 = TREE_OPERAND (t, 1);
-         tree lhs = RECUR (TREE_OPERAND (op1, 0));
-         tree rhs = RECUR (TREE_OPERAND (op1, 1));
-         finish_omp_atomic (TREE_CODE (op1), lhs, rhs);
-        }
+      gcc_assert (OMP_ATOMIC_DEPENDENT_P (t));
+      {
+       tree op1 = TREE_OPERAND (t, 1);
+       tree lhs = RECUR (TREE_OPERAND (op1, 0));
+       tree rhs = RECUR (TREE_OPERAND (op1, 1));
+       finish_omp_atomic (TREE_CODE (op1), lhs, rhs);
+      }
       break;
 
     case EXPR_PACK_EXPANSION:
@@ -10214,6 +10824,8 @@ tsubst_copy_and_build (tree t,
           /* We only want to compute the number of arguments.  */
           tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
                                                 complain, in_decl);
+         if (expanded == error_mark_node)
+           return error_mark_node;
           return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
         }
       /* Fall through */
@@ -10267,12 +10879,25 @@ tsubst_copy_and_build (tree t,
       return build_x_arrow (op1);
 
     case NEW_EXPR:
-      return build_new
-       (RECUR (TREE_OPERAND (t, 0)),
-        RECUR (TREE_OPERAND (t, 1)),
-        RECUR (TREE_OPERAND (t, 2)),
-        RECUR (TREE_OPERAND (t, 3)),
-        NEW_EXPR_USE_GLOBAL (t));
+      {
+       tree init = RECUR (TREE_OPERAND (t, 3));
+
+       if (TREE_OPERAND (t, 3) && !init)
+         /* If there was an initializer in the the original tree, but
+            it instantiated to an empty list, then we should pass on
+            VOID_ZERO_NODE to tell build_new that it was an empty
+            initializer () rather than no initializer.  This can only
+            happen when the initializer is a pack expansion whose
+            parameter packs are of length zero.  */
+         init = void_zero_node;
+
+       return build_new
+         (RECUR (TREE_OPERAND (t, 0)),
+          RECUR (TREE_OPERAND (t, 1)),
+          RECUR (TREE_OPERAND (t, 2)),
+          init,
+          NEW_EXPR_USE_GLOBAL (t));
+      }
 
     case DELETE_EXPR:
      return delete_sanity
@@ -10494,15 +11119,23 @@ tsubst_copy_and_build (tree t,
 
        if (object_type && !CLASS_TYPE_P (object_type))
          {
-           if (TREE_CODE (member) == BIT_NOT_EXPR)
-             return finish_pseudo_destructor_expr (object,
-                                                   NULL_TREE,
-                                                   object_type);
-           else if (TREE_CODE (member) == SCOPE_REF
-                    && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
-             return finish_pseudo_destructor_expr (object,
-                                                   object,
-                                                   object_type);
+           if (SCALAR_TYPE_P (object_type))
+             {
+               tree s = NULL_TREE;
+               tree dtor = member;
+
+               if (TREE_CODE (dtor) == SCOPE_REF)
+                 {
+                   s = TREE_OPERAND (dtor, 0);
+                   dtor = TREE_OPERAND (dtor, 1);
+                 }
+               if (TREE_CODE (dtor) == BIT_NOT_EXPR)
+                 {
+                   dtor = TREE_OPERAND (dtor, 0);
+                   if (TYPE_P (dtor))
+                     return finish_pseudo_destructor_expr (object, s, dtor);
+                 }
+             }
          }
        else if (TREE_CODE (member) == SCOPE_REF
                 && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
@@ -10593,7 +11226,9 @@ tsubst_copy_and_build (tree t,
                 ce->value = tsubst_pack_expansion (ce->value, args, complain,
                                                   in_decl);
 
-                if (TREE_VEC_LENGTH (ce->value) == 1)
+               if (ce->value == error_mark_node)
+                 ;
+               else if (TREE_VEC_LENGTH (ce->value) == 1)
                   /* Just move the argument into place.  */
                   ce->value = TREE_VEC_ELT (ce->value, 0);
                 else
@@ -10667,6 +11302,18 @@ tsubst_copy_and_build (tree t,
     case OFFSETOF_EXPR:
       return finish_offsetof (RECUR (TREE_OPERAND (t, 0)));
 
+    case TRAIT_EXPR:
+      {
+       tree type1 = tsubst_copy (TRAIT_EXPR_TYPE1 (t), args,
+                                 complain, in_decl);
+
+       tree type2 = TRAIT_EXPR_TYPE2 (t);
+       if (type2)
+         type2 = tsubst_copy (type2, args, complain, in_decl);
+       
+       return finish_trait_expr (TRAIT_EXPR_KIND (t), type1, type2);
+      }
+
     case STMT_EXPR:
       {
        tree old_stmt_expr = cur_stmt_expr;
@@ -10989,8 +11636,12 @@ fn_type_unification (tree fn,
               /* Mark the argument pack as "incomplete". We could
                  still deduce more arguments during unification.  */
               targ = TMPL_ARG (converted_args, level, idx);
-              ARGUMENT_PACK_INCOMPLETE_P(targ) = 1;
-              ARGUMENT_PACK_EXPLICIT_ARGS (targ) = ARGUMENT_PACK_ARGS (targ);
+              if (targ)
+                {
+                  ARGUMENT_PACK_INCOMPLETE_P(targ) = 1;
+                  ARGUMENT_PACK_EXPLICIT_ARGS (targ) 
+                    = ARGUMENT_PACK_ARGS (targ);
+                }
 
               /* We have some incomplete argument packs.  */
               incomplete_argument_packs_p = true;
@@ -11050,6 +11701,32 @@ fn_type_unification (tree fn,
         }
     }
 
+  /* Now that we have bindings for all of the template arguments,
+     ensure that the arguments deduced for the template template
+     parameters have compatible template parameter lists.  We cannot
+     check this property before we have deduced all template
+     arguments, because the template parameter types of a template
+     template parameter might depend on prior template parameters
+     deduced after the template template parameter.  The following
+     ill-formed example illustrates this issue:
+
+       template<typename T, template<T> class C> void f(C<5>, T);
+
+       template<int N> struct X {};
+
+       void g() {
+         f(X<5>(), 5l); // error: template argument deduction fails
+       }
+
+     The template parameter list of 'C' depends on the template type
+     parameter 'T', but 'C' is deduced to 'X' before 'T' is deduced to
+     'long'.  Thus, we can't check that 'C' cannot bind to 'X' at the
+     time that we deduce 'C'.  */
+  if (result == 0
+      && !template_template_parm_bindings_ok_p 
+           (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs))
+    return 1;
+
   if (result == 0)
     /* All is well so far.  Now, check:
 
@@ -11072,12 +11749,14 @@ fn_type_unification (tree fn,
    sections are symmetric.  PARM is the type of a function parameter
    or the return type of the conversion function.  ARG is the type of
    the argument passed to the call, or the type of the value
-   initialized with the result of the conversion function.  */
+   initialized with the result of the conversion function.
+   ARG_EXPR is the original argument expression, which may be null.  */
 
 static int
 maybe_adjust_types_for_deduction (unification_kind_t strict,
                                  tree* parm,
-                                 tree* arg)
+                                 tree* arg,
+                                 tree arg_expr)
 {
   int result = 0;
 
@@ -11131,6 +11810,16 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
        *arg = TYPE_MAIN_VARIANT (*arg);
     }
 
+  /* From C++0x [14.8.2.1/3 temp.deduct.call] (after DR606), "If P is
+     of the form T&&, where T is a template parameter, and the argument
+     is an lvalue, T is deduced as A& */
+  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
+      && arg_expr && real_lvalue_p (arg_expr))
+    *arg = build_reference_type (*arg);
+
   /* [temp.deduct.call]
 
      If P is a cv-qualified type, the top level cv-qualifiers
@@ -11167,7 +11856,7 @@ type_unification_real (tree tparms,
                       unification_kind_t strict,
                       int flags)
 {
-  tree parm, arg;
+  tree parm, arg, arg_expr;
   int i;
   int ntparms = TREE_VEC_LENGTH (tparms);
   int sub_strict;
@@ -11212,6 +11901,7 @@ type_unification_real (tree tparms,
       parms = TREE_CHAIN (parms);
       arg = TREE_VALUE (args);
       args = TREE_CHAIN (args);
+      arg_expr = NULL;
 
       if (arg == error_mark_node)
        return 1;
@@ -11248,19 +11938,21 @@ type_unification_real (tree tparms,
          gcc_assert (TREE_TYPE (arg) != NULL_TREE);
          if (type_unknown_p (arg))
            {
-             /* [temp.deduct.type] A template-argument can be deduced from
-                a pointer to function or pointer to member function
-                argument if the set of overloaded functions does not
-                contain function templates and at most one of a set of
-                overloaded functions provides a unique match.  */
+             /* [temp.deduct.type] 
 
+                A template-argument can be deduced from a pointer to
+                function or pointer to member function argument if
+                the set of overloaded functions does not contain
+                function templates and at most one of a set of
+                overloaded functions provides a unique match.  */
              if (resolve_overloaded_unification
-                 (tparms, targs, parm, arg, strict, sub_strict)
-                 != 0)
-               return 1;
-             continue;
+                 (tparms, targs, parm, arg, strict, sub_strict))
+               continue;
+
+             return 1;
            }
-         arg = TREE_TYPE (arg);
+         arg_expr = arg;
+         arg = unlowered_expr_type (arg);
          if (arg == error_mark_node)
            return 1;
        }
@@ -11269,7 +11961,8 @@ type_unification_real (tree tparms,
        int arg_strict = sub_strict;
 
        if (!subr)
-         arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
+         arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg,
+                                                         arg_expr);
 
        if (unify (tparms, targs, parm, arg, arg_strict))
          return 1;
@@ -11338,18 +12031,61 @@ type_unification_real (tree tparms,
              && !saw_undeduced++)
            goto again;
 
+          /* Core issue #226 (C++0x) [temp.deduct]:
+
+               If a template argument has not been deduced, its
+               default template argument, if any, is used. 
+
+             When we are in C++98 mode, TREE_PURPOSE will either
+            be NULL_TREE or ERROR_MARK_NODE, so we do not need
+            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);
+              if (arg == error_mark_node)
+                return 1;
+              else
+                {
+                  TREE_VEC_ELT (targs, i) = arg;
+                  continue;
+                }
+            }
+
+          /* If the type parameter is a parameter pack, then it will
+             be deduced to an empty parameter pack.  */
+          if (template_parameter_pack_p (tparm))
+            {
+              tree arg;
+
+              if (TREE_CODE (tparm) == TEMPLATE_PARM_INDEX)
+                {
+                  arg = make_node (NONTYPE_ARGUMENT_PACK);
+                  TREE_TYPE (arg)  = TREE_TYPE (TEMPLATE_PARM_DECL (tparm));
+                  TREE_CONSTANT (arg) = 1;
+                }
+              else
+                arg = make_node (TYPE_ARGUMENT_PACK);
+
+              SET_ARGUMENT_PACK_ARGS (arg, make_tree_vec (0));
+
+              TREE_VEC_ELT (targs, i) = arg;
+              continue;
+            }
+
          return 2;
        }
 
   return 0;
 }
 
-/* Subroutine of type_unification_real.  Args are like the variables at the
-   call site.  ARG is an overloaded function (or template-id); we try
-   deducing template args from each of the overloads, and if only one
-   succeeds, we go with that.  Modifies TARGS and returns 0 on success.  */
+/* Subroutine of type_unification_real.  Args are like the variables
+   at the call site.  ARG is an overloaded function (or template-id);
+   we try deducing template args from each of the overloads, and if
+   only one succeeds, we go with that.  Modifies TARGS and returns
+   true on success.  */
 
-static int
+static bool
 resolve_overloaded_unification (tree tparms,
                                tree targs,
                                tree parm,
@@ -11398,6 +12134,7 @@ resolve_overloaded_unification (tree tparms,
          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)
@@ -11406,18 +12143,20 @@ resolve_overloaded_unification (tree tparms,
              good += try_one_overload (tparms, targs, tempargs, parm,
                                        elem, strict, sub_strict, addr_p);
            }
+         --processing_template_decl;
        }
     }
+  else if (TREE_CODE (arg) != OVERLOAD
+          && TREE_CODE (arg) != FUNCTION_DECL)
+    /* If ARG is, for example, "(0, &f)" then its type will be unknown
+       -- but the deduction does not succeed because the expression is
+       not just the function on its own.  */
+    return false;
   else
-    {
-      gcc_assert (TREE_CODE (arg) == OVERLOAD
-                 || TREE_CODE (arg) == FUNCTION_DECL);
-
-      for (; arg; arg = OVL_NEXT (arg))
-       good += try_one_overload (tparms, targs, tempargs, parm,
-                                 TREE_TYPE (OVL_CURRENT (arg)),
-                                 strict, sub_strict, addr_p);
-    }
+    for (; arg; arg = OVL_NEXT (arg))
+      good += try_one_overload (tparms, targs, tempargs, parm,
+                               TREE_TYPE (OVL_CURRENT (arg)),
+                               strict, sub_strict, addr_p);
 
   /* [temp.deduct.type] A template-argument can be deduced from a pointer
      to function or pointer to member function argument if the set of
@@ -11435,9 +12174,9 @@ resolve_overloaded_unification (tree tparms,
          TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (tempargs, i);
     }
   if (good)
-    return 0;
+    return true;
 
-  return 1;
+  return false;
 }
 
 /* Subroutine of resolve_overloaded_unification; does deduction for a single
@@ -11477,7 +12216,7 @@ try_one_overload (tree tparms,
   else if (addr_p)
     arg = build_pointer_type (arg);
 
-  sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
+  sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL);
 
   /* We don't copy orig_targs for this because if we have already deduced
      some template args from previous args, unify would complain when we
@@ -11753,6 +12492,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
       /* Unify the pattern with the current argument.  */
       {
         tree arg = TREE_VEC_ELT (packed_args, i);
+       tree arg_expr = NULL_TREE;
         int arg_strict = strict;
         bool skip_arg_p = false;
 
@@ -11803,7 +12543,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
 
                 if (!skip_arg_p)
                   {
-                    arg = TREE_TYPE (arg);
+                   arg_expr = arg;
+                    arg = unlowered_expr_type (arg);
                     if (arg == error_mark_node)
                       return 1;
                   }
@@ -11813,7 +12554,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
 
             if (!subr)
               arg_strict |= 
-                maybe_adjust_types_for_deduction (strict, &parm, &arg);
+                maybe_adjust_types_for_deduction (strict, &parm, &arg, 
+                                                 arg_expr);
           }
 
         if (!skip_arg_p)
@@ -11841,6 +12583,16 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
     {
       tree old_pack = TREE_VALUE (pack);
       tree new_args = TREE_TYPE (pack);
+      int i, len = TREE_VEC_LENGTH (new_args);
+      bool nondeduced_p = false;
+
+      /* If NEW_ARGS contains any NULL_TREE entries, we didn't
+        actually deduce anything.  */
+      for (i = 0; i < len && !nondeduced_p; ++i)
+       if (TREE_VEC_ELT (new_args, i) == NULL_TREE)
+         nondeduced_p = true;
+      if (nondeduced_p)
+       continue;
 
       if (old_pack && ARGUMENT_PACK_INCOMPLETE_P (old_pack))
         {
@@ -12028,6 +12780,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
     case TEMPLATE_TEMPLATE_PARM:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
+      if (tparm == error_mark_node)
+       return 1;
 
       if (TEMPLATE_TYPE_LEVEL (parm)
          != template_decl_level (tparm))
@@ -12059,7 +12813,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
            tree argtmplvec
              = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
-           int i;
+           int i, len;
+            int parm_variadic_p = 0;
 
            /* The resolution to DR150 makes clear that default
               arguments for an N-argument may not be used to bind T
@@ -12101,7 +12856,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
               rather than the whole TREE_VEC since they can have
               different number of elements.  */
 
-           for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
+            parmvec = expand_template_argument_pack (parmvec);
+            argvec = expand_template_argument_pack (argvec);
+
+            len = TREE_VEC_LENGTH (parmvec);
+
+            /* Check if the parameters end in a pack, making them
+               variadic.  */
+            if (len > 0
+                && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
+              parm_variadic_p = 1;
+            
+            if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
+              return 1;
+
+             for (i = 0; i < len - parm_variadic_p; ++i)
              {
                if (unify (tparms, targs,
                           TREE_VEC_ELT (parmvec, i),
@@ -12109,6 +12878,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
                           UNIFY_ALLOW_NONE))
                  return 1;
              }
+
+           if (parm_variadic_p
+               && unify_pack_expansion (tparms, targs,
+                                        parmvec, argvec,
+                                        UNIFY_ALLOW_NONE,
+                                        /*call_args_p=*/false,
+                                        /*subr=*/false))
+             return 1;
          }
          arg = TYPE_TI_TEMPLATE (arg);
 
@@ -12531,10 +13308,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
         int argslen = TREE_VEC_LENGTH (packed_args);
         int parm_variadic_p = 0;
 
-        /* Check if the parameters end in a pack, making them variadic.  */
-        if (len > 0 
-           && PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, len - 1)))
-          parm_variadic_p = 1;
+       for (i = 0; i < len; ++i)
+         {
+           if (PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, i)))
+             {
+               if (i == len - 1)
+                 /* We can unify against something with a trailing
+                    parameter pack.  */
+                 parm_variadic_p = 1;
+               else
+                 /* Since there is something following the pack
+                    expansion, we cannot unify this template argument
+                    list.  */
+                 return 0;
+             }
+         }
+         
 
         /* If we don't have enough arguments to satisfy the parameters
            (not counting the pack expression at the end), or we have
@@ -12563,6 +13352,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
       break;
 
+    case TYPEOF_TYPE:
+    case DECLTYPE_TYPE:
+      /* Cannot deduce anything from TYPEOF_TYPE or DECLTYPE_TYPE
+         nodes.  */
+      return 0;
+
+    case ERROR_MARK:
+      /* Unification fails if we hit an error node.  */
+      return 1;
+
     default:
       gcc_assert (EXPR_P (parm));
 
@@ -12802,7 +13601,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
       if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION)
         {
-          int i, len2 = len + 1;
+          int i, len2 = list_length (args2);
           tree parmvec = make_tree_vec (1);
           tree argvec = make_tree_vec (len2);
           tree ta = args2;
@@ -12826,7 +13625,7 @@ more_specialized_fn (tree pat1, tree pat2, int len)
         }
       else if (TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
         {
-          int i, len1 = len + 1;
+          int i, len1 = list_length (args1);
           tree parmvec = make_tree_vec (1);
           tree argvec = make_tree_vec (len1);
           tree ta = args1;
@@ -12888,6 +13687,10 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
       args1 = TREE_CHAIN (args1);
       args2 = TREE_CHAIN (args2);
+
+      /* Stop when an ellipsis is seen.  */
+      if (args1 == NULL_TREE || args2 == NULL_TREE)
+       break;
     }
 
   processing_template_decl--;
@@ -13105,6 +13908,14 @@ get_class_bindings (tree tparms, tree spec_args, tree args)
                              INNERMOST_TEMPLATE_ARGS (args)))
     return NULL_TREE;
 
+  /* Now that we have bindings for all of the template arguments,
+     ensure that the arguments deduced for the template template
+     parameters have compatible template parameter lists.  See the use
+     of template_template_parm_bindings_ok_p in fn_type_unification
+     for more information.  */
+  if (!template_template_parm_bindings_ok_p (tparms, deduced_args))
+    return NULL_TREE;
+
   return deduced_args;
 }
 
@@ -13256,20 +14067,57 @@ most_specialized_class (tree type, tree tmpl)
   int fate;
   bool ambiguous_p;
   tree args;
+  tree outer_args = NULL_TREE;
 
   tmpl = most_general_template (tmpl);
   args = CLASSTYPE_TI_ARGS (type);
+
+  /* For determining which partial specialization to use, only the
+     innermost args are interesting.  */
+  if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+    {
+      outer_args = strip_innermost_template_args (args, 1);
+      args = INNERMOST_TEMPLATE_ARGS (args);
+    }
+
   for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t))
     {
       tree partial_spec_args;
       tree spec_args;
+      tree parms = TREE_VALUE (t);
 
       partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
-      spec_args = get_class_bindings (TREE_VALUE (t),
+      if (outer_args)
+       {
+         int i;
+
+         ++processing_template_decl;
+
+         /* Discard the outer levels of args, and then substitute in the
+            template args from the enclosing class.  */
+         partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
+         partial_spec_args = tsubst_template_args
+           (partial_spec_args, outer_args, tf_none, NULL_TREE);
+
+         /* PARMS already refers to just the innermost parms, but the
+            template parms in partial_spec_args had their levels lowered
+            by tsubst, so we need to do the same for the parm list.  We
+            can't just tsubst the TREE_VEC itself, as tsubst wants to
+            treat a TREE_VEC as an argument vector.  */
+         parms = copy_node (parms);
+         for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
+           TREE_VEC_ELT (parms, i) =
+             tsubst (TREE_VEC_ELT (parms, i), outer_args, tf_none, NULL_TREE);
+
+         --processing_template_decl;
+       }
+      spec_args = get_class_bindings (parms,
                                      partial_spec_args,
                                      args);
       if (spec_args)
        {
+         if (outer_args)
+           spec_args = add_to_template_args (outer_args, spec_args);
          list = tree_cons (spec_args, TREE_VALUE (t), list);
          TREE_TYPE (list) = TREE_TYPE (t);
        }
@@ -13355,6 +14203,11 @@ do_decl_instantiation (tree decl, tree storage)
         VAR_DECLs so we do the lookup here.  Probably, grokdeclarator
         should handle VAR_DECLs as it currently handles
         FUNCTION_DECLs.  */
+      if (!DECL_CLASS_SCOPE_P (decl))
+       {
+         error ("%qD is not a static data member of a class template", decl);
+         return;
+       }
       result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, false);
       if (!result || TREE_CODE (result) != VAR_DECL)
        {
@@ -13821,6 +14674,7 @@ instantiate_decl (tree d, int defer_ok,
   bool pattern_defined;
   int need_push;
   location_t saved_loc = input_location;
+  int saved_in_system_header = in_system_header;
   bool external_p;
 
   /* This function should only be used to instantiate templates for
@@ -13903,6 +14757,7 @@ instantiate_decl (tree d, int defer_ok,
     mark_definable (d);
 
   input_location = DECL_SOURCE_LOCATION (d);
+  in_system_header = DECL_IN_SYSTEM_HEADER (d);
 
   /* If D is a member of an explicitly instantiated class template,
      and no definition is available, treat it like an implicit
@@ -14153,6 +15008,10 @@ instantiate_decl (tree d, int defer_ok,
                   tf_warning_or_error, tmpl,
                   /*integral_constant_expression_p=*/false);
 
+      /* Set the current input_location to the end of the function
+         so that finish_function knows where we are.  */
+      input_location = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
+
       /* We don't need the local specializations any more.  */
       htab_delete (local_specializations);
       local_specializations = saved_local_specializations;
@@ -14170,6 +15029,7 @@ instantiate_decl (tree d, int defer_ok,
 
 out:
   input_location = saved_loc;
+  in_system_header = saved_in_system_header;
   pop_deferring_access_checks ();
   pop_tinst_level ();
 
@@ -14185,8 +15045,6 @@ out:
 void
 instantiate_pending_templates (int retries)
 {
-  tree *t;
-  tree last = NULL_TREE;
   int reconsider;
   location_t saved_loc = input_location;
   int saved_in_system_header = in_system_header;
@@ -14196,7 +15054,7 @@ instantiate_pending_templates (int retries)
      to avoid infinite loop.  */
   if (pending_templates && retries >= max_tinst_depth)
     {
-      tree decl = TREE_VALUE (pending_templates);
+      tree decl = pending_templates->tinst->decl;
 
       error ("template instantiation depth exceeds maximum of %d"
             " instantiating %q+D, possibly from virtual table generation"
@@ -14210,14 +15068,13 @@ instantiate_pending_templates (int retries)
 
   do
     {
+      struct pending_template **t = &pending_templates;
+      struct pending_template *last = NULL;
       reconsider = 0;
-
-      t = &pending_templates;
       while (*t)
        {
-         tree instantiation = TREE_VALUE (*t);
-
-         reopen_tinst_level (TREE_PURPOSE (*t));
+         tree instantiation = reopen_tinst_level ((*t)->tinst);
+         bool complete = false;
 
          if (TYPE_P (instantiation))
            {
@@ -14238,15 +15095,7 @@ instantiate_pending_templates (int retries)
                    reconsider = 1;
                }
 
-             if (COMPLETE_TYPE_P (instantiation))
-               /* If INSTANTIATION has been instantiated, then we don't
-                  need to consider it again in the future.  */
-               *t = TREE_CHAIN (*t);
-             else
-               {
-                 last = *t;
-                 t = &TREE_CHAIN (*t);
-               }
+             complete = COMPLETE_TYPE_P (instantiation);
            }
          else
            {
@@ -14261,19 +15110,21 @@ instantiate_pending_templates (int retries)
                    reconsider = 1;
                }
 
-             if (DECL_TEMPLATE_SPECIALIZATION (instantiation)
-                 || DECL_TEMPLATE_INSTANTIATED (instantiation))
-               /* If INSTANTIATION has been instantiated, then we don't
-                  need to consider it again in the future.  */
-               *t = TREE_CHAIN (*t);
-             else
-               {
-                 last = *t;
-                 t = &TREE_CHAIN (*t);
-               }
+             complete = (DECL_TEMPLATE_SPECIALIZATION (instantiation)
+                         || DECL_TEMPLATE_INSTANTIATED (instantiation));
+           }
+
+         if (complete)
+           /* If INSTANTIATION has been instantiated, then we don't
+              need to consider it again in the future.  */
+           *t = (*t)->next;
+         else
+           {
+             last = *t;
+             t = &(*t)->next;
            }
          tinst_depth = 0;
-         current_tinst_level = NULL_TREE;
+         current_tinst_level = NULL;
        }
       last_pending_template = last;
     }
@@ -14327,37 +15178,49 @@ tsubst_initializer_list (tree t, tree argvec)
           PACK_EXPANSION_PARAMETER_PACKS (expr) =
             PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
 
-          /* Substitute parameter packs into each argument in the
-             TREE_LIST.  */
-          in_base_initializer = 1;
-          for (arg = TREE_VALUE (t); arg; arg = TREE_CHAIN (arg))
-            {
-              tree expanded_exprs;
-
-              /* Expand the argument.  */
-              SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
-              expanded_exprs = tsubst_pack_expansion (expr, argvec,
-                                                      tf_warning_or_error,
-                                                      NULL_TREE);
-
-              /* Prepend each of the expanded expressions to the
-                 corresponding TREE_LIST in EXPANDED_ARGUMENTS.  */
-              for (i = 0; i < len; i++)
-                {
-                  TREE_VEC_ELT (expanded_arguments, i) = 
-                    tree_cons (NULL_TREE, TREE_VEC_ELT (expanded_exprs, i),
-                               TREE_VEC_ELT (expanded_arguments, i));
-                }
-            }
-          in_base_initializer = 0;
+         if (TREE_VALUE (t) == void_type_node)
+           /* VOID_TYPE_NODE is used to indicate
+              value-initialization.  */
+           {
+             for (i = 0; i < len; i++)
+               TREE_VEC_ELT (expanded_arguments, i) = void_type_node;
+           }
+         else
+           {
+             /* Substitute parameter packs into each argument in the
+                TREE_LIST.  */
+             in_base_initializer = 1;
+             for (arg = TREE_VALUE (t); arg; arg = TREE_CHAIN (arg))
+               {
+                 tree expanded_exprs;
+
+                 /* Expand the argument.  */
+                 SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
+                 expanded_exprs 
+                   = tsubst_pack_expansion (expr, argvec,
+                                            tf_warning_or_error,
+                                            NULL_TREE);
+
+                 /* Prepend each of the expanded expressions to the
+                    corresponding TREE_LIST in EXPANDED_ARGUMENTS.  */
+                 for (i = 0; i < len; i++)
+                   {
+                     TREE_VEC_ELT (expanded_arguments, i) = 
+                       tree_cons (NULL_TREE, 
+                                  TREE_VEC_ELT (expanded_exprs, i),
+                                  TREE_VEC_ELT (expanded_arguments, i));
+                   }
+               }
+             in_base_initializer = 0;
 
-          /* Reverse all of the TREE_LISTs in EXPANDED_ARGUMENTS,
-             since we built them backwards.  */
-          for (i = 0; i < len; i++)
-            {
-              TREE_VEC_ELT (expanded_arguments, i) = 
-                nreverse (TREE_VEC_ELT (expanded_arguments, i));
-            }
+             /* Reverse all of the TREE_LISTs in EXPANDED_ARGUMENTS,
+                since we built them backwards.  */
+             for (i = 0; i < len; i++)
+               {
+                 TREE_VEC_ELT (expanded_arguments, i) = 
+                   nreverse (TREE_VEC_ELT (expanded_arguments, i));
+               }
+           }
         }
 
       for (i = 0; i < len; ++i)
@@ -14522,7 +15385,7 @@ record_last_problematic_instantiation (void)
   last_template_error_tick = tinst_level_tick;
 }
 
-tree
+struct tinst_level *
 current_instantiation (void)
 {
   return current_tinst_level;
@@ -14605,13 +15468,18 @@ dependent_type_p_r (tree type)
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       if (TYPE_DOMAIN (type)
-         && ((value_dependent_expression_p
-              (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
-             || (type_dependent_expression_p
-                 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))))
+         && dependent_type_p (TYPE_DOMAIN (type)))
        return true;
       return dependent_type_p (TREE_TYPE (type));
     }
+  else if (TREE_CODE (type) == INTEGER_TYPE
+          && !TREE_CONSTANT (TYPE_MAX_VALUE (type)))
+    {
+      /* If this is the TYPE_DOMAIN of an array type, consider it
+        dependent.  */
+      return (value_dependent_expression_p (TYPE_MAX_VALUE (type))
+             || type_dependent_expression_p (TYPE_MAX_VALUE (type)));
+    }
 
   /* -- a template-id in which either the template name is a template
      parameter ...  */
@@ -14624,10 +15492,11 @@ dependent_type_p_r (tree type)
               (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
     return true;
 
-  /* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
-     expression is not type-dependent, then it should already been
-     have resolved.  */
-  if (TREE_CODE (type) == TYPEOF_TYPE)
+  /* All TYPEOF_TYPEs and DECLTYPE_TYPEs are dependent; if the
+     argument of the `typeof' expression is not type-dependent, then
+     it should already been have resolved.  */
+  if (TREE_CODE (type) == TYPEOF_TYPE
+      || TREE_CODE (type) == DECLTYPE_TYPE)
     return true;
 
   /* A template argument pack is dependent if any of its packed
@@ -14766,7 +15635,7 @@ value_dependent_expression_p (tree expression)
       /* A non-type template parm.  */
       if (DECL_TEMPLATE_PARM_P (expression))
        return true;
-      return false;
+      return value_dependent_expression_p (DECL_INITIAL (expression));
 
     case VAR_DECL:
        /* A constant with integral or enumeration type and is initialized
@@ -14804,12 +15673,7 @@ value_dependent_expression_p (tree expression)
          }
 
        if (TREE_CODE (expression) == TREE_LIST)
-         {
-           for (; expression; expression = TREE_CHAIN (expression))
-             if (value_dependent_expression_p (TREE_VALUE (expression)))
-               return true;
-           return false;
-         }
+         return any_value_dependent_elements_p (expression);
 
        return value_dependent_expression_p (expression);
       }
@@ -14852,6 +15716,17 @@ value_dependent_expression_p (tree expression)
         return false;
       }
 
+    case TRAIT_EXPR:
+      {
+       tree type2 = TRAIT_EXPR_TYPE2 (expression);
+       return (dependent_type_p (TRAIT_EXPR_TYPE1 (expression))
+               || (type2 ? dependent_type_p (type2) : false));
+      }
+
+    case MODOP_EXPR:
+      return ((value_dependent_expression_p (TREE_OPERAND (expression, 0)))
+             || (value_dependent_expression_p (TREE_OPERAND (expression, 2))));
+
     default:
       /* A constant expression is value-dependent if any subexpression is
         value-dependent.  */
@@ -14915,6 +15790,7 @@ type_dependent_expression_p (tree expression)
   if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
       || TREE_CODE (expression) == SIZEOF_EXPR
       || TREE_CODE (expression) == ALIGNOF_EXPR
+      || TREE_CODE (expression) == TRAIT_EXPR
       || TREE_CODE (expression) == TYPEID_EXPR
       || TREE_CODE (expression) == DELETE_EXPR
       || TREE_CODE (expression) == VEC_DELETE_EXPR
@@ -14965,6 +15841,9 @@ type_dependent_expression_p (tree expression)
       && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
     return false;
 
+  if (TREE_CODE (expression) == STMT_EXPR)
+    expression = stmt_expr_value_expr (expression);
+
   if (TREE_TYPE (expression) == unknown_type_node)
     {
       if (TREE_CODE (expression) == ADDR_EXPR)
@@ -15013,7 +15892,7 @@ type_dependent_expression_p (tree expression)
    contains a type-dependent expression.  */
 
 bool
-any_type_dependent_arguments_p (tree args)
+any_type_dependent_arguments_p (const_tree args)
 {
   while (args)
     {
@@ -15026,6 +15905,19 @@ any_type_dependent_arguments_p (tree args)
   return false;
 }
 
+/* Returns TRUE if LIST (a TREE_LIST whose TREE_VALUEs are
+   expressions) contains any value-dependent expressions.  */
+
+bool
+any_value_dependent_elements_p (const_tree list)
+{
+  for (; list; list = TREE_CHAIN (list))
+    if (value_dependent_expression_p (TREE_VALUE (list)))
+      return true;
+
+  return false;
+}
+
 /* Returns TRUE if the ARG (a template argument) is dependent.  */
 
 bool
@@ -15112,7 +16004,7 @@ any_template_arguments_need_structural_equality_p (tree args)
    any dependent arguments.  */
 
 bool
-any_dependent_template_arguments_p (tree args)
+any_dependent_template_arguments_p (const_tree args)
 {
   int i;
   int j;
@@ -15124,7 +16016,7 @@ any_dependent_template_arguments_p (tree args)
 
   for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
     {
-      tree level = TMPL_ARGS_LEVEL (args, i + 1);
+      const_tree level = TMPL_ARGS_LEVEL (args, i + 1);
       for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
        if (dependent_template_arg_p (TREE_VEC_ELT (level, j)))
          return true;
@@ -15173,11 +16065,12 @@ dependent_template_id_p (tree tmpl, tree args)
 }
 
 /* TYPE is a TYPENAME_TYPE.  Returns the ordinary TYPE to which the
-   TYPENAME_TYPE corresponds.  Returns ERROR_MARK_NODE if no such TYPE
-   can be found.  Note that this function peers inside uninstantiated
-   templates and therefore should be used only in extremely limited
-   situations.  ONLY_CURRENT_P restricts this peering to the currently
-   open classes hierarchy (which is required when comparing types).  */
+   TYPENAME_TYPE corresponds.  Returns the original TYPENAME_TYPE if
+   no such TYPE can be found.  Note that this function peers inside
+   uninstantiated templates and therefore should be used only in
+   extremely limited situations.  ONLY_CURRENT_P restricts this
+   peering to the currently open classes hierarchy (which is required
+   when comparing types).  */
 
 tree
 resolve_typename_type (tree type, bool only_current_p)
@@ -15187,6 +16080,7 @@ resolve_typename_type (tree type, bool only_current_p)
   tree decl;
   int quals;
   tree pushed_scope;
+  tree result;
 
   gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
 
@@ -15199,8 +16093,8 @@ resolve_typename_type (tree type, bool only_current_p)
     scope = resolve_typename_type (scope, only_current_p);
   /* If we don't know what SCOPE refers to, then we cannot resolve the
      TYPENAME_TYPE.  */
-  if (scope == error_mark_node || TREE_CODE (scope) == TYPENAME_TYPE)
-    return error_mark_node;
+  if (TREE_CODE (scope) == TYPENAME_TYPE)
+    return type;
   /* If the SCOPE is a template type parameter, we have no way of
      resolving the name.  */
   if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM)
@@ -15208,25 +16102,37 @@ resolve_typename_type (tree type, bool only_current_p)
   /* If the SCOPE is not the current instantiation, there's no reason
      to look inside it.  */
   if (only_current_p && !currently_open_class (scope))
-    return error_mark_node;
-  /* If SCOPE is a partial instantiation, it will not have a valid
-     TYPE_FIELDS list, so use the original template.  */
-  scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
+    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)))
+    /* scope is either the template itself or a compatible instantiation
+       like X<T>, so look up the name in the original template.  */
+    scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
+  else
+    /* scope is a partial instantiation, so we can't do the lookup or we
+       will lose the template arguments.  */
+    return type;
   /* Enter the SCOPE so that name lookup will be resolved as if we
      were in the class definition.  In particular, SCOPE will no
      longer be considered a dependent type.  */
   pushed_scope = push_scope (scope);
   /* Look up the declaration.  */
   decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true);
-  /* Obtain the set of qualifiers applied to the TYPE.  */
-  quals = cp_type_quals (type);
+
+  result = NULL_TREE;
+  
   /* For a TYPENAME_TYPE like "typename X::template Y<T>", we want to
      find a TEMPLATE_DECL.  Otherwise, we want to find a TYPE_DECL.  */
   if (!decl)
-    type = error_mark_node;
+    /*nop*/;
   else if (TREE_CODE (TYPENAME_TYPE_FULLNAME (type)) == IDENTIFIER_NODE
           && TREE_CODE (decl) == TYPE_DECL)
-    type = TREE_TYPE (decl);
+    {
+      result = TREE_TYPE (decl);
+      if (result == error_mark_node)
+       result = NULL_TREE;
+    }
   else if (TREE_CODE (TYPENAME_TYPE_FULLNAME (type)) == TEMPLATE_ID_EXPR
           && DECL_CLASS_TEMPLATE_P (decl))
     {
@@ -15236,19 +16142,37 @@ resolve_typename_type (tree type, bool only_current_p)
       tmpl = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 0);
       args = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 1);
       /* Instantiate the template.  */
-      type = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
-                                   /*entering_scope=*/0, tf_error | tf_user);
+      result = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
+                                     /*entering_scope=*/0,
+                                     tf_error | tf_user);
+      if (result == error_mark_node)
+       result = NULL_TREE;
     }
-  else
-    type = error_mark_node;
-  /* Qualify the resulting type.  */
-  if (type != error_mark_node && quals)
-    type = cp_build_qualified_type (type, quals);
+  
   /* Leave the SCOPE.  */
   if (pushed_scope)
     pop_scope (pushed_scope);
 
-  return type;
+  /* If we failed to resolve it, return the original typename.  */
+  if (!result)
+    return type;
+  
+  /* If lookup found a typename type, resolve that too.  */
+  if (TREE_CODE (result) == TYPENAME_TYPE && !TYPENAME_IS_RESOLVING_P (result))
+    {
+      /* Ill-formed programs can cause infinite recursion here, so we
+        must catch that.  */
+      TYPENAME_IS_RESOLVING_P (type) = 1;
+      result = resolve_typename_type (result, only_current_p);
+      TYPENAME_IS_RESOLVING_P (type) = 0;
+    }
+  
+  /* Qualify the resulting type.  */
+  quals = cp_type_quals (type);
+  if (quals)
+    result = cp_build_qualified_type (result, cp_type_quals (result) | quals);
+
+  return result;
 }
 
 /* EXPR is an expression which is not type-dependent.  Return a proxy
@@ -15267,6 +16191,8 @@ build_non_dependent_expr (tree expr)
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
   inner_expr = expr;
+  if (TREE_CODE (inner_expr) == STMT_EXPR)
+    inner_expr = stmt_expr_value_expr (inner_expr);
   if (TREE_CODE (inner_expr) == ADDR_EXPR)
     inner_expr = TREE_OPERAND (inner_expr, 0);
   if (TREE_CODE (inner_expr) == COMPONENT_REF)