OSDN Git Service

gcc/objc/
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index c0205a4..c609bd0 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;
 
@@ -80,6 +81,12 @@ static tree cur_stmt_expr;
    local variables.  */
 static htab_t local_specializations;
 
+/* Contains canonical template parameter types. The vector is indexed by
+   the TEMPLATE_TYPE_IDX of the template parameter. Each element is a
+   TREE_LIST, whose TREE_VALUEs contain the canonical template
+   parameters of various types and levels.  */
+static GTY(()) VEC(tree,gc) *canonical_template_parms;
+
 #define UNIFY_ALLOW_NONE 0
 #define UNIFY_ALLOW_MORE_CV_QUAL 1
 #define UNIFY_ALLOW_LESS_CV_QUAL 2
@@ -91,17 +98,15 @@ static htab_t local_specializations;
 
 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 classtype_mangled_name (tree);
-static char* mangle_class_name_for_template (const char *, tree, 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,
@@ -110,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);
@@ -119,13 +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);
@@ -134,6 +141,8 @@ static int can_complete_type_without_circularity (tree);
 static tree get_bindings (tree, tree, tree, bool);
 static int template_decl_level (tree);
 static int check_cv_quals_for_unify (int, tree, tree);
+static void template_parm_level_and_index (tree, int*, int*);
+static int unify_pack_expansion (tree, tree, tree, tree, int, bool, bool);
 static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
@@ -142,14 +151,14 @@ static tree most_specialized_class (tree, tree);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
 static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
-static void check_specialization_scope (void);
+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 *);
@@ -157,10 +166,13 @@ static tree copy_default_args_to_explicit_spec_1 (tree, tree);
 static void copy_default_args_to_explicit_spec (tree);
 static int invalid_nontype_parm_type_p (tree, tsubst_flags_t);
 static int eq_local_specializations (const void *, const void *);
+static bool dependent_template_arg_p (tree);
+static bool any_template_arguments_need_structural_equality_p (tree);
 static bool dependent_type_p_r (tree);
 static tree tsubst (tree, tree, tsubst_flags_t, tree);
-static tree tsubst_expr        (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_expr        (tree, tree, tsubst_flags_t, tree, bool);
 static tree tsubst_copy        (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
 
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
@@ -224,7 +236,9 @@ finish_member_template_decl (tree decl)
       tree type;
 
       type = TREE_TYPE (decl);
-      if (IS_AGGR_TYPE (type)
+      if (type == error_mark_node)
+       return error_mark_node;
+      if (MAYBE_CLASS_TYPE_P (type)
          && CLASSTYPE_TEMPLATE_INFO (type)
          && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
        {
@@ -252,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:
@@ -280,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)));
@@ -336,12 +360,11 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
               NULL);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
-      tree parm;
+      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
 
-      if (TREE_VEC_ELT (parms, i) == error_mark_node)
-        continue;
+      if (parm == error_mark_node)
+       continue;
 
-      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
@@ -361,7 +384,6 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
                                    TREE_TYPE (parm));
            DECL_ARTIFICIAL (decl) = 1;
            TREE_CONSTANT (decl) = 1;
-           TREE_INVARIANT (decl) = 1;
            TREE_READONLY (decl) = 1;
            DECL_INITIAL (decl) = DECL_INITIAL (parm);
            SET_DECL_TEMPLATE_PARM_P (decl);
@@ -509,6 +531,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.  */
 
@@ -536,9 +589,10 @@ begin_template_parm_list (void)
 }
 
 /* This routine is called when a specialization is declared.  If it is
-   invalid to declare a specialization here, an error is reported.  */
+   invalid to declare a specialization here, an error is reported and
+   false is returned, otherwise this routine will return true.  */
 
-static void
+static bool
 check_specialization_scope (void)
 {
   tree scope = current_scope ();
@@ -553,7 +607,10 @@ check_specialization_scope (void)
      shall be declared in the namespace of which the class template
      is a member.  */
   if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
-    error ("explicit specialization in non-namespace scope %qD", scope);
+    {
+      error ("explicit specialization in non-namespace scope %qD", scope);
+      return false;
+    }
 
   /* [temp.expl.spec]
 
@@ -564,17 +621,22 @@ check_specialization_scope (void)
      explicitly specialize a class member template if its enclosing
      class templates are not explicitly specialized as well.  */
   if (current_template_parms)
-    error ("enclosing class templates are not explicitly specialized");
+    {
+      error ("enclosing class templates are not explicitly specialized");
+      return false;
+    }
+
+  return true;
 }
 
 /* We've just seen template <>.  */
 
-void
+bool
 begin_specialization (void)
 {
   begin_scope (sk_template_spec, NULL);
   note_template_header (1);
-  check_specialization_scope ();
+  return check_specialization_scope ();
 }
 
 /* Called at then end of processing a declaration preceded by
@@ -648,8 +710,8 @@ check_specialization_namespace (tree tmpl)
     return true;
   else
     {
-      pedwarn ("specialization of %qD in different namespace", tmpl);
-      pedwarn ("  from definition of %q+#D", tmpl);
+      permerror ("specialization of %qD in different namespace", tmpl);
+      permerror ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
@@ -666,21 +728,28 @@ check_explicit_instantiation_namespace (tree spec)
      namespace of its template.  */
   ns = decl_namespace_context (spec);
   if (!is_ancestor (current_namespace, ns))
-    pedwarn ("explicit instantiation of %qD in namespace %qD "
-            "(which does not enclose namespace %qD)",
-            spec, current_namespace, ns);
+    permerror ("explicit instantiation of %qD in namespace %qD "
+              "(which does not enclose namespace %qD)",
+              spec, current_namespace, ns);
 }
 
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
-void
+tree
 maybe_process_partial_specialization (tree type)
 {
   tree context;
 
   if (type == error_mark_node)
-    return;
+    return error_mark_node;
+
+  if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+    {
+      error ("name of class shadows template template parameter %qD",
+            TYPE_NAME (type));
+      return error_mark_node;
+    }
 
   context = TYPE_CONTEXT (type);
 
@@ -703,7 +772,11 @@ maybe_process_partial_specialization (tree type)
          check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type));
          SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
          if (processing_template_decl)
-           push_template_decl (TYPE_MAIN_DECL (type));
+           {
+             if (push_template_decl (TYPE_MAIN_DECL (type))
+                 == error_mark_node)
+               return error_mark_node;
+           }
        }
       else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
        error ("specialization of %qT after instantiation", type);
@@ -738,9 +811,9 @@ maybe_process_partial_specialization (tree type)
          if (current_namespace
              != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
            {
-             pedwarn ("specializing %q#T in different namespace", type);
-             pedwarn ("  from definition of %q+#D",
-                      CLASSTYPE_TI_TEMPLATE (type));
+             permerror ("specializing %q#T in different namespace", type);
+             permerror ("  from definition of %q+#D",
+                        CLASSTYPE_TI_TEMPLATE (type));
            }
 
          /* Check for invalid specialization after instantiation:
@@ -765,7 +838,12 @@ maybe_process_partial_specialization (tree type)
        }
     }
   else if (processing_specialization)
-    error ("explicit specialization of non-template %qT", type);
+    {
+      error ("explicit specialization of non-template %qT", type);
+      return error_mark_node;
+    }
+
+  return type;
 }
 
 /* Returns nonzero if we can optimize the retrieval of specializations
@@ -816,6 +894,9 @@ static tree
 retrieve_specialization (tree tmpl, tree args,
                         bool class_specializations_p)
 {
+  if (args == error_mark_node)
+    return NULL_TREE;
+
   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
 
   /* There should be as many levels of arguments as there are
@@ -865,7 +946,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);
@@ -899,8 +981,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;
 }
 
@@ -935,10 +1022,10 @@ is_specialization_of (tree decl, tree tmpl)
 }
 
 /* Returns nonzero iff DECL is a specialization of friend declaration
-   FRIEND according to [temp.friend].  */
+   FRIEND_DECL according to [temp.friend].  */
 
 bool
-is_specialization_of_friend (tree decl, tree friend)
+is_specialization_of_friend (tree decl, tree friend_decl)
 {
   bool need_template = true;
   int template_depth;
@@ -946,26 +1033,26 @@ is_specialization_of_friend (tree decl, tree friend)
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
              || TREE_CODE (decl) == TYPE_DECL);
 
-  /* For [temp.friend/6] when FRIEND is an ordinary member function
+  /* For [temp.friend/6] when FRIEND_DECL is an ordinary member function
      of a template class, we want to check if DECL is a specialization
      if this.  */
-  if (TREE_CODE (friend) == FUNCTION_DECL
-      && DECL_TEMPLATE_INFO (friend)
-      && !DECL_USE_TEMPLATE (friend))
+  if (TREE_CODE (friend_decl) == FUNCTION_DECL
+      && DECL_TEMPLATE_INFO (friend_decl)
+      && !DECL_USE_TEMPLATE (friend_decl))
     {
       /* We want a TEMPLATE_DECL for `is_specialization_of'.  */
-      friend = DECL_TI_TEMPLATE (friend);
+      friend_decl = DECL_TI_TEMPLATE (friend_decl);
       need_template = false;
     }
-  else if (TREE_CODE (friend) == TEMPLATE_DECL
-          && !PRIMARY_TEMPLATE_P (friend))
+  else if (TREE_CODE (friend_decl) == TEMPLATE_DECL
+          && !PRIMARY_TEMPLATE_P (friend_decl))
     need_template = false;
 
   /* There is nothing to do if this is not a template friend.  */
-  if (TREE_CODE (friend) != TEMPLATE_DECL)
+  if (TREE_CODE (friend_decl) != TEMPLATE_DECL)
     return false;
 
-  if (is_specialization_of (decl, friend))
+  if (is_specialization_of (decl, friend_decl))
     return true;
 
   /* [temp.friend/6]
@@ -988,14 +1075,14 @@ is_specialization_of_friend (tree decl, tree friend)
      nonzero.  To determine if DECL is a friend of FRIEND, we first
      check if the enclosing class is a specialization of another.  */
 
-  template_depth = template_class_depth (DECL_CONTEXT (friend));
+  template_depth = template_class_depth (DECL_CONTEXT (friend_decl));
   if (template_depth
       && DECL_CLASS_SCOPE_P (decl)
       && is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)),
-                              CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend))))
+                              CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend_decl))))
     {
       /* Next, we check the members themselves.  In order to handle
-        a few tricky cases, such as when FRIEND's are
+        a few tricky cases, such as when FRIEND_DECL's are
 
           template <class T> friend void A<T>::g(T t);
           template <class T> template <T t> friend void A<T>::h();
@@ -1035,7 +1122,7 @@ is_specialization_of_friend (tree decl, tree friend)
          tree friend_args_type;
          tree decl_args_type;
 
-         /* Make sure that both DECL and FRIEND are templates or
+         /* Make sure that both DECL and FRIEND_DECL are templates or
             non-templates.  */
          is_template = DECL_TEMPLATE_INFO (decl)
                        && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl));
@@ -1045,7 +1132,7 @@ is_specialization_of_friend (tree decl, tree friend)
            {
              /* If both are templates, check template parameter list.  */
              tree friend_parms
-               = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend),
+               = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl),
                                         args, tf_none);
              if (!comp_template_parms
                     (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)),
@@ -1057,7 +1144,7 @@ is_specialization_of_friend (tree decl, tree friend)
          else
            decl_type = TREE_TYPE (decl);
 
-         friend_type = tsubst_function_type (TREE_TYPE (friend), args,
+         friend_type = tsubst_function_type (TREE_TYPE (friend_decl), args,
                                              tf_none, NULL_TREE);
          if (friend_type == error_mark_node)
            return false;
@@ -1070,7 +1157,7 @@ is_specialization_of_friend (tree decl, tree friend)
             `this' parameter.  */
          friend_args_type = TYPE_ARG_TYPES (friend_type);
          decl_args_type = TYPE_ARG_TYPES (decl_type);
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend))
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend_decl))
            friend_args_type = TREE_CHAIN (friend_args_type);
          if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
            decl_args_type = TREE_CHAIN (decl_args_type);
@@ -1083,7 +1170,7 @@ is_specialization_of_friend (tree decl, tree friend)
          bool is_template;
          tree decl_type = TREE_TYPE (decl);
 
-         /* Make sure that both DECL and FRIEND are templates or
+         /* Make sure that both DECL and FRIEND_DECL are templates or
             non-templates.  */
          is_template
            = CLASSTYPE_TEMPLATE_INFO (decl_type)
@@ -1097,12 +1184,12 @@ is_specialization_of_friend (tree decl, tree friend)
              /* If both are templates, check the name of the two
                 TEMPLATE_DECL's first because is_friend didn't.  */
              if (DECL_NAME (CLASSTYPE_TI_TEMPLATE (decl_type))
-                 != DECL_NAME (friend))
+                 != DECL_NAME (friend_decl))
                return false;
 
              /* Now check template parameter list.  */
              friend_parms
-               = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend),
+               = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl),
                                         args, tf_none);
              return comp_template_parms
                (DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (decl_type)),
@@ -1110,7 +1197,7 @@ is_specialization_of_friend (tree decl, tree friend)
            }
          else
            return (DECL_NAME (decl)
-                   == DECL_NAME (friend));
+                   == DECL_NAME (friend_decl));
        }
     }
   return false;
@@ -1161,7 +1248,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
            {
              error ("specialization of %qD after instantiation",
                     fn);
-             return spec;
+             return error_mark_node;
            }
          else
            {
@@ -1269,7 +1356,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.  */
@@ -1277,7 +1364,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
@@ -1293,6 +1380,17 @@ register_local_specialization (tree spec, tree tmpl)
   *slot = build_tree_list (spec, tmpl);
 }
 
+/* TYPE is a class type.  Returns true if TYPE is an explicitly
+   specialized class.  */
+
+bool
+explicit_class_specialization_p (tree type)
+{
+  if (!CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
+    return false;
+  return !uses_template_parms (CLASSTYPE_TI_ARGS (type));
+}
+
 /* Print the list of candidate FNS in an error message.  */
 
 void
@@ -1395,33 +1493,6 @@ determine_specialization (tree template_id,
          tree decl_arg_types;
          tree fn_arg_types;
 
-         /* DECL might be a specialization of FN.  */
-
-         /* Adjust the type of DECL in case FN is a static member.  */
-         decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
-         if (DECL_STATIC_FUNCTION_P (fn)
-             && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
-           decl_arg_types = TREE_CHAIN (decl_arg_types);
-
-         /* Check that the number of function parameters matches.
-            For example,
-              template <class T> void f(int i = 0);
-              template <> void f<int>();
-            The specialization f<int> is invalid but is not caught
-            by get_bindings below.  */
-
-         fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
-         if (list_length (fn_arg_types) != list_length (decl_arg_types))
-           continue;
-
-         /* For a non-static member function, we need to make sure that
-            the const qualification is the same. This can be done by
-            checking the 'this' in the argument list.  */
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
-             && !same_type_p (TREE_VALUE (fn_arg_types),
-                              TREE_VALUE (decl_arg_types)))
-           continue;
-
          /* In case of explicit specialization, we need to check if
             the number of template headers appearing in the specialization
             is correct. This is usually done in check_explicit_specialization,
@@ -1460,14 +1531,44 @@ determine_specialization (tree template_id,
                                      (current_template_parms))))
            continue;
 
+         /* DECL might be a specialization of FN.  */
+         decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
+         fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+
+         /* For a non-static member function, we need to make sure
+            that the const qualification is the same.  Since
+            get_bindings does not try to merge the "this" parameter,
+            we must do the comparison explicitly.  */
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+             && !same_type_p (TREE_VALUE (fn_arg_types),
+                              TREE_VALUE (decl_arg_types)))
+           continue;
+
+         /* Skip the "this" parameter and, for constructors of
+            classes with virtual bases, the VTT parameter.  A
+            full specialization of a constructor will have a VTT
+            parameter, but a template never will.  */ 
+         decl_arg_types 
+           = skip_artificial_parms_for (decl, decl_arg_types);
+         fn_arg_types 
+           = skip_artificial_parms_for (fn, fn_arg_types);
+
+         /* Check that the number of function parameters matches.
+            For example,
+              template <class T> void f(int i = 0);
+              template <> void f<int>();
+            The specialization f<int> is invalid but is not caught
+            by get_bindings below.  */
+         if (list_length (fn_arg_types) != list_length (decl_arg_types))
+           continue;
+
          /* Function templates cannot be specializations; there are
             no partial specializations of functions.  Therefore, if
             the type of DECL does not match FN, there is no
             match.  */
          if (tsk == tsk_template)
            {
-             if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
-                            decl_arg_types))
+             if (compparms (fn_arg_types, decl_arg_types))
                candidates = tree_cons (NULL_TREE, fn, candidates);
              continue;
            }
@@ -1567,7 +1668,7 @@ determine_specialization (tree template_id,
         This extension can only serve to make invalid programs valid,
         so it's safe.  And, there is strong anecdotal evidence that
         the committee intended the partial ordering rules to apply;
-        the EDG front-end has that behavior, and John Spicer claims
+        the EDG front end has that behavior, and John Spicer claims
         that the committee simply forgot to delete the wording in
         [temp.expl.spec].  */
       tree tmpl = most_specialized_instantiation (templates);
@@ -1905,7 +2006,7 @@ check_explicit_specialization (tree declarator,
       for (; t; t = TREE_CHAIN (t))
        if (TREE_PURPOSE (t))
          {
-           pedwarn
+           permerror
              ("default argument specified in explicit specialization");
            break;
          }
@@ -1934,7 +2035,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;
@@ -1995,7 +2096,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]:
@@ -2146,6 +2247,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:
@@ -2185,10 +2322,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;
@@ -2209,20 +2346,20 @@ comp_template_parms (tree parms1, tree parms2)
 
       for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
        {
-          tree parm1;
-          tree parm2;
-
-          if (TREE_VEC_ELT (t1, i) == error_mark_node
-              || TREE_VEC_ELT (t2, i) == error_mark_node)
-            continue;
+          tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+          tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
 
-         parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
-          parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+          /* If either of the template parameters are invalid, assume
+             they match for the sake of error recovery. */
+          if (parm1 == error_mark_node || parm2 == error_mark_node)
+            return 1;
 
          if (TREE_CODE (parm1) != TREE_CODE (parm2))
            return 0;
 
-         if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM)
+         if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM
+              && (TEMPLATE_TYPE_PARAMETER_PACK (parm1)
+                  == TEMPLATE_TYPE_PARAMETER_PACK (parm2)))
            continue;
          else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2)))
            return 0;
@@ -2237,131 +2374,609 @@ comp_template_parms (tree parms1, tree parms2)
   return 1;
 }
 
-/* Complain if DECL shadows a template parameter.
-
-   [temp.local]: A template-parameter shall not be redeclared within its
-   scope (including nested scopes).  */
-
-void
-check_template_shadow (tree decl)
+/* Determine whether PARM is a parameter pack.  */
+bool 
+template_parameter_pack_p (const_tree parm)
 {
-  tree olddecl;
+  /* Determine if we have a non-type template parameter pack.  */
+  if (TREE_CODE (parm) == PARM_DECL)
+    return (DECL_TEMPLATE_PARM_P (parm) 
+            && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)));
+
+  /* If this is a list of template parameters, we could get a
+     TYPE_DECL or a TEMPLATE_DECL.  */ 
+  if (TREE_CODE (parm) == TYPE_DECL || TREE_CODE (parm) == TEMPLATE_DECL)
+    parm = TREE_TYPE (parm);
+
+  return ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+          || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
+         && TEMPLATE_TYPE_PARAMETER_PACK (parm));
+}
 
-  /* If we're not in a template, we can't possibly shadow a template
-     parameter.  */
-  if (!current_template_parms)
-    return;
+/* Determine whether ARGS describes a variadic template args list,
+   i.e., one that is terminated by a template argument pack.  */
+static bool 
+template_args_variadic_p (tree args)
+{
+  int nargs;
+  tree last_parm;
 
-  /* Figure out what we're shadowing.  */
-  if (TREE_CODE (decl) == OVERLOAD)
-    decl = OVL_CURRENT (decl);
-  olddecl = innermost_non_namespace_value (DECL_NAME (decl));
+  if (args == NULL_TREE)
+    return false;
 
-  /* If there's no previous binding for this name, we're not shadowing
-     anything, let alone a template parameter.  */
-  if (!olddecl)
-    return;
+  args = INNERMOST_TEMPLATE_ARGS (args);
+  nargs = TREE_VEC_LENGTH (args);
 
-  /* If we're not shadowing a template parameter, we're done.  Note
-     that OLDDECL might be an OVERLOAD (or perhaps even an
-     ERROR_MARK), so we can't just blithely assume it to be a _DECL
-     node.  */
-  if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl))
-    return;
+  if (nargs == 0)
+    return false;
 
-  /* We check for decl != olddecl to avoid bogus errors for using a
-     name inside a class.  We check TPFI to avoid duplicate errors for
-     inline member templates.  */
-  if (decl == olddecl
-      || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
-    return;
+  last_parm = TREE_VEC_ELT (args, nargs - 1);
 
-  error ("declaration of %q+#D", decl);
-  error (" shadows template parm %q+#D", olddecl);
+  return ARGUMENT_PACK_P (last_parm);
 }
 
-/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
-   ORIG_LEVEL, DECL, and TYPE.  */
-
+/* Generate a new name for the parameter pack name NAME (an
+   IDENTIFIER_NODE) that incorporates its */
 static tree
-build_template_parm_index (int index,
-                          int level,
-                          int orig_level,
-                          tree decl,
-                          tree type)
+make_ith_pack_parameter_name (tree name, int i)
 {
-  tree t = make_node (TEMPLATE_PARM_INDEX);
-  TEMPLATE_PARM_IDX (t) = index;
-  TEMPLATE_PARM_LEVEL (t) = level;
-  TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
-  TEMPLATE_PARM_DECL (t) = decl;
-  TREE_TYPE (t) = type;
-  TREE_CONSTANT (t) = TREE_CONSTANT (decl);
-  TREE_INVARIANT (t) = TREE_INVARIANT (decl);
-  TREE_READONLY (t) = TREE_READONLY (decl);
-
-  return t;
+  /* Munge the name to include the parameter index.  */
+  char numbuf[128];
+  char* newname;
+  
+  sprintf(numbuf, "%i", i);
+  newname = (char*)alloca (IDENTIFIER_LENGTH (name) + strlen(numbuf) + 2);
+  sprintf(newname, "%s#%i", IDENTIFIER_POINTER (name), i);
+  return get_identifier (newname);
 }
 
-/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose
-   TEMPLATE_PARM_LEVEL has been decreased by LEVELS.  If such a
-   TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a
-   new one is created.  */
+/* 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;
+};
 
+/* 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
+   make_pack_expansion and uses_parameter_packs.  */
 static tree
-reduce_template_parm_level (tree index, tree type, int levels)
+find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
 {
-  if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
-      || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
-         != TEMPLATE_PARM_LEVEL (index) - levels))
+  tree t = *tp;
+  struct find_parameter_pack_data* ppd = 
+    (struct find_parameter_pack_data*)data;
+  bool parameter_pack_p = false;
+
+  /* Identify whether this is a parameter pack or not.  */
+  switch (TREE_CODE (t))
     {
-      tree orig_decl = TEMPLATE_PARM_DECL (index);
-      tree decl, t;
+    case TEMPLATE_PARM_INDEX:
+      if (TEMPLATE_PARM_PARAMETER_PACK (t))
+        parameter_pack_p = true;
+      break;
 
-      decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type);
-      TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl);
-      TREE_INVARIANT (decl) = TREE_INVARIANT (orig_decl);
-      TREE_READONLY (decl) = TREE_READONLY (orig_decl);
-      DECL_ARTIFICIAL (decl) = 1;
-      SET_DECL_TEMPLATE_PARM_P (decl);
+    case TEMPLATE_TYPE_PARM:
+    case TEMPLATE_TEMPLATE_PARM:
+      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+        parameter_pack_p = true;
+      break;
 
-      t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
-                                    TEMPLATE_PARM_LEVEL (index) - levels,
-                                    TEMPLATE_PARM_ORIG_LEVEL (index),
-                                    decl, type);
-      TEMPLATE_PARM_DESCENDANTS (index) = t;
+    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;
 
-       /* Template template parameters need this.  */
-      if (TREE_CODE (decl) != CONST_DECL)
-       DECL_TEMPLATE_PARMS (decl)
-         = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
+    default:
+      /* Not a parameter pack.  */
+      break;
     }
 
-  return TEMPLATE_PARM_DESCENDANTS (index);
-}
+  if (parameter_pack_p)
+    {
+      /* Add this parameter pack to the list.  */
+      *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
+    }
 
-/* Process information from new template parameter PARM and append it to the
-   LIST being built.  This new parameter is a non-type parameter iff
-   IS_NON_TYPE is true.  */
+  if (TYPE_P (t))
+    cp_walk_tree (&TYPE_CONTEXT (t), 
+                 &find_parameter_packs_r, ppd, ppd->visited);
 
-tree
-process_template_parm (tree list, tree parm, bool is_non_type)
-{
-  tree decl = 0;
-  tree defval;
-  int idx;
+  /* This switch statement will return immediately if we don't find a
+     parameter pack.  */
+  switch (TREE_CODE (t)) 
+    {
+    case TEMPLATE_PARM_INDEX:
+      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.  */
+      cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, 
+                   ppd->visited);
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
+    case TEMPLATE_TYPE_PARM:
+    case TEMPLATE_TEMPLATE_PARM:
+      return NULL_TREE;
+
+    case PARM_DECL:
+      return NULL_TREE;
+
+    case RECORD_TYPE:
+      if (TYPE_PTRMEMFUNC_P (t))
+       return NULL_TREE;
+      /* Fall through.  */
+
+    case UNION_TYPE:
+    case ENUMERAL_TYPE:
+      if (TYPE_TEMPLATE_INFO (t))
+       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:
+      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;
+    }
+
+  return NULL_TREE;
+}
+
+/* Determines if the expression or type T uses any parameter packs.  */
+bool
+uses_parameter_packs (tree t)
+{
+  tree parameter_packs = NULL_TREE;
+  struct find_parameter_pack_data ppd;
+  ppd.parameter_packs = &parameter_packs;
+  ppd.visited = pointer_set_create ();
+  cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
+  pointer_set_destroy (ppd.visited);
+  return parameter_packs != NULL_TREE;
+}
+
+/* Turn ARG, which may be an expression, type, or a TREE_LIST
+   representation a base-class initializer into a parameter pack
+   expansion. If all goes well, the resulting node will be an
+   EXPR_PACK_EXPANSION, TYPE_PACK_EXPANSION, or TREE_LIST,
+   respectively.  */
+tree 
+make_pack_expansion (tree arg)
+{
+  tree result;
+  tree parameter_packs = NULL_TREE;
+  bool for_types = false;
+  struct find_parameter_pack_data ppd;
+
+  if (!arg || arg == error_mark_node)
+    return arg;
+
+  if (TREE_CODE (arg) == TREE_LIST)
+    {
+      /* The only time we will see a TREE_LIST here is for a base
+         class initializer.  In this case, the TREE_PURPOSE will be a
+         _TYPE node (representing the base class expansion we're
+         initializing) and the TREE_VALUE will be a TREE_LIST
+         containing the initialization arguments. 
+
+         The resulting expansion looks somewhat different from most
+         expansions. Rather than returning just one _EXPANSION, we
+         return a TREE_LIST whose TREE_PURPOSE is a
+         TYPE_PACK_EXPANSION containing the bases that will be
+         initialized.  The TREE_VALUE will be identical to the
+         original TREE_VALUE, which is a list of arguments that will
+         be passed to each base.  We do not introduce any new pack
+         expansion nodes into the TREE_VALUE (although it is possible
+         that some already exist), because the TREE_PURPOSE and
+         TREE_VALUE all need to be expanded together with the same
+         _EXPANSION node.  Note that the TYPE_PACK_EXPANSION in the
+         resulting TREE_PURPOSE will mention the parameter packs in
+         both the bases and the arguments to the bases.  */
+      tree purpose;
+      tree value;
+      tree parameter_packs = NULL_TREE;
+
+      /* Determine which parameter packs will be used by the base
+         class expansion.  */
+      ppd.visited = pointer_set_create ();
+      ppd.parameter_packs = &parameter_packs;
+      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;
+        }
+
+      if (TREE_VALUE (arg) != void_type_node)
+        {
+          /* Collect the sets of parameter packs used in each of the
+             initialization arguments.  */
+          for (value = TREE_VALUE (arg); value; value = TREE_CHAIN (value))
+            {
+              /* Determine which parameter packs will be expanded in this
+                 argument.  */
+              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));
+      PACK_EXPANSION_PARAMETER_PACKS (purpose) = parameter_packs;
+
+      /* Just use structural equality for these TYPE_PACK_EXPANSIONS;
+        they will rarely be compared to anything.  */
+      SET_TYPE_STRUCTURAL_EQUALITY (purpose);
+
+      return tree_cons (purpose, TREE_VALUE (arg), NULL_TREE);
+    }
+
+  if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
+    for_types = true;
+
+  /* Build the PACK_EXPANSION_* node.  */
+  result = make_node (for_types ? TYPE_PACK_EXPANSION : EXPR_PACK_EXPANSION);
+  SET_PACK_EXPANSION_PATTERN (result, arg);
+  if (TREE_CODE (result) == EXPR_PACK_EXPANSION)
+    {
+      /* Propagate type and const-expression information.  */
+      TREE_TYPE (result) = TREE_TYPE (arg);
+      TREE_CONSTANT (result) = TREE_CONSTANT (arg);
+    }
+  else
+    /* Just use structural equality for these TYPE_PACK_EXPANSIONS;
+       they will rarely be compared to anything.  */
+    SET_TYPE_STRUCTURAL_EQUALITY (result);
+
+  /* Determine which parameter packs will be expanded.  */
+  ppd.parameter_packs = &parameter_packs;
+  ppd.visited = pointer_set_create ();
+  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)
+    {
+      if (TYPE_P (arg))
+        error ("expansion pattern %<%T%> contains no argument packs", arg);
+      else
+        error ("expansion pattern %<%E%> contains no argument packs", arg);
+      return error_mark_node;
+    }
+  PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
+
+  return result;
+}
+
+/* Checks T for any "bare" parameter packs, which have not yet been
+   expanded, and issues an error if any are found. This operation can
+   only be done on full expressions or types (e.g., an expression
+   statement, "if" condition, etc.), because we could have expressions like:
+
+     foo(f(g(h(args)))...)
+
+   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. 
+
+   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 false;
+
+  if (TREE_CODE (t) == TYPE_DECL)
+    t = TREE_TYPE (t);
+
+  ppd.parameter_packs = &parameter_packs;
+  ppd.visited = pointer_set_create ();
+  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 (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 (name)
+           inform ("        %qD", name);
+         else
+           inform ("        <anonymous>");
+
+          parameter_packs = TREE_CHAIN (parameter_packs);
+        }
+
+      return true;
+    }
+
+  return false;
+}
+
+/* Expand any parameter packs that occur in the template arguments in
+   ARGS.  */
+tree
+expand_template_argument_pack (tree args)
+{
+  tree result_args = NULL_TREE;
+  int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
+  int num_result_args = -1;
+
+  /* First, determine if we need to expand anything, and the number of
+     slots we'll need.  */
+  for (in_arg = 0; in_arg < nargs; ++in_arg)
+    {
+      tree arg = TREE_VEC_ELT (args, in_arg);
+      if (ARGUMENT_PACK_P (arg))
+        {
+          int num_packed = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg));
+          if (num_result_args < 0)
+            num_result_args = in_arg + num_packed;
+          else
+            num_result_args += num_packed;
+        }
+      else
+        {
+          if (num_result_args >= 0)
+            num_result_args++;
+        }
+    }
+
+  /* If no expansion is necessary, we're done.  */
+  if (num_result_args < 0)
+    return args;
+
+  /* Expand arguments.  */
+  result_args = make_tree_vec (num_result_args);
+  for (in_arg = 0; in_arg < nargs; ++in_arg)
+    {
+      tree arg = TREE_VEC_ELT (args, in_arg);
+      if (ARGUMENT_PACK_P (arg))
+        {
+          tree packed = ARGUMENT_PACK_ARGS (arg);
+          int i, num_packed = TREE_VEC_LENGTH (packed);
+          for (i = 0; i < num_packed; ++i, ++out_arg)
+            TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
+        }
+      else
+        {
+          TREE_VEC_ELT (result_args, out_arg) = arg;
+          ++out_arg;
+        }
+    }
+
+  return result_args;
+}
+
+/* Complain if DECL shadows a template parameter.
+
+   [temp.local]: A template-parameter shall not be redeclared within its
+   scope (including nested scopes).  */
+
+void
+check_template_shadow (tree decl)
+{
+  tree olddecl;
+
+  /* If we're not in a template, we can't possibly shadow a template
+     parameter.  */
+  if (!current_template_parms)
+    return;
+
+  /* Figure out what we're shadowing.  */
+  if (TREE_CODE (decl) == OVERLOAD)
+    decl = OVL_CURRENT (decl);
+  olddecl = innermost_non_namespace_value (DECL_NAME (decl));
+
+  /* If there's no previous binding for this name, we're not shadowing
+     anything, let alone a template parameter.  */
+  if (!olddecl)
+    return;
+
+  /* If we're not shadowing a template parameter, we're done.  Note
+     that OLDDECL might be an OVERLOAD (or perhaps even an
+     ERROR_MARK), so we can't just blithely assume it to be a _DECL
+     node.  */
+  if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl))
+    return;
+
+  /* We check for decl != olddecl to avoid bogus errors for using a
+     name inside a class.  We check TPFI to avoid duplicate errors for
+     inline member templates.  */
+  if (decl == olddecl
+      || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
+    return;
+
+  error ("declaration of %q+#D", decl);
+  error (" shadows template parm %q+#D", olddecl);
+}
+
+/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
+   ORIG_LEVEL, DECL, and TYPE.  */
+
+static tree
+build_template_parm_index (int index,
+                          int level,
+                          int orig_level,
+                          tree decl,
+                          tree type)
+{
+  tree t = make_node (TEMPLATE_PARM_INDEX);
+  TEMPLATE_PARM_IDX (t) = index;
+  TEMPLATE_PARM_LEVEL (t) = level;
+  TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
+  TEMPLATE_PARM_DECL (t) = decl;
+  TREE_TYPE (t) = type;
+  TREE_CONSTANT (t) = TREE_CONSTANT (decl);
+  TREE_READONLY (t) = TREE_READONLY (decl);
+
+  return t;
+}
+
+/* Find the canonical type parameter for the given template type
+   parameter.  Returns the canonical type parameter, which may be TYPE
+   if no such parameter existed.  */
+static tree
+canonical_type_parameter (tree type)
+{
+  tree list;
+  int idx = TEMPLATE_TYPE_IDX (type);
+  if (!canonical_template_parms)
+    canonical_template_parms = VEC_alloc (tree, gc, idx+1);
+
+  while (VEC_length (tree, canonical_template_parms) <= (unsigned)idx)
+    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))
+    list = TREE_CHAIN (list);
+
+  if (list)
+    return TREE_VALUE (list);
+  else
+    {
+      VEC_replace(tree, canonical_template_parms, idx,
+                 tree_cons (NULL_TREE, type, 
+                            VEC_index (tree, canonical_template_parms, idx)));
+      return type;
+    }
+}
+
+/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose
+   TEMPLATE_PARM_LEVEL has been decreased by LEVELS.  If such a
+   TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a
+   new one is created.  */
+
+static tree
+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))
+         != TEMPLATE_PARM_LEVEL (index) - levels))
+    {
+      tree orig_decl = TEMPLATE_PARM_DECL (index);
+      tree decl, t;
+
+      decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type);
+      TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl);
+      TREE_READONLY (decl) = TREE_READONLY (orig_decl);
+      DECL_ARTIFICIAL (decl) = 1;
+      SET_DECL_TEMPLATE_PARM_P (decl);
+
+      t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
+                                    TEMPLATE_PARM_LEVEL (index) - levels,
+                                    TEMPLATE_PARM_ORIG_LEVEL (index),
+                                    decl, type);
+      TEMPLATE_PARM_DESCENDANTS (index) = t;
+      TEMPLATE_PARM_PARAMETER_PACK (t) 
+       = TEMPLATE_PARM_PARAMETER_PACK (index);
+
+       /* Template template parameters need this.  */
+      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);
+}
+
+/* Process information from new template parameter PARM and append it to the
+   LIST being built.  This new parameter is a non-type parameter iff
+   IS_NON_TYPE is true. This new parameter is a parameter
+   pack iff IS_PARAMETER_PACK is true.  */
+
+tree
+process_template_parm (tree list, tree parm, bool is_non_type, 
+                       bool is_parameter_pack)
+{
+  tree decl = 0;
+  tree defval;
+  tree err_parm_list;
+  int idx = 0;
 
   gcc_assert (TREE_CODE (parm) == TREE_LIST);
   defval = TREE_PURPOSE (parm);
 
   if (list)
     {
-      tree p = TREE_VALUE (tree_last (list));
+      tree p = tree_last (list);
+
+      if (p && TREE_VALUE (p) != error_mark_node)
+        {
+          p = TREE_VALUE (p);
+          if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
+            idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
+          else
+            idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
+        }
 
-      if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
-       idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
-      else
-       idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
       ++idx;
     }
   else
@@ -2374,7 +2989,11 @@ process_template_parm (tree list, tree parm, bool is_non_type)
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       if (TREE_TYPE (parm) == error_mark_node)
-       return chainon(list, error_mark_node);
+        {
+          err_parm_list = build_tree_list (defval, parm);
+          TREE_VALUE (err_parm_list) = error_mark_node;
+          return chainon (list, err_parm_list);
+        }
       else
       {
        /* [temp.param]
@@ -2383,21 +3002,36 @@ process_template_parm (tree list, tree parm, bool is_non_type)
           ignored when determining its type.  */
        TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
        if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-         return chainon(list, error_mark_node);
+          {
+            err_parm_list = build_tree_list (defval, parm);
+            TREE_VALUE (err_parm_list) = error_mark_node;
+            return chainon (list, err_parm_list);
+          }
+
+        if (uses_parameter_packs (TREE_TYPE (parm)) && !is_parameter_pack)
+         {
+           /* This template parameter is not a parameter pack, but it
+              should be. Complain about "bare" parameter packs.  */
+           check_for_bare_parameter_packs (TREE_TYPE (parm));
+           
+           /* Recover by calling this a parameter pack.  */
+           is_parameter_pack = true;
+         }
       }
 
       /* A template parameter is not modifiable.  */
       TREE_CONSTANT (parm) = 1;
-      TREE_INVARIANT (parm) = 1;
       TREE_READONLY (parm) = 1;
       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
       TREE_CONSTANT (decl) = 1;
-      TREE_INVARIANT (decl) = 1;
       TREE_READONLY (decl) = 1;
       DECL_INITIAL (parm) = DECL_INITIAL (decl)
        = build_template_parm_index (idx, processing_template_decl,
                                     processing_template_decl,
                                     decl, TREE_TYPE (parm));
+
+      TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)) 
+       = is_parameter_pack;
     }
   else
     {
@@ -2406,7 +3040,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
 
       if (parm && TREE_CODE (parm) == TEMPLATE_DECL)
        {
-         t = make_aggr_type (TEMPLATE_TEMPLATE_PARM);
+         t = cxx_make_type (TEMPLATE_TEMPLATE_PARM);
          /* This is for distinguishing between real templates and template
             template parameters */
          TREE_TYPE (parm) = t;
@@ -2415,7 +3049,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
        }
       else
        {
-         t = make_aggr_type (TEMPLATE_TYPE_PARM);
+         t = cxx_make_type (TEMPLATE_TYPE_PARM);
          /* parm is either IDENTIFIER_NODE or NULL_TREE.  */
          decl = build_decl (TYPE_DECL, parm, t);
        }
@@ -2427,6 +3061,8 @@ process_template_parm (tree list, tree parm, bool is_non_type)
        = build_template_parm_index (idx, processing_template_decl,
                                     processing_template_decl,
                                     decl, TREE_TYPE (parm));
+      TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack;
+      TYPE_CANONICAL (t) = canonical_type_parameter (t);
     }
   DECL_ARTIFICIAL (decl) = 1;
   SET_DECL_TEMPLATE_PARM_P (decl);
@@ -2480,8 +3116,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)
@@ -2514,12 +3152,43 @@ current_template_args (void)
            {
              t = TREE_VALUE (t);
 
-             if (TREE_CODE (t) == TYPE_DECL
-                 || TREE_CODE (t) == TEMPLATE_DECL)
-               t = TREE_TYPE (t);
-             else
-               t = DECL_INITIAL (t);
-             TREE_VEC_ELT (a, i) = t;
+             if (!error_operand_p (t))
+               {
+                 if (TREE_CODE (t) == TYPE_DECL
+                     || TREE_CODE (t) == TEMPLATE_DECL)
+                    {
+                      t = TREE_TYPE (t);
+                      
+                      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+                        {
+                          /* Turn this argument into a TYPE_ARGUMENT_PACK
+                             with a single element, which expands T.  */
+                          tree vec = make_tree_vec (1);
+                          TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
+                          
+                          t = make_node (TYPE_ARGUMENT_PACK);
+                          SET_ARGUMENT_PACK_ARGS (t, vec);
+                        }
+                    }
+                  else
+                    {
+                      t = DECL_INITIAL (t);
+                      
+                      if (TEMPLATE_PARM_PARAMETER_PACK (t))
+                        {
+                          /* Turn this argument into a NONTYPE_ARGUMENT_PACK
+                             with a single element, which expands T.  */
+                          tree vec = make_tree_vec (1);
+                          tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
+                          TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
+                          
+                          t  = make_node (NONTYPE_ARGUMENT_PACK);
+                          SET_ARGUMENT_PACK_ARGS (t, vec);
+                          TREE_TYPE (t) = type;
+                        }
+                    }
+                 TREE_VEC_ELT (a, i) = t;
+                }
            }
        }
 
@@ -2674,7 +3343,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)
@@ -2708,74 +3378,118 @@ process_partial_specialization (tree decl)
 
      The type of a template parameter corresponding to a specialized
      non-type argument shall not be dependent on a parameter of the
-     specialization.  */
+     specialization. 
+
+     Also, we verify that pack expansions only occur at the
+     end of the argument list.  */
   gcc_assert (nargs == DECL_NTPARMS (maintmpl));
   tpd2.parms = 0;
   for (i = 0; i < nargs; ++i)
     {
+      tree parm = TREE_VALUE (TREE_VEC_ELT (main_inner_parms, i));
       tree arg = TREE_VEC_ELT (inner_args, i);
-      if (/* These first two lines are the `non-type' bit.  */
-         !TYPE_P (arg)
-         && TREE_CODE (arg) != TEMPLATE_DECL
-         /* This next line is the `argument expression is not just a
-            simple identifier' condition and also the `specialized
-            non-type argument' bit.  */
-         && TREE_CODE (arg) != TEMPLATE_PARM_INDEX)
-       {
-         if (tpd.arg_uses_template_parms[i])
-           error ("template argument %qE involves template parameter(s)", arg);
-         else
-           {
-             /* Look at the corresponding template parameter,
-                marking which template parameters its type depends
-                upon.  */
-             tree type =
-               TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (main_inner_parms,
-                                                    i)));
-
-             if (!tpd2.parms)
-               {
-                 /* We haven't yet initialized TPD2.  Do so now.  */
-                 tpd2.arg_uses_template_parms
-                   = (int *) alloca (sizeof (int) * nargs);
-                 /* The number of parameters here is the number in the
-                    main template, which, as checked in the assertion
-                    above, is NARGS.  */
-                 tpd2.parms = (int *) alloca (sizeof (int) * nargs);
-                 tpd2.level =
-                   TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
-               }
+      tree packed_args = NULL_TREE;
+      int j, len = 1;
 
-             /* Mark the template parameters.  But this time, we're
-                looking for the template parameters of the main
-                template, not in the specialization.  */
-             tpd2.current_arg = i;
-             tpd2.arg_uses_template_parms[i] = 0;
-             memset (tpd2.parms, 0, sizeof (int) * nargs);
-             for_each_template_parm (type,
-                                     &mark_template_parm,
-                                     &tpd2,
-                                     NULL);
-
-             if (tpd2.arg_uses_template_parms [i])
-               {
-                 /* The type depended on some template parameters.
-                    If they are fully specialized in the
-                    specialization, that's OK.  */
-                 int j;
-                 for (j = 0; j < nargs; ++j)
-                   if (tpd2.parms[j] != 0
-                       && tpd.arg_uses_template_parms [j])
-                     {
-                       error ("type %qT of template argument %qE depends "
-                              "on template parameter(s)",
-                              type,
-                              arg);
-                       break;
-                     }
-               }
-           }
-       }
+      if (ARGUMENT_PACK_P (arg))
+        {
+          /* Extract the arguments from the argument pack. We'll be
+             iterating over these in the following loop.  */
+          packed_args = ARGUMENT_PACK_ARGS (arg);
+          len = TREE_VEC_LENGTH (packed_args);
+        }
+
+      for (j = 0; j < len; j++)
+        {
+          if (packed_args)
+            /* Get the Jth argument in the parameter pack.  */
+            arg = TREE_VEC_ELT (packed_args, j);
+
+          if (PACK_EXPANSION_P (arg))
+            {
+              /* Pack expansions must come at the end of the
+                 argument list.  */
+              if ((packed_args && j < len - 1)
+                  || (!packed_args && i < nargs - 1))
+                {
+                  if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
+                    error ("parameter pack argument %qE must be at the end of the template argument list", arg);
+                  else
+                    error ("parameter pack argument %qT must be at the end of the template argument list", arg);
+
+                 if (packed_args)
+                   TREE_VEC_ELT (packed_args, j) = error_mark_node;
+                }
+            }
+
+          if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
+            /* We only care about the pattern.  */
+            arg = PACK_EXPANSION_PATTERN (arg);
+
+          if (/* These first two lines are the `non-type' bit.  */
+              !TYPE_P (arg)
+              && TREE_CODE (arg) != TEMPLATE_DECL
+              /* This next line is the `argument expression is not just a
+                 simple identifier' condition and also the `specialized
+                 non-type argument' bit.  */
+              && TREE_CODE (arg) != TEMPLATE_PARM_INDEX)
+            {
+              if ((!packed_args && tpd.arg_uses_template_parms[i])
+                  || (packed_args && uses_template_parms (arg)))
+                error ("template argument %qE involves template parameter(s)",
+                       arg);
+              else 
+                {
+                  /* Look at the corresponding template parameter,
+                     marking which template parameters its type depends
+                     upon.  */
+                  tree type = TREE_TYPE (parm);
+
+                  if (!tpd2.parms)
+                    {
+                      /* We haven't yet initialized TPD2.  Do so now.  */
+                      tpd2.arg_uses_template_parms 
+                        = (int *) alloca (sizeof (int) * nargs);
+                      /* The number of parameters here is the number in the
+                         main template, which, as checked in the assertion
+                         above, is NARGS.  */
+                      tpd2.parms = (int *) alloca (sizeof (int) * nargs);
+                      tpd2.level = 
+                        TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
+                    }
+
+                  /* Mark the template parameters.  But this time, we're
+                     looking for the template parameters of the main
+                     template, not in the specialization.  */
+                  tpd2.current_arg = i;
+                  tpd2.arg_uses_template_parms[i] = 0;
+                  memset (tpd2.parms, 0, sizeof (int) * nargs);
+                  for_each_template_parm (type,
+                                          &mark_template_parm,
+                                          &tpd2,
+                                          NULL,
+                                         /*include_nondeduced_p=*/false);
+
+                  if (tpd2.arg_uses_template_parms [i])
+                    {
+                      /* The type depended on some template parameters.
+                         If they are fully specialized in the
+                         specialization, that's OK.  */
+                      int j;
+                      for (j = 0; j < nargs; ++j)
+                        if (tpd2.parms[j] != 0
+                            && tpd.arg_uses_template_parms [j])
+                          {
+                            error ("type %qT of template argument %qE depends "
+                                   "on template parameter(s)", 
+                                   type,
+                                   arg);
+                            break;
+                          }
+                    }
+                }
+            }
+        }
     }
 
   if (retrieve_specialization (maintmpl, specargs,
@@ -2785,22 +3499,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]
 
@@ -2813,7 +3538,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)
@@ -2833,40 +3558,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;
+
+          for (i = 0; i < ntparms; ++i)
+            {
+              tree parm = TREE_VEC_ELT (inner_parms, i);
+
+              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 (parm == error_mark_node)
-            continue;
+                 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)));
 
-         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;
-           }
-       }
+                 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>
@@ -2877,8 +3634,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
@@ -2887,7 +3644,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";
@@ -2926,6 +3687,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;
                }
@@ -2941,6 +3706,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
@@ -3014,7 +3781,13 @@ push_template_decl_real (tree decl, bool is_friend)
     DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
 
   /* See if this is a primary template.  */
-  primary = template_parm_scope_p ();
+  if (is_friend && ctx)
+    /* A friend template that specifies a class context, i.e.
+         template <typename T> friend void A<T>::f();
+       is not primary.  */
+    primary = 0;
+  else
+    primary = template_parm_scope_p ();
 
   if (primary)
     {
@@ -3022,7 +3795,10 @@ push_template_decl_real (tree decl, bool is_friend)
        member_template_p = true;
       if (TREE_CODE (decl) == TYPE_DECL
          && ANON_AGGRNAME_P (DECL_NAME (decl)))
-       error ("template class without a name");
+       {
+         error ("template class without a name");
+         return error_mark_node;
+       }
       else if (TREE_CODE (decl) == FUNCTION_DECL)
        {
          if (DECL_DESTRUCTOR_P (decl))
@@ -3062,7 +3838,50 @@ 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.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      /* 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)
+        {
+          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;
+            }
+
+          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);
@@ -3111,31 +3930,19 @@ push_template_decl_real (tree decl, bool is_friend)
            }
        }
     }
-  else
-    {
-      tree a, t, current, parms;
-      int i;
-
-      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))
+  else
+    {
+      tree a, t, current, parms;
+      int i;
+      tree tinfo = get_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)
@@ -3195,14 +4002,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;
@@ -3229,10 +4051,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.  */
@@ -3241,6 +4066,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
@@ -3253,14 +4088,7 @@ push_template_decl_real (tree decl, bool is_friend)
   info = tree_cons (tmpl, args, NULL_TREE);
 
   if (DECL_IMPLICIT_TYPEDEF_P (decl))
-    {
-      SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info);
-      if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL)
-         && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
-         /* Don't change the name if we've already set it up.  */
-         && !IDENTIFIER_TEMPLATE (DECL_NAME (decl)))
-       DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl));
-    }
+    SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info);
   else if (DECL_LANG_SPECIFIC (decl))
     DECL_TEMPLATE_INFO (decl) = info;
 
@@ -3279,7 +4107,7 @@ push_template_decl (tree decl)
      template <class T> struct S;
      template <class T> struct S {};  */
 
-void
+bool
 redeclare_class_template (tree type, tree parms)
 {
   tree tmpl;
@@ -3289,7 +4117,7 @@ redeclare_class_template (tree type, tree parms)
   if (!TYPE_TEMPLATE_INFO (type))
     {
       error ("%qT is not a template type", type);
-      return;
+      return false;
     }
 
   tmpl = TYPE_TI_TEMPLATE (type);
@@ -3297,13 +4125,13 @@ redeclare_class_template (tree type, tree parms)
     /* The type is nested in some template class.  Nothing to worry
        about here; there are no new template parameters for the nested
        type.  */
-    return;
+    return true;
 
   if (!parms)
     {
       error ("template specifiers not specified in declaration of %qD",
             tmpl);
-      return;
+      return false;
     }
 
   parms = INNERMOST_TEMPLATE_PARMS (parms);
@@ -3311,29 +4139,45 @@ 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));
-      return;
+      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;
     }
 
   for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
     {
-      tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
-      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
-      tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
+      tree tmpl_parm;
+      tree parm;
+      tree tmpl_default;
+      tree parm_default;
+
+      if (TREE_VEC_ELT (tmpl_parms, i) == error_mark_node
+          || TREE_VEC_ELT (parms, i) == error_mark_node)
+        continue;
+
+      tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
+      parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
 
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
         TEMPLATE_DECL.  */
-      if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-         || (TREE_CODE (tmpl_parm) != TYPE_DECL
-             && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
+      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) != 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);
-         return;
+         return false;
        }
 
       if (tmpl_default != NULL_TREE && parm_default != NULL_TREE)
@@ -3343,8 +4187,8 @@ 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);
-         return;
+         inform ("%Joriginal definition appeared here", tmpl_parm);
+         return false;
        }
 
       if (parm_default != NULL_TREE)
@@ -3356,6 +4200,8 @@ redeclare_class_template (tree type, tree parms)
           parameters for any members.  */
        TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default;
     }
+
+    return true;
 }
 
 /* Simplify EXPR if it is a non-dependent expression.  Returns the
@@ -3364,6 +4210,9 @@ redeclare_class_template (tree type, tree parms)
 tree
 fold_non_dependent_expr (tree expr)
 {
+  if (expr == NULL_TREE)
+    return NULL_TREE;
+
   /* If we're in a template, but EXPR isn't value dependent, simplify
      it.  We're supposed to treat:
 
@@ -3383,7 +4232,8 @@ fold_non_dependent_expr (tree expr)
                                    /*args=*/NULL_TREE,
                                    tf_error,
                                    /*in_decl=*/NULL_TREE,
-                                   /*function_p=*/false);
+                                   /*function_p=*/false,
+                                   /*integral_constant_expression_p=*/true);
       processing_template_decl = saved_processing_template_decl;
     }
   return expr;
@@ -3391,7 +4241,7 @@ fold_non_dependent_expr (tree expr)
 
 /* EXPR is an expression which is used in a constant-expression context.
    For instance, it could be a VAR_DECL with a constant initializer.
-   Extract the innest constant expression.
+   Extract the innermost constant expression.
 
    This is basically a more powerful version of
    integral_constant_value, which can be used also in templates where
@@ -3430,7 +4280,9 @@ convert_nontype_argument_function (tree type, tree expr)
   fn_no_ptr = fn;
   if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
     fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
-
+  if (TREE_CODE (fn_no_ptr) == BASELINK)
+    fn_no_ptr = BASELINK_FUNCTIONS (fn_no_ptr);
   /* [temp.arg.nontype]/1
 
      A template-argument for a non-type, non-template template-parameter
@@ -3592,10 +4444,46 @@ convert_nontype_argument (tree type, tree expr)
 
        Here, we do not care about functions, as they are invalid anyway
        for a parameter of type pointer-to-object.  */
-      bool constant_address_p =
-       (TREE_CODE (expr) == ADDR_EXPR
-        || TREE_CODE (expr_type) == ARRAY_TYPE
-        || (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr)));
+
+      if (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr))
+       /* Non-type template parameters are OK.  */
+       ;
+      else if (TREE_CODE (expr) != ADDR_EXPR
+              && TREE_CODE (expr_type) != ARRAY_TYPE)
+       {
+         if (TREE_CODE (expr) == VAR_DECL)
+           {
+             error ("%qD is not a valid template argument "
+                    "because %qD is a variable, not the address of "
+                    "a variable",
+                    expr, expr);
+             return NULL_TREE;
+           }
+         /* Other values, like integer constants, might be valid
+            non-type arguments of some other type.  */
+         return error_mark_node;
+       }
+      else
+       {
+         tree decl;
+
+         decl = ((TREE_CODE (expr) == ADDR_EXPR)
+                 ? TREE_OPERAND (expr, 0) : expr);
+         if (TREE_CODE (decl) != VAR_DECL)
+           {
+             error ("%qE is not a valid template argument of type %qT "
+                    "because %qE is not a variable",
+                    expr, type, decl);
+             return NULL_TREE;
+           }
+         else if (!DECL_EXTERNAL_LINKAGE_P (decl))
+           {
+             error ("%qE is not a valid template argument of type %qT "
+                    "because %qD does not have external linkage",
+                    expr, type, decl);
+             return NULL_TREE;
+           }
+       }
 
       expr = decay_conversion (expr);
       if (expr == error_mark_node)
@@ -3604,13 +4492,6 @@ convert_nontype_argument (tree type, tree expr)
       expr = perform_qualification_conversions (type, expr);
       if (expr == error_mark_node)
        return error_mark_node;
-
-      if (!constant_address_p)
-       {
-         error ("%qE is not a valid template argument for type %qT "
-                "because it is not a constant pointer", expr, type);
-         return NULL_TREE;
-       }
     }
   /* [temp.arg.nontype]/5, bullet 3
 
@@ -3751,6 +4632,77 @@ convert_nontype_argument (tree type, tree expr)
   return expr;
 }
 
+/* Subroutine of coerce_template_template_parms, which returns 1 if
+   PARM_PARM and ARG_PARM match using the rule for the template
+   parameters of template template parameters. Both PARM and ARG are
+   template parameters; the rest of the arguments are the same as for
+   coerce_template_template_parms.
+ */
+static int
+coerce_template_template_parm (tree parm,
+                              tree arg,
+                              tsubst_flags_t complain,
+                              tree in_decl,
+                              tree outer_args)
+{
+  if (arg == NULL_TREE || arg == error_mark_node
+      || parm == NULL_TREE || parm == error_mark_node)
+    return 0;
+  
+  if (TREE_CODE (arg) != TREE_CODE (parm))
+    return 0;
+  
+  switch (TREE_CODE (parm))
+    {
+    case TEMPLATE_DECL:
+      /* We encounter instantiations of templates like
+        template <template <template <class> class> class TT>
+        class C;  */
+      {
+       tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+       tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+       
+       if (!coerce_template_template_parms
+           (parmparm, argparm, complain, in_decl, outer_args))
+         return 0;
+      }
+      /* Fall through.  */
+      
+    case TYPE_DECL:
+      if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (arg))
+         && !TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))
+       /* Argument is a parameter pack but parameter is not.  */
+       return 0;
+      break;
+      
+    case PARM_DECL:
+      /* The tsubst call is used to handle cases such as
+        
+           template <int> class C {};
+          template <class T, template <T> class TT> class D {};
+          D<int, C> d;
+
+        i.e. the parameter list of TT depends on earlier parameters.  */
+      if (!dependent_type_p (TREE_TYPE (arg))
+         && !same_type_p
+               (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
+                TREE_TYPE (arg)))
+       return 0;
+      
+      if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (arg))
+         && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+       /* Argument is a parameter pack but parameter is not.  */
+       return 0;
+      
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return 1;
+}
+
 
 /* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for
    template template parameters.  Both PARM_PARMS and ARG_PARMS are
@@ -3773,6 +4725,7 @@ coerce_template_template_parms (tree parm_parms,
 {
   int nparms, nargs, i;
   tree parm, arg;
+  int variadic_p = 0;
 
   gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
   gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
@@ -3780,63 +4733,155 @@ coerce_template_template_parms (tree parm_parms,
   nparms = TREE_VEC_LENGTH (parm_parms);
   nargs = TREE_VEC_LENGTH (arg_parms);
 
-  if (nargs != nparms)
+  /* Determine whether we have a parameter pack at the end of the
+     template template parameter's template parameter list.  */
+  if (TREE_VEC_ELT (parm_parms, nparms - 1) != error_mark_node)
+    {
+      parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, nparms - 1));
+      
+      switch (TREE_CODE (parm))
+        {
+        case TEMPLATE_DECL:
+        case TYPE_DECL:
+          if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))
+            variadic_p = 1;
+          break;
+         
+        case PARM_DECL:
+          if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+            variadic_p = 1;
+          break;
+         
+        default:
+          gcc_unreachable ();
+        }
+    }
+  if (nargs != nparms
+      && !(variadic_p && nargs >= nparms - 1))
     return 0;
 
-  for (i = 0; i < nparms; ++i)
+  /* Check all of the template parameters except the parameter pack at
+     the end (if any).  */
+  for (i = 0; i < nparms - variadic_p; ++i)
     {
-      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node)
+      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node
+          || TREE_VEC_ELT (arg_parms, i) == error_mark_node)
         continue;
 
       parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
       arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
 
-      if (arg == NULL_TREE || arg == error_mark_node
-         || parm == NULL_TREE || parm == error_mark_node)
+      if (!coerce_template_template_parm (parm, arg, complain, in_decl,
+                                          outer_args))
        return 0;
 
-      if (TREE_CODE (arg) != TREE_CODE (parm))
+    }
+
+  if (variadic_p)
+    {
+      /* Check each of the template parameters in the template
+        argument against the template parameter pack at the end of
+        the template template parameter.  */
+      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node)
        return 0;
 
-      switch (TREE_CODE (parm))
-       {
-       case TYPE_DECL:
-         break;
+      parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
 
-       case TEMPLATE_DECL:
-         /* We encounter instantiations of templates like
-              template <template <template <class> class> class TT>
-              class C;  */
-         {
-           tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
-           tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+      for (; i < nargs; ++i)
+        {
+          if (TREE_VEC_ELT (arg_parms, i) == error_mark_node)
+            continue;
+          arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
+          if (!coerce_template_template_parm (parm, arg, complain, in_decl,
+                                              outer_args))
+            return 0;
+        }
+    }
 
-           if (!coerce_template_template_parms
-               (parmparm, argparm, complain, in_decl, outer_args))
-             return 0;
-         }
-         break;
+  return 1;
+}
 
-       case PARM_DECL:
-         /* The tsubst call is used to handle cases such as
+/* 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);
+  bool ret = true;
 
-              template <int> class C {};
-              template <class T, template <T> class TT> class D {};
-              D<int, C> d;
+  /* We're dealing with template parms in this process.  */
+  ++processing_template_decl;
 
-            i.e. the parameter list of TT depends on earlier parameters.  */
-         if (!dependent_type_p (TREE_TYPE (arg))
-             && !same_type_p
-                   (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
-                            TREE_TYPE (arg)))
-           return 0;
-         break;
+  targs = INNERMOST_TEMPLATE_ARGS (targs);
 
-       default:
-         gcc_unreachable ();
+  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))
+               {
+                 ret = false;
+                 goto out;
+               }
+           }
        }
     }
-  return 1;
+
+ out:
+
+  --processing_template_decl;
+  return ret;
 }
 
 /* Convert the indicated template ARG as necessary to match the
@@ -3854,6 +4899,7 @@ 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;
 
@@ -3865,18 +4911,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);
 
-  is_tmpl_type = ((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);
+  /* When determining whether an argument pack expansion is a template,
+     look at the pattern.  */
+  if (TREE_CODE (arg) == TYPE_PACK_EXPANSION)
+    arg = PACK_EXPANSION_PATTERN (arg);
+
+  is_tmpl_type = 
+    ((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
@@ -3888,13 +4942,14 @@ convert_template_argument (tree parm,
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      pedwarn ("to refer to a type member of a template parameter, "
-              "use %<typename %E%>", arg);
-
-      arg = make_typename_type (TREE_OPERAND (arg, 0),
-                               TREE_OPERAND (arg, 1),
-                               typename_type,
-                               complain & tf_error);
+      permerror ("to refer to a type member of a template parameter, "
+                "use %<typename %E%>", orig_arg);
+
+      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)
@@ -3909,11 +4964,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;
@@ -3928,7 +4983,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;
     }
@@ -3944,19 +4999,29 @@ convert_template_argument (tree parm,
          else
            {
              tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
-             tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+             tree argparm;
+
+              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.  */
-                 if (val != error_mark_node
-                     && DECL_TEMPLATE_TEMPLATE_PARM_P (val))
-                   val = TREE_TYPE (val);
+                 if (val != error_mark_node)
+                    {
+                      if (DECL_TEMPLATE_TEMPLATE_PARM_P (val))
+                        val = TREE_TYPE (val);
+                      else if (TREE_CODE (val) == TYPE_PACK_EXPANSION
+                               && DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
+                        {
+                          val = TREE_TYPE (arg);
+                          val = make_pack_expansion (val);
+                        }
+                    }
                }
              else
                {
@@ -3966,7 +5031,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;
@@ -3974,7 +5039,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
@@ -3990,7 +5055,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
@@ -4001,19 +5066,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
@@ -4034,17 +5216,37 @@ 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;
+  bool saved_skip_evaluation;
+
+  /* When used as a boolean value, indicates whether this is a
+     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 = 0;
+
+  inner_args 
+    = expand_template_argument_pack (INNERMOST_TEMPLATE_ARGS (args));
 
-  inner_args = INNERMOST_TEMPLATE_ARGS (args);
   nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
   nparms = TREE_VEC_LENGTH (parms);
 
-  if (nargs > nparms
-      || (nargs < nparms
+  /* 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
          && (!use_default_args
              || (TREE_VEC_ELT (parms, nargs) != error_mark_node
@@ -4052,8 +5254,15 @@ coerce_template_parms (tree parms,
     {
       if (complain & tf_error)
        {
-         error ("wrong number of template arguments (%d, should be %d)",
-                nargs, nparms);
+          const char *or_more = "";
+          if (variadic_p)
+            {
+              or_more = " or more";
+              --nparms;
+            }
+
+         error ("wrong number of template arguments (%d, should be %d%s)",
+                 nargs, nparms, or_more);
 
          if (in_decl)
            error ("provided for %q+D", in_decl);
@@ -4062,44 +5271,97 @@ coerce_template_parms (tree parms,
       return error_mark_node;
     }
 
+  /* We need to evaluate the template arguments, even though this
+     template-id may be nested within a "sizeof".  */
+  saved_skip_evaluation = skip_evaluation;
+  skip_evaluation = false;
   new_inner_args = make_tree_vec (nparms);
   new_args = add_outermost_template_args (args, new_inner_args);
-  for (i = 0; i < nparms; 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, arg_idx) = error_mark_node;
         continue;
+      }
+
+      /* Calculate the next argument.  */
+      if (template_parameter_pack_p (TREE_VALUE (parm)))
+        {
+          /* 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);
 
-      /* Calculate the Ith argument.  */
-      if (i < nargs)
-       arg = TREE_VEC_ELT (inner_args, i);
+          if (arg && PACK_EXPANSION_P (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 (lost)
     return error_mark_node;
@@ -4118,152 +5380,41 @@ template_args_equal (tree ot, tree nt)
   if (TREE_CODE (nt) == TREE_VEC)
     /* For member templates */
     return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt);
+  else if (PACK_EXPANSION_P (ot))
+    return PACK_EXPANSION_P (nt) 
+      && template_args_equal (PACK_EXPANSION_PATTERN (ot),
+                              PACK_EXPANSION_PATTERN (nt));
   else if (TYPE_P (nt))
     return TYPE_P (ot) && same_type_p (ot, nt);
-  else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
-    return 0;
-  else
-    return cp_tree_equal (ot, nt);
-}
-
-/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
-   of template arguments.  Returns 0 otherwise.  */
-
-int
-comp_template_args (tree oldargs, tree newargs)
-{
-  int i;
-
-  if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs))
-    return 0;
-
-  for (i = 0; i < TREE_VEC_LENGTH (oldargs); ++i)
-    {
-      tree nt = TREE_VEC_ELT (newargs, i);
-      tree ot = TREE_VEC_ELT (oldargs, i);
-
-      if (! template_args_equal (ot, nt))
-       return 0;
-    }
-  return 1;
-}
-
-/* Given class template name and parameter list, produce a user-friendly name
-   for the instantiation.  */
-
-static char *
-mangle_class_name_for_template (const char* name, tree parms, tree arglist)
-{
-  static struct obstack scratch_obstack;
-  static char *scratch_firstobj;
-  int i, nparms;
-
-  if (!scratch_firstobj)
-    gcc_obstack_init (&scratch_obstack);
-  else
-    obstack_free (&scratch_obstack, scratch_firstobj);
-  scratch_firstobj = (char *) obstack_alloc (&scratch_obstack, 1);
-
-#define ccat(C)        obstack_1grow (&scratch_obstack, (C));
-#define cat(S) obstack_grow (&scratch_obstack, (S), strlen (S))
-
-  cat (name);
-  ccat ('<');
-  nparms = TREE_VEC_LENGTH (parms);
-  arglist = INNERMOST_TEMPLATE_ARGS (arglist);
-  gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
-  for (i = 0; i < nparms; i++)
-    {
-      tree parm;
-      tree arg;
-
-      if (TREE_VEC_ELT (parms, i) == error_mark_node)
-        continue;
-
-      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      arg = TREE_VEC_ELT (arglist, i);
-
-      if (i)
-       ccat (',');
-
-      if (TREE_CODE (parm) == TYPE_DECL)
-       {
-         cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
-         continue;
-       }
-      else if (TREE_CODE (parm) == TEMPLATE_DECL)
-       {
-         if (TREE_CODE (arg) == TEMPLATE_DECL)
-           {
-             /* Already substituted with real template.  Just output
-                the template name here */
-             tree context = DECL_CONTEXT (arg);
-             if (context)
-               {
-                 /* The template may be defined in a namespace, or
-                    may be a member template.  */
-                 gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
-                             || CLASS_TYPE_P (context));
-                 cat (decl_as_string (DECL_CONTEXT (arg),
-                                     TFF_PLAIN_IDENTIFIER));
-                 cat ("::");
-               }
-             cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
-           }
-         else
-           /* Output the parameter declaration.  */
-           cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
-         continue;
-       }
-      else
-       gcc_assert (TREE_CODE (parm) == PARM_DECL);
-
-      /* No need to check arglist against parmlist here; we did that
-        in coerce_template_parms, called from lookup_template_class.  */
-      cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER));
-    }
-  {
-    char *bufp = obstack_next_free (&scratch_obstack);
-    int offset = 0;
-    while (bufp[offset - 1] == ' ')
-      offset--;
-    obstack_blank_fast (&scratch_obstack, offset);
-
-    /* B<C<char> >, not B<C<char>> */
-    if (bufp[offset - 1] == '>')
-      ccat (' ');
-  }
-  ccat ('>');
-  ccat ('\0');
-  return (char *) obstack_base (&scratch_obstack);
+  else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
+    return 0;
+  else
+    return cp_tree_equal (ot, nt);
 }
 
-static tree
-classtype_mangled_name (tree t)
+/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
+   of template arguments.  Returns 0 otherwise.  */
+
+int
+comp_template_args (tree oldargs, tree newargs)
 {
-  if (CLASSTYPE_TEMPLATE_INFO (t)
-      /* Specializations have already had their names set up in
-        lookup_template_class.  */
-      && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
+  int i;
+
+  oldargs = expand_template_argument_pack (oldargs);
+  newargs = expand_template_argument_pack (newargs);
+
+  if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs))
+    return 0;
+
+  for (i = 0; i < TREE_VEC_LENGTH (oldargs); ++i)
     {
-      tree tmpl = most_general_template (CLASSTYPE_TI_TEMPLATE (t));
+      tree nt = TREE_VEC_ELT (newargs, i);
+      tree ot = TREE_VEC_ELT (oldargs, i);
 
-      /* For non-primary templates, the template parameters are
-        implicit from their surrounding context.  */
-      if (PRIMARY_TEMPLATE_P (tmpl))
-       {
-         tree name = DECL_NAME (tmpl);
-         char *mangled_name = mangle_class_name_for_template
-           (IDENTIFIER_POINTER (name),
-            DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
-            CLASSTYPE_TI_ARGS (t));
-         tree id = get_identifier (mangled_name);
-         IDENTIFIER_TEMPLATE (id) = name;
-         return id;
-       }
+      if (! template_args_equal (ot, nt))
+       return 0;
     }
-
-  return TYPE_IDENTIFIER (t);
+  return 1;
 }
 
 static void
@@ -4272,7 +5423,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))
@@ -4281,14 +5432,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;
 
@@ -4383,7 +5536,7 @@ lookup_template_class (tree d1,
                       int entering_scope,
                       tsubst_flags_t complain)
 {
-  tree template = NULL_TREE, parmlist;
+  tree templ = NULL_TREE, parmlist;
   tree t;
 
   timevar_push (TV_NAME_LOOKUP);
@@ -4392,20 +5545,20 @@ lookup_template_class (tree d1,
     {
       tree value = innermost_non_namespace_value (d1);
       if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
-       template = value;
+       templ = value;
       else
        {
          if (context)
            push_decl_namespace (context);
-         template = lookup_name (d1);
-         template = maybe_get_template_decl_from_type_decl (template);
+         templ = lookup_name (d1);
+         templ = maybe_get_template_decl_from_type_decl (templ);
          if (context)
            pop_decl_namespace ();
        }
-      if (template)
-       context = DECL_CONTEXT (template);
+      if (templ)
+       context = DECL_CONTEXT (templ);
     }
-  else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
+  else if (TREE_CODE (d1) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (d1)))
     {
       tree type = TREE_TYPE (d1);
 
@@ -4416,37 +5569,37 @@ lookup_template_class (tree d1,
 
       if (CLASSTYPE_TEMPLATE_INFO (type))
        {
-         template = CLASSTYPE_TI_TEMPLATE (type);
-         d1 = DECL_NAME (template);
+         templ = CLASSTYPE_TI_TEMPLATE (type);
+         d1 = DECL_NAME (templ);
        }
     }
   else if (TREE_CODE (d1) == ENUMERAL_TYPE
-          || (TYPE_P (d1) && IS_AGGR_TYPE (d1)))
+          || (TYPE_P (d1) && MAYBE_CLASS_TYPE_P (d1)))
     {
-      template = TYPE_TI_TEMPLATE (d1);
-      d1 = DECL_NAME (template);
+      templ = TYPE_TI_TEMPLATE (d1);
+      d1 = DECL_NAME (templ);
     }
   else if (TREE_CODE (d1) == TEMPLATE_DECL
           && TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL)
     {
-      template = d1;
-      d1 = DECL_NAME (template);
-      context = DECL_CONTEXT (template);
+      templ = d1;
+      d1 = DECL_NAME (templ);
+      context = DECL_CONTEXT (templ);
     }
 
   /* Issue an error message if we didn't find a template.  */
-  if (! template)
+  if (! templ)
     {
       if (complain & tf_error)
        error ("%qT is not a template", d1);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
     }
 
-  if (TREE_CODE (template) != TEMPLATE_DECL
+  if (TREE_CODE (templ) != TEMPLATE_DECL
         /* Make sure it's a user visible template, if it was named by
            the user.  */
-      || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
-         && !PRIMARY_TEMPLATE_P (template)))
+      || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (templ)
+         && !PRIMARY_TEMPLATE_P (templ)))
     {
       if (complain & tf_error)
        {
@@ -4459,15 +5612,16 @@ lookup_template_class (tree d1,
 
   complain &= ~tf_user;
 
-  if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
+  if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
     {
       /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
         template arguments */
 
       tree parm;
       tree arglist2;
+      tree outer;
 
-      parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
+      parmlist = DECL_INNERMOST_TEMPLATE_PARMS (templ);
 
       /* Consider an example where a template template parameter declared as
 
@@ -4478,31 +5632,39 @@ 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 (templ);
+      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,
+      arglist2 = coerce_template_parms (parmlist, arglist, templ,
                                        complain,
                                        /*require_all_args=*/true,
                                        /*use_default_args=*/true);
       if (arglist2 == error_mark_node
          || (!uses_template_parms (arglist2)
-             && check_instantiated_args (template, arglist2, complain)))
+             && check_instantiated_args (templ, arglist2, complain)))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
-      parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
+      parm = bind_template_template_parm (TREE_TYPE (templ), arglist2);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
     }
   else
     {
-      tree template_type = TREE_TYPE (template);
+      tree template_type = TREE_TYPE (templ);
       tree gen_tmpl;
       tree type_decl;
       tree found = NULL_TREE;
@@ -4510,7 +5672,7 @@ lookup_template_class (tree d1,
       int parm_depth;
       int is_partial_instantiation;
 
-      gen_tmpl = most_general_template (template);
+      gen_tmpl = most_general_template (templ);
       parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
       parm_depth = TMPL_PARMS_DEPTH (parmlist);
       arg_depth = TMPL_ARGS_DEPTH (arglist);
@@ -4530,7 +5692,7 @@ lookup_template_class (tree d1,
             <class U> struct S1<T>::S2'.  We must fill in the missing
             arguments.  */
          arglist
-           = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (template)),
+           = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)),
                                           arglist);
          arg_depth = TMPL_ARGS_DEPTH (arglist);
        }
@@ -4540,7 +5702,7 @@ lookup_template_class (tree d1,
 
       /* From here on, we're only interested in the most general
         template.  */
-      template = gen_tmpl;
+      templ = gen_tmpl;
 
       /* Calculate the BOUND_ARGS.  These will be the args that are
         actually tsubst'd into the definition to create the
@@ -4554,12 +5716,12 @@ lookup_template_class (tree d1,
          tree bound_args = make_tree_vec (parm_depth);
 
          for (i = saved_depth,
-                t = DECL_TEMPLATE_PARMS (template);
+                t = DECL_TEMPLATE_PARMS (templ);
               i > 0 && t != NULL_TREE;
               --i, t = TREE_CHAIN (t))
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
-                                             arglist, template,
+                                             arglist, templ,
                                              complain,
                                              /*require_all_args=*/true,
                                              /*use_default_args=*/true);
@@ -4590,7 +5752,7 @@ lookup_template_class (tree d1,
        arglist
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
-                                  template,
+                                  templ,
                                   complain,
                                   /*require_all_args=*/true,
                                   /*use_default_args=*/true);
@@ -4612,7 +5774,7 @@ lookup_template_class (tree d1,
        {
          found = template_type;
 
-         if (!entering_scope && PRIMARY_TEMPLATE_P (template))
+         if (!entering_scope && PRIMARY_TEMPLATE_P (templ))
            {
              tree ctx;
 
@@ -4634,7 +5796,7 @@ lookup_template_class (tree d1,
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
 
       /* If we already have this specialization, return it.  */
-      found = retrieve_specialization (template, arglist,
+      found = retrieve_specialization (templ, arglist,
                                       /*class_specializations_p=*/false);
       if (found)
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
@@ -4648,22 +5810,22 @@ lookup_template_class (tree d1,
       /* If the deduced arguments are invalid, then the binding
         failed.  */
       if (!is_partial_instantiation
-         && check_instantiated_args (template,
+         && check_instantiated_args (templ,
                                      INNERMOST_TEMPLATE_ARGS (arglist),
                                      complain))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
       if (!is_partial_instantiation
-         && !PRIMARY_TEMPLATE_P (template)
-         && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
+         && !PRIMARY_TEMPLATE_P (templ)
+         && TREE_CODE (CP_DECL_CONTEXT (templ)) == NAMESPACE_DECL)
        {
-         found = xref_tag_from_type (TREE_TYPE (template),
-                                     DECL_NAME (template),
+         found = xref_tag_from_type (TREE_TYPE (templ),
+                                     DECL_NAME (templ),
                                      /*tag_scope=*/ts_global);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
        }
 
-      context = tsubst (DECL_CONTEXT (template), arglist,
+      context = tsubst (DECL_CONTEXT (templ), arglist,
                        complain, in_decl);
       if (!context)
        context = global_namespace;
@@ -4685,7 +5847,7 @@ lookup_template_class (tree d1,
        }
       else
        {
-         t = make_aggr_type (TREE_CODE (template_type));
+         t = make_class_type (TREE_CODE (template_type));
          CLASSTYPE_DECLARED_CLASS (t)
            = CLASSTYPE_DECLARED_CLASS (template_type);
          SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
@@ -4693,7 +5855,18 @@ lookup_template_class (tree d1,
 
          /* A local class.  Make sure the decl gets registered properly.  */
          if (context == current_function_decl)
-           pushtag (DECL_NAME (template), t, /*tag_scope=*/ts_current);
+           pushtag (DECL_NAME (templ), t, /*tag_scope=*/ts_current);
+
+         if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
+           /* This instantiation is another name for the primary
+              template type. Set the TYPE_CANONICAL field
+              appropriately. */
+           TYPE_CANONICAL (t) = template_type;
+         else if (any_template_arguments_need_structural_equality_p (arglist))
+           /* Some of the template arguments require structural
+              equality testing, so this template class requires
+              structural equality testing. */
+           SET_TYPE_STRUCTURAL_EQUALITY (t);
        }
 
       /* If we called start_enum or pushtag above, this information
@@ -4702,7 +5875,7 @@ lookup_template_class (tree d1,
        {
          TYPE_CONTEXT (t) = FROB_CONTEXT (context);
 
-         type_decl = create_implicit_typedef (DECL_NAME (template), t);
+         type_decl = create_implicit_typedef (DECL_NAME (templ), t);
          DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
          TYPE_STUB_DECL (t) = type_decl;
          DECL_SOURCE_LOCATION (type_decl)
@@ -4715,8 +5888,6 @@ lookup_template_class (tree d1,
        = TREE_PRIVATE (TYPE_STUB_DECL (template_type));
       TREE_PROTECTED (type_decl)
        = TREE_PROTECTED (TYPE_STUB_DECL (template_type));
-      DECL_IN_SYSTEM_HEADER (type_decl)
-       = DECL_IN_SYSTEM_HEADER (template);
       if (CLASSTYPE_VISIBILITY_SPECIFIED (template_type))
        {
          DECL_VISIBILITY_SPECIFIED (type_decl) = 1;
@@ -4727,15 +5898,15 @@ lookup_template_class (tree d1,
         template is the immediate parent if this is a full
         instantiation.  */
       if (parm_depth == 1 || is_partial_instantiation
-         || !PRIMARY_TEMPLATE_P (template))
+         || !PRIMARY_TEMPLATE_P (templ))
        /* This case is easy; there are no member templates involved.  */
-       found = template;
+       found = templ;
       else
        {
          /* This is a full instantiation of a member template.  Look
             for a partial instantiation of which this is an instance.  */
 
-         for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
+         for (found = DECL_TEMPLATE_INSTANTIATIONS (templ);
               found; found = TREE_CHAIN (found))
            {
              int success;
@@ -4780,15 +5951,15 @@ lookup_template_class (tree d1,
                 Create the partial instantiation.
               */
              TREE_VEC_LENGTH (arglist)--;
-             found = tsubst (template, arglist, complain, NULL_TREE);
+             found = tsubst (templ, arglist, complain, NULL_TREE);
              TREE_VEC_LENGTH (arglist)++;
            }
        }
 
       SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
-      DECL_TEMPLATE_INSTANTIATIONS (template)
+      DECL_TEMPLATE_INSTANTIATIONS (templ)
        = tree_cons (arglist, t,
-                    DECL_TEMPLATE_INSTANTIATIONS (template));
+                    DECL_TEMPLATE_INSTANTIATIONS (templ));
 
       if (TREE_CODE (t) == ENUMERAL_TYPE
          && !is_partial_instantiation)
@@ -4801,10 +5972,6 @@ lookup_template_class (tree d1,
           the instantiation and exit above.  */
        tsubst_enum (template_type, t, arglist);
 
-      /* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO
-        is set up.  */
-      if (TREE_CODE (t) != ENUMERAL_TYPE)
-       DECL_NAME (type_decl) = classtype_mangled_name (t);
       if (is_partial_instantiation)
        /* If the type makes use of template parameters, the
           code that generates debugging information will crash.  */
@@ -4823,6 +5990,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;
 };
 
@@ -4837,7 +6007,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))
@@ -4852,7 +6024,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, 
+                                 pfd->include_nondeduced_p)
+         || for_each_template_parm (TYPE_MAX_VALUE (t),
+                                    fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -4860,13 +6043,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
@@ -4880,7 +6064,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
@@ -4890,8 +6074,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;
 
@@ -4899,7 +6085,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.  */
 
@@ -4907,17 +6093,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.  */
 
@@ -4933,7 +6121,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 */
@@ -4943,15 +6132,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;
 
@@ -4977,16 +6168,6 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
        return error_mark_node;
       break;
 
-    case BASELINK:
-      /* If we do not handle this case specially, we end up walking
-        the BINFO hierarchy, which is circular, and therefore
-        confuses walk_tree.  */
-      *walk_subtrees = 0;
-      if (for_each_template_parm (BASELINK_FUNCTIONS (*tp), fn, data,
-                                 pfd->visited))
-       return error_mark_node;
-      break;
-
     default:
       break;
     }
@@ -5002,11 +6183,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;
@@ -5014,6 +6200,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
@@ -5024,10 +6211,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)
@@ -5065,6 +6252,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));
@@ -5084,7 +6272,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;
@@ -5101,7 +6290,7 @@ static int last_template_error_tick;
 static int
 push_tinst_level (tree d)
 {
-  tree new;
+  struct tinst_level *new_level;
 
   if (tinst_depth >= max_tinst_depth)
     {
@@ -5121,12 +6310,12 @@ 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;
-  current_tinst_level = new;
+  new_level = GGC_NEW (struct tinst_level);
+  new_level->decl = d;
+  new_level->locus = input_location;
+  new_level->in_system_header_p = in_system_header;
+  new_level->next = current_tinst_level;
+  current_tinst_level = new_level;
 
   ++tinst_depth;
 #ifdef GATHER_STATISTICS
@@ -5144,32 +6333,43 @@ 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;
+  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
@@ -5201,10 +6401,11 @@ tsubst_friend_function (tree decl, tree args)
 
       /* Friend functions are looked up in the containing namespace scope.
         We must enter that scope, to avoid finding member functions of the
-        current cless with same name.  */
+        current class with same name.  */
       push_nested_namespace (ns);
       fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
-                        tf_warning_or_error, NULL_TREE);
+                        tf_warning_or_error, NULL_TREE,
+                        /*integral_constant_expression_p=*/false);
       pop_nested_namespace (ns);
       arglist = tsubst (DECL_TI_ARGS (decl), args,
                        tf_warning_or_error, NULL_TREE);
@@ -5279,6 +6480,10 @@ tsubst_friend_function (tree decl, tree args)
       else
        new_friend_result_template_info = NULL_TREE;
 
+      /* Make the init_value nonzero so pushdecl knows this is a defn.  */
+      if (new_friend_is_defn)
+       DECL_INITIAL (new_friend) = error_mark_node;
+
       /* Inside pushdecl_namespace_level, we will push into the
         current namespace. However, the friend function should go
         into the namespace of the template.  */
@@ -5487,9 +6692,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);
@@ -5547,10 +6758,85 @@ 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;
+             /* If the first attribute argument is an identifier, don't
+                pass it through tsubst.  Attributes like mode, format,
+                cleanup and several target specific attributes expect it
+                unmodified.  */
+             if (TREE_VALUE (t)
+                 && TREE_CODE (TREE_VALUE (t)) == TREE_LIST
+                 && TREE_VALUE (TREE_VALUE (t))
+                 && (TREE_CODE (TREE_VALUE (TREE_VALUE (t)))
+                     == IDENTIFIER_NODE))
+               {
+                 tree chain
+                   = tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain,
+                                  in_decl,
+                                  /*integral_constant_expression_p=*/false);
+                 if (chain != TREE_CHAIN (TREE_VALUE (t)))
+                   TREE_VALUE (t)
+                     = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)),
+                                  chain);
+               }
+             else
+               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)
 {
-  tree template, args, pattern, t, member;
+  tree templ, args, pattern, t, member;
   tree typedecl;
   tree pbinfo;
   tree base_list;
@@ -5564,12 +6850,12 @@ instantiate_class_template (tree type)
     return type;
 
   /* Figure out which template is being instantiated.  */
-  template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
-  gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
+  templ = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
+  gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
 
   /* Determine what specialization of the original template to
      instantiate.  */
-  t = most_specialized_class (type, template);
+  t = most_specialized_class (type, templ);
   if (t == error_mark_node)
     {
       TYPE_BEING_DEFINED (type) = 1;
@@ -5592,7 +6878,7 @@ instantiate_class_template (tree type)
     }
   else
     {
-      pattern = TREE_TYPE (template);
+      pattern = TREE_TYPE (templ);
       args = CLASSTYPE_TI_ARGS (type);
     }
 
@@ -5621,9 +6907,8 @@ instantiate_class_template (tree type)
      if tsubsting causes an error.  */
   typedecl = TYPE_MAIN_DECL (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);
@@ -5674,15 +6959,37 @@ instantiate_class_template (tree type)
        {
          tree base;
          tree access = BINFO_BASE_ACCESS (pbinfo, i);
-
-         /* Substitute to figure out the base class.  */
-         base = tsubst (BINFO_TYPE (pbase_binfo), args, tf_error, NULL_TREE);
-         if (base == error_mark_node)
-           continue;
-
-         base_list = tree_cons (access, base, base_list);
-         if (BINFO_VIRTUAL_P (pbase_binfo))
-           TREE_TYPE (base_list) = integer_type_node;
+          tree expanded_bases = NULL_TREE;
+          int idx, len = 1;
+
+          if (PACK_EXPANSION_P (BINFO_TYPE (pbase_binfo)))
+            {
+              expanded_bases = 
+               tsubst_pack_expansion (BINFO_TYPE (pbase_binfo),
+                                      args, tf_error, NULL_TREE);
+              if (expanded_bases == error_mark_node)
+                continue;
+
+              len = TREE_VEC_LENGTH (expanded_bases);
+            }
+
+          for (idx = 0; idx < len; idx++)
+            {
+              if (expanded_bases)
+                /* Extract the already-expanded base class.  */
+                base = TREE_VEC_ELT (expanded_bases, idx);
+              else
+                /* Substitute to figure out the base class.  */
+                base = tsubst (BINFO_TYPE (pbase_binfo), args, tf_error, 
+                               NULL_TREE);
+
+              if (base == error_mark_node)
+                continue;
+
+              base_list = tree_cons (access, base, base_list);
+              if (BINFO_VIRTUAL_P (pbase_binfo))
+                TREE_TYPE (base_list) = integer_type_node;
+            }
        }
 
       /* The list is now in reverse order; correct that.  */
@@ -5695,13 +7002,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);
@@ -5779,12 +7089,22 @@ instantiate_class_template (tree type)
          else
            {
              /* Build new TYPE_FIELDS.  */
-
-             if (TREE_CODE (t) != CONST_DECL)
+              if (TREE_CODE (t) == STATIC_ASSERT)
+                {
+                  tree condition = 
+                    tsubst_expr (STATIC_ASSERT_CONDITION (t), args, 
+                                 tf_warning_or_error, NULL_TREE,
+                                 /*integral_constant_expression_p=*/true);
+                  finish_static_assert (condition,
+                                        STATIC_ASSERT_MESSAGE (t), 
+                                        STATIC_ASSERT_SOURCE_LOCATION (t),
+                                        /*member_p=*/true);
+                }
+             else if (TREE_CODE (t) != CONST_DECL)
                {
                  tree r;
 
-                 /* The the file and line for this declaration, to
+                 /* The file and line for this declaration, to
                     assist in error message reporting.  Since we
                     called push_tinst_level above, we don't need to
                     restore these.  */
@@ -5943,7 +7263,7 @@ instantiate_class_template (tree type)
              /* Build new DECL_FRIENDLIST.  */
              tree r;
 
-             /* The the file and line for this declaration, to
+             /* The file and line for this declaration, to
                 assist in error message reporting.  Since we
                 called push_tinst_level above, we don't need to
                 restore these.  */
@@ -5979,7 +7299,7 @@ instantiate_class_template (tree type)
   /* Now that the class is complete, instantiate default arguments for
      any member functions.  We don't do this earlier because the
      default arguments may reference members of the class.  */
-  if (!PRIMARY_TEMPLATE_P (template))
+  if (!PRIMARY_TEMPLATE_P (templ))
     for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t))
       if (TREE_CODE (t) == FUNCTION_DECL
          /* Implicitly generated member functions will not have template
@@ -5988,7 +7308,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 ();
@@ -6014,19 +7334,232 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     r = tsubst (t, args, complain, in_decl);
   else
     {
-      r = tsubst_expr (t, args, complain, in_decl);
+      r = tsubst_expr (t, args, complain, in_decl,
+                      /*integral_constant_expression_p=*/true);
       r = fold_non_dependent_expr (r);
     }
   return r;
 }
 
+/* Substitute ARGS into T, which is an pack expansion
+   (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a
+   TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node
+   (if only a partial substitution could be performed) or
+   ERROR_MARK_NODE if there was an error.  */
+tree
+tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
+                      tree in_decl)
+{
+  tree pattern;
+  tree pack, packs = NULL_TREE, unsubstituted_packs = NULL_TREE;
+  tree first_arg_pack; int i, len = -1;
+  tree result;
+  int incomplete = 0;
+
+  gcc_assert (PACK_EXPANSION_P (t));
+  pattern = PACK_EXPANSION_PATTERN (t);
+
+  /* Determine the argument packs that will instantiate the parameter
+     packs used in the expansion expression. While we're at it,
+     compute the number of arguments to be expanded and make sure it
+     is consistent.  */
+  for (pack = PACK_EXPANSION_PARAMETER_PACKS (t); pack; 
+       pack = TREE_CHAIN (pack))
+    {
+      tree parm_pack = TREE_VALUE (pack);
+      tree arg_pack = NULL_TREE;
+      tree orig_arg = NULL_TREE;
+
+      if (TREE_CODE (parm_pack) == PARM_DECL)
+       arg_pack = retrieve_local_specialization (parm_pack);
+      else
+        {
+          int level, idx, levels;
+          template_parm_level_and_index (parm_pack, &level, &idx);
+
+          levels = TMPL_ARGS_DEPTH (args);
+          if (level <= levels)
+            arg_pack = TMPL_ARG (args, level, idx);
+        }
+
+      orig_arg = arg_pack;
+      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 = 
+            TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
+
+          /* It's all-or-nothing with incomplete argument packs.  */
+          if (incomplete && !ARGUMENT_PACK_INCOMPLETE_P (arg_pack))
+            return error_mark_node;
+          
+          if (ARGUMENT_PACK_INCOMPLETE_P (arg_pack))
+            incomplete = 1;
+
+          if (len < 0)
+            {
+              len = my_len;
+              first_arg_pack = arg_pack;
+            }
+          else if (len != my_len)
+            {
+              if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
+                error ("mismatched argument pack lengths while expanding "
+                       "%<%T%>",
+                       pattern);
+              else
+                error ("mismatched argument pack lengths while expanding "
+                       "%<%E%>",
+                       pattern);
+              return error_mark_node;
+            }
+
+          /* Keep track of the parameter packs and their corresponding
+             argument packs.  */
+          packs = tree_cons (parm_pack, arg_pack, packs);
+          TREE_TYPE (packs) = orig_arg;
+        }
+      else
+        /* We can't substitute for this parameter pack.  */
+        unsubstituted_packs = tree_cons (TREE_PURPOSE (pack),
+                                         TREE_VALUE (pack),
+                                         unsubstituted_packs);
+    }
+
+  /* We cannot expand this expansion expression, because we don't have
+     all of the argument packs we need. Substitute into the pattern
+     and return a PACK_EXPANSION_*. The caller will need to deal with
+     that.  */
+  if (unsubstituted_packs)
+    return make_pack_expansion (tsubst (pattern, args, complain, 
+                                       in_decl));
+
+  /* We could not find any argument packs that work.  */
+  if (len < 0)
+    return error_mark_node;
+
+  /* For each argument in each argument pack, substitute into the
+     pattern.  */
+  result = make_tree_vec (len + incomplete);
+  for (i = 0; i < len + incomplete; ++i)
+    {
+      /* For parameter pack, change the substitution of the parameter
+         pack to the ith argument in its argument pack, then expand
+         the pattern.  */
+      for (pack = packs; pack; pack = TREE_CHAIN (pack))
+        {
+          tree parm = TREE_PURPOSE (pack);
+
+          if (TREE_CODE (parm) == PARM_DECL)
+            {
+             /* Select the Ith argument from the pack.  */
+             tree arg = make_node (ARGUMENT_PACK_SELECT);
+             ARGUMENT_PACK_SELECT_FROM_PACK (arg) = TREE_VALUE (pack);
+             ARGUMENT_PACK_SELECT_INDEX (arg) = i;
+              mark_used (parm);
+              register_local_specialization (arg, parm);
+            }
+          else
+            {
+              tree value = parm;
+              int idx, level;
+              template_parm_level_and_index (parm, &level, &idx);
+              
+             if (i < len) 
+               {
+                 /* Select the Ith argument from the pack. */
+                 value = make_node (ARGUMENT_PACK_SELECT);
+                 ARGUMENT_PACK_SELECT_FROM_PACK (value) = TREE_VALUE (pack);
+                 ARGUMENT_PACK_SELECT_INDEX (value) = i;
+               }
+
+              /* Update the corresponding argument.  */
+              TMPL_ARG (args, level, idx) = value;
+            }
+        }
+
+      /* Substitute into the PATTERN with the altered arguments.  */
+      if (TREE_CODE (t) == EXPR_PACK_EXPANSION)
+        TREE_VEC_ELT (result, i) = 
+          tsubst_expr (pattern, args, complain, in_decl,
+                       /*integral_constant_expression_p=*/false);
+      else
+        TREE_VEC_ELT (result, i) = tsubst (pattern, args, complain, in_decl);
+
+      if (i == len)
+        /* When we have incomplete argument packs, the last "expanded"
+           result is itself a pack expansion, which allows us
+           to deduce more arguments.  */
+        TREE_VEC_ELT (result, i) = 
+          make_pack_expansion (TREE_VEC_ELT (result, i));
+
+      if (TREE_VEC_ELT (result, i) == error_mark_node)
+       {
+         result = error_mark_node;
+         break;
+       }
+    }
+  
+  /* Update ARGS to restore the substitution from parameter packs to
+     their argument packs.  */
+  for (pack = packs; pack; pack = TREE_CHAIN (pack))
+    {
+      tree parm = TREE_PURPOSE (pack);
+
+      if (TREE_CODE (parm) == PARM_DECL)
+        register_local_specialization (TREE_TYPE (pack), parm);
+      else
+        {
+          int idx, level;
+          template_parm_level_and_index (parm, &level, &idx);
+          
+          /* Update the corresponding argument.  */
+          if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+            TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) =
+              TREE_TYPE (pack);
+          else
+            TREE_VEC_ELT (args, idx) = TREE_TYPE (pack);
+        }
+    }
+
+  return result;
+}
+
 /* Substitute ARGS into the vector or list of template arguments T.  */
 
 static tree
 tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 {
+  tree orig_t = t;
   int len = TREE_VEC_LENGTH (t);
-  int need_new = 0, i;
+  int need_new = 0, i, expanded_len_adjust = 0, out;
   tree *elts = (tree *) alloca (len * sizeof (tree));
 
   for (i = 0; i < len; i++)
@@ -6036,6 +7569,42 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
       if (TREE_CODE (orig_arg) == TREE_VEC)
        new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
+      else if (PACK_EXPANSION_P (orig_arg))
+        {
+          /* Substitute into an expansion expression.  */
+          new_arg = tsubst_pack_expansion (orig_arg, args, complain, in_decl);
+
+          if (TREE_CODE (new_arg) == TREE_VEC)
+            /* Add to the expanded length adjustment the number of
+               expanded arguments. We subtract one from this
+               measurement, because the argument pack expression
+               itself is already counted as 1 in
+               LEN. EXPANDED_LEN_ADJUST can actually be negative, if
+               the argument pack is empty.  */
+            expanded_len_adjust += TREE_VEC_LENGTH (new_arg) - 1;
+        }
+      else if (ARGUMENT_PACK_P (orig_arg))
+        {
+          /* Substitute into each of the arguments.  */
+          new_arg = make_node (TREE_CODE (orig_arg));
+          
+          SET_ARGUMENT_PACK_ARGS (
+            new_arg,
+            tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg),
+                                  args, complain, in_decl));
+
+          if (ARGUMENT_PACK_ARGS (new_arg) == error_mark_node)
+            new_arg = error_mark_node;
+
+          if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK) {
+            TREE_TYPE (new_arg) = tsubst (TREE_TYPE (orig_arg), args,
+                                          complain, in_decl);
+            TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg);
+
+            if (TREE_TYPE (new_arg) == error_mark_node)
+              new_arg = error_mark_node;
+          }
+        }
       else
        new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl);
 
@@ -6050,9 +7619,27 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   if (!need_new)
     return t;
 
-  t = make_tree_vec (len);
-  for (i = 0; i < len; i++)
-    TREE_VEC_ELT (t, i) = elts[i];
+  /* Make space for the expanded arguments coming from template
+     argument packs.  */
+  t = make_tree_vec (len + expanded_len_adjust);
+  for (i = 0, out = 0; i < len; i++)
+    {
+      if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
+           || ARGUMENT_PACK_P (TREE_VEC_ELT (orig_t, i)))
+          && TREE_CODE (elts[i]) == TREE_VEC)
+        {
+          int idx;
+
+          /* Now expand the template argument pack "in place".  */
+          for (idx = 0; idx < TREE_VEC_LENGTH (elts[i]); idx++, out++)
+            TREE_VEC_ELT (t, out) = TREE_VEC_ELT (elts[i], idx);
+        }
+      else
+        {
+          TREE_VEC_ELT (t, out) = elts[i];
+          out++;
+        }
+    }
 
   return t;
 }
@@ -6149,7 +7736,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;
@@ -6164,8 +7751,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:
@@ -6239,7 +7832,8 @@ tsubst_default_argument (tree fn, tree type, tree arg)
      stack.  */
   ++function_depth;
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
-                    tf_warning_or_error, NULL_TREE);
+                    tf_warning_or_error, NULL_TREE,
+                    /*integral_constant_expression_p=*/false);
   --function_depth;
   pop_deferring_access_checks();
 
@@ -6637,8 +8231,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            if (PRIMARY_TEMPLATE_P (gen_tmpl))
              clone_function_decl (r, /*update_method_vec_p=*/0);
          }
-       else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
-         grok_op_properties (r, (complain & tf_error) != 0);
+       else if (IDENTIFIER_OPNAME_P (DECL_NAME (r))
+                && !grok_op_properties (r, (complain & tf_error) != 0))
+         return error_mark_node;
 
        if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
          SET_DECL_FRIEND_CONTEXT (r,
@@ -6654,38 +8249,121 @@ 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;
 
     case PARM_DECL:
       {
-       tree type;
-
-       r = copy_node (t);
-       if (DECL_TEMPLATE_PARM_P (t))
-         SET_DECL_TEMPLATE_PARM_P (r);
-
-       type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-       type = type_decays_to (type);
-       TREE_TYPE (r) = type;
-       cp_apply_type_quals_to_decl (cp_type_quals (type), r);
-
-       if (DECL_INITIAL (r))
-         {
-           if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
-             DECL_INITIAL (r) = TREE_TYPE (r);
-           else
-             DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
-                                        complain, in_decl);
-         }
-
-       DECL_CONTEXT (r) = NULL_TREE;
+       tree type = NULL_TREE;
+        int i, len = 1;
+        tree expanded_types = NULL_TREE;
+        tree prev_r = NULL_TREE;
+        tree first_r = NULL_TREE;
+
+        if (FUNCTION_PARAMETER_PACK_P (t))
+          {
+            /* 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 specialization (which will be a single
+               parm).  */
+            tree spec = retrieve_local_specialization (t);
+            if (spec 
+                && TREE_CODE (spec) == PARM_DECL
+                && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION)
+              return spec;
+
+            /* Expand the TYPE_PACK_EXPANSION that provides the types for
+               the parameters in this function parameter pack.  */
+            expanded_types = tsubst_pack_expansion (TREE_TYPE (t), args,
+                                                   complain, in_decl);
+            if (TREE_CODE (expanded_types) == TREE_VEC)
+              {
+                len = TREE_VEC_LENGTH (expanded_types);
+
+                /* Zero-length parameter packs are boring. Just substitute
+                   into the chain.  */
+                if (len == 0)
+                  return tsubst (TREE_CHAIN (t), args, complain, 
+                                 TREE_CHAIN (t));
+              }
+            else
+              {
+                /* All we did was update the type. Make a note of that.  */
+                type = expanded_types;
+                expanded_types = NULL_TREE;
+              }
+          }
+
+        /* Loop through all of the parameter's we'll build. When T is
+           a function parameter pack, LEN is the number of expanded
+           types in EXPANDED_TYPES; otherwise, LEN is 1.  */
+        r = NULL_TREE;
+        for (i = 0; i < len; ++i)
+          {
+            prev_r = r;
+            r = copy_node (t);
+            if (DECL_TEMPLATE_PARM_P (t))
+              SET_DECL_TEMPLATE_PARM_P (r);
+
+            if (expanded_types)
+              /* We're on the Ith parameter of the function parameter
+                 pack.  */
+              {
+                /* Get the Ith type.  */
+                type = TREE_VEC_ELT (expanded_types, i);
+
+                if (DECL_NAME (r))
+                  /* Rename the parameter to include the index.  */
+                  DECL_NAME (r) =
+                    make_ith_pack_parameter_name (DECL_NAME (r), i);
+              }
+            else if (!type)
+              /* We're dealing with a normal parameter.  */
+              type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+            type = type_decays_to (type);
+            TREE_TYPE (r) = type;
+            cp_apply_type_quals_to_decl (cp_type_quals (type), r);
+
+            if (DECL_INITIAL (r))
+              {
+                if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
+                  DECL_INITIAL (r) = TREE_TYPE (r);
+                else
+                  DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
+                                             complain, in_decl);
+              }
+
+            DECL_CONTEXT (r) = NULL_TREE;
+
+            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.  */
+            if (!first_r)
+              first_r = r;
+
+            /* Build a proper chain of parameters when substituting
+               into a function parameter pack.  */
+            if (prev_r)
+              TREE_CHAIN (prev_r) = r;
+          }
 
-       if (!DECL_TEMPLATE_PARM_P (r))
-         DECL_ARG_TYPE (r) = type_passed_as (type);
        if (TREE_CHAIN (t))
          TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
                                   complain, TREE_CHAIN (t));
+
+        /* FIRST_R contains the start of the chain we've built.  */
+        r = first_r;
       }
       break;
 
@@ -6700,13 +8378,19 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        TREE_TYPE (r) = type;
        cp_apply_type_quals_to_decl (cp_type_quals (type), r);
 
+       /* DECL_INITIAL gives the number of bits in a bit-field.  */
+       DECL_INITIAL (r)
+         = tsubst_expr (DECL_INITIAL (t), args,
+                        complain, in_decl,
+                        /*integral_constant_expression_p=*/true);
        /* We don't have to set DECL_CONTEXT here; it is set by
           finish_member_declaration.  */
-       DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
-                                       complain, in_decl);
        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;
 
@@ -6738,20 +8422,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
@@ -6813,6 +8496,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
@@ -6820,9 +8505,29 @@ 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)
+             {
+               /* It may seem that this case cannot occur, since:
+
+                    typedef void f();
+                    void g() { f x; }
+
+                  declares a function, not a variable.  However:
+      
+                    typedef void f();
+                    template <typename T> void g() { T t; }
+                    template void g<f>();
+
+                  is an attempt to declare a variable with function
+                  type.  */
+               error ("variable %qD has function type",
+                      /* R is not yet sufficiently initialized, so we
+                         just use its name.  */
+                      DECL_NAME (r));
+               return error_mark_node;
+             }
            type = complete_type (type);
            DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
              = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
@@ -6831,7 +8536,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            if (DECL_HAS_VALUE_EXPR_P (t))
              {
                tree ve = DECL_VALUE_EXPR (t);
-               ve = tsubst_expr (ve, args, complain, in_decl);
+               ve = tsubst_expr (ve, args, complain, in_decl,
+                                 /*constant_expression_p=*/false);
                SET_DECL_VALUE_EXPR (r, ve);
              }
          }
@@ -6862,6 +8568,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)
          {
@@ -6879,6 +8595,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;
@@ -6902,9 +8622,10 @@ tsubst_arg_types (tree arg_types,
                  tree in_decl)
 {
   tree remaining_arg_types;
-  tree type;
+  tree type = NULL_TREE;
+  int i = 1;
+  tree expanded_args = NULL_TREE;
   tree default_arg;
-  tree result = NULL_TREE;
 
   if (!arg_types || arg_types == void_list_node)
     return arg_types;
@@ -6914,42 +8635,73 @@ tsubst_arg_types (tree arg_types,
   if (remaining_arg_types == error_mark_node)
     return error_mark_node;
 
-  type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
-  if (type == error_mark_node)
-    return error_mark_node;
-  if (VOID_TYPE_P (type))
+  if (PACK_EXPANSION_P (TREE_VALUE (arg_types)))
     {
-      if (complain & tf_error)
-       {
-         error ("invalid parameter type %qT", type);
-         if (in_decl)
-           error ("in declaration %q+D", in_decl);
-       }
-      return error_mark_node;
+      /* For a pack expansion, perform substitution on the
+         entire expression. Later on, we'll handle the arguments
+         one-by-one.  */
+      expanded_args = tsubst_pack_expansion (TREE_VALUE (arg_types),
+                                            args, complain, in_decl);
+
+      if (TREE_CODE (expanded_args) == TREE_VEC)
+        /* So that we'll spin through the parameters, one by one.  */
+        i = TREE_VEC_LENGTH (expanded_args);
+      else
+        {
+          /* We only partially substituted into the parameter
+             pack. Our type is TYPE_PACK_EXPANSION.  */
+          type = expanded_args;
+          expanded_args = NULL_TREE;
+        }
     }
 
-  /* Do array-to-pointer, function-to-pointer conversion, and ignore
-     top-level qualifiers as required.  */
-  type = TYPE_MAIN_VARIANT (type_decays_to (type));
-
-  /* We do not substitute into default arguments here.  The standard
-     mandates that they be instantiated only when needed, which is
-     done in build_over_call.  */
-  default_arg = TREE_PURPOSE (arg_types);
+  while (i > 0) {
+    --i;
+    
+    if (expanded_args)
+      type = TREE_VEC_ELT (expanded_args, i);
+    else if (!type)
+      type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
 
-  if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
-    {
-      /* We've instantiated a template before its default arguments
-        have been parsed.  This can happen for a nested template
-        class, and is not an error unless we require the default
-        argument in a call of this function.  */
-      result = tree_cons (default_arg, type, remaining_arg_types);
-      VEC_safe_push (tree, gc, DEFARG_INSTANTIATIONS (default_arg), result);
+    if (type == error_mark_node)
+      return error_mark_node;
+    if (VOID_TYPE_P (type))
+      {
+        if (complain & tf_error)
+          {
+            error ("invalid parameter type %qT", type);
+            if (in_decl)
+              error ("in declaration %q+D", in_decl);
+          }
+        return error_mark_node;
     }
-  else
-    result = hash_tree_cons (default_arg, type, remaining_arg_types);
+    
+    /* Do array-to-pointer, function-to-pointer conversion, and ignore
+       top-level qualifiers as required.  */
+    type = TYPE_MAIN_VARIANT (type_decays_to (type));
 
-  return result;
+    /* We do not substitute into default arguments here.  The standard
+       mandates that they be instantiated only when needed, which is
+       done in build_over_call.  */
+    default_arg = TREE_PURPOSE (arg_types);
+
+    if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
+      {
+        /* We've instantiated a template before its default arguments
+           have been parsed.  This can happen for a nested template
+           class, and is not an error unless we require the default
+           argument in a call of this function.  */
+        remaining_arg_types = 
+          tree_cons (default_arg, type, remaining_arg_types);
+        VEC_safe_push (tree, gc, DEFARG_INSTANTIATIONS (default_arg), 
+                       remaining_arg_types);
+      }
+    else
+      remaining_arg_types = 
+        hash_tree_cons (default_arg, type, remaining_arg_types);
+  }
+       
+  return remaining_arg_types;
 }
 
 /* Substitute into a FUNCTION_TYPE or METHOD_TYPE.  This routine does
@@ -7015,7 +8767,7 @@ tsubst_function_type (tree t,
   else
     {
       tree r = TREE_TYPE (TREE_VALUE (arg_types));
-      if (! IS_AGGR_TYPE (r))
+      if (! MAYBE_CLASS_TYPE_P (r))
        {
          /* [temp.deduct]
 
@@ -7062,11 +8814,48 @@ tsubst_exception_specification (tree fntype,
        while (specs)
          {
            tree spec;
-           spec = tsubst (TREE_VALUE (specs), args, complain, in_decl);
-           if (spec == error_mark_node)
-             return spec;
-           new_specs = add_exception_specifier (new_specs, spec, complain);
-           specs = TREE_CHAIN (specs);
+            int i, len = 1;
+            tree expanded_specs = NULL_TREE;
+
+            if (PACK_EXPANSION_P (TREE_VALUE (specs)))
+              {
+                /* Expand the pack expansion type.  */
+                expanded_specs = tsubst_pack_expansion (TREE_VALUE (specs),
+                                                       args, complain,
+                                                       in_decl);
+
+               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)
+              {
+                if (expanded_specs)
+                  spec = TREE_VEC_ELT (expanded_specs, i);
+                else
+                  spec = tsubst (TREE_VALUE (specs), args, complain, in_decl);
+                if (spec == error_mark_node)
+                  return spec;
+                new_specs = add_exception_specifier (new_specs, spec, 
+                                                     complain);
+              }
+
+            specs = TREE_CHAIN (specs);
          }
     }
   return new_specs;
@@ -7111,6 +8900,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
@@ -7151,11 +8975,19 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
 
-       /* The array dimension behaves like a non-type template arg,
-          in that we want to fold it as much as possible.  */
-       max = tsubst_template_arg (omax, args, complain, in_decl);
+       max = tsubst_expr (omax, args, complain, in_decl,
+                          /*integral_constant_expression_p=*/false);
        max = fold_decl_constant_value (max);
 
+       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");
+           return error_mark_node;
+         }
+
        /* [temp.deduct]
 
           Type deduction may fail for any of the following
@@ -7168,7 +9000,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
             indicated by the state of complain), so that
             another substitution can be found.  */
          return error_mark_node;
-
        else if (TREE_CODE (max) == INTEGER_CST
                 && INT_CST_LT (max, integer_zero_node))
          {
@@ -7194,33 +9025,52 @@ 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)
-         arg = TMPL_ARG (args, level, idx);
+         {
+           arg = TMPL_ARG (args, level, idx);
+
+           if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
+             /* See through ARGUMENT_PACK_SELECT arguments. */
+             arg = ARGUMENT_PACK_SELECT_ARG (arg);
+         }
 
        if (arg == error_mark_node)
          return error_mark_node;
        else if (arg != NULL_TREE)
          {
+           if (ARGUMENT_PACK_P (arg))
+             /* If ARG is an argument pack, we don't actually want to
+                perform a substitution here, because substitutions
+                for argument packs are only done
+                element-by-element. We can get to this point when
+                substituting the type of a non-type template
+                parameter pack, when that type actually contains
+                template parameter packs from an outer template, e.g.,
+
+                template<typename... Types> struct A {
+                  template<Types... Values> struct B { };
+                 };  */
+             return t;
+
            if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
              {
+               int quals;
                gcc_assert (TYPE_P (arg));
+
+               /* cv-quals from the template are discarded when
+                  substituting in a function or reference type.  */
+               if (TREE_CODE (arg) == FUNCTION_TYPE
+                   || TREE_CODE (arg) == METHOD_TYPE
+                   || TREE_CODE (arg) == REFERENCE_TYPE)
+                 quals = cp_type_quals (arg);
+               else
+                 quals = cp_type_quals (arg) | cp_type_quals (t);
+                 
                return cp_build_qualified_type_real
-                 (arg, cp_type_quals (arg) | cp_type_quals (t),
-                  complain | tf_ignore_bad_quals);
+                 (arg, quals, complain | tf_ignore_bad_quals);
              }
            else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
              {
@@ -7279,12 +9129,26 @@ 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;
                TYPE_REFERENCE_TO (r) = NULL_TREE;
 
+               if (TREE_CODE (r) == TEMPLATE_TEMPLATE_PARM)
+                 /* We have reduced the level of the template
+                    template parameter, but not the levels of its
+                    template parameters, so canonical_type_parameter
+                    will not be able to find the canonical template
+                    template parameter for this level. Thus, we
+                    require structural equality checking to compare
+                    TEMPLATE_TEMPLATE_PARMs. */
+                 SET_TYPE_STRUCTURAL_EQUALITY (r);
+               else if (TYPE_STRUCTURAL_EQUALITY_P (t))
+                 SET_TYPE_STRUCTURAL_EQUALITY (r);
+               else
+                 TYPE_CANONICAL (r) = canonical_type_parameter (r);
+
                if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
                  {
                    tree argvec = tsubst (TYPE_TI_ARGS (t), args,
@@ -7299,7 +9163,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:
@@ -7371,8 +9235,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;
@@ -7381,13 +9250,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");
@@ -7406,8 +9269,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)
@@ -7419,7 +9296,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OFFSET_TYPE:
       {
        r = tsubst (TYPE_OFFSET_BASETYPE (t), args, complain, in_decl);
-       if (r == error_mark_node || !IS_AGGR_TYPE (r))
+       if (r == error_mark_node || !MAYBE_CLASS_TYPE_P (r))
          {
            /* [temp.deduct]
 
@@ -7520,6 +9397,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;
       }
 
@@ -7555,7 +9439,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (ctx == error_mark_node || f == error_mark_node)
          return error_mark_node;
 
-       if (!IS_AGGR_TYPE (ctx))
+       if (!MAYBE_CLASS_TYPE_P (ctx))
          {
            if (complain & tf_error)
              error ("%qT is not a class, struct, or union type", ctx);
@@ -7627,7 +9511,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case ARRAY_REF:
       {
        tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
+       tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl,
+                              /*integral_constant_expression_p=*/false);
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
@@ -7649,14 +9534,52 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree type;
 
-       type = finish_typeof (tsubst_expr (TYPEOF_TYPE_EXPR (t), args,
-                                          complain, in_decl));
+       type = finish_typeof (tsubst_expr 
+                             (TYPEOF_TYPE_EXPR (t), args,
+                              complain, in_decl,
+                              /*integral_constant_expression_p=*/false));
+       return cp_build_qualified_type_real (type,
+                                            cp_type_quals (t)
+                                            | cp_type_quals (type),
+                                            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:
+      {
+        tree r = make_node (TREE_CODE (t));
+        tree packed_out = 
+          tsubst_template_args (ARGUMENT_PACK_ARGS (t), 
+                                args,
+                                complain,
+                                in_decl);
+        SET_ARGUMENT_PACK_ARGS (r, packed_out);
+
+        /* For template nontype argument packs, also substitute into
+           the type.  */
+        if (TREE_CODE (t) == NONTYPE_ARGUMENT_PACK)
+          TREE_TYPE (r) = tsubst (TREE_TYPE (t), args, complain, in_decl);
+
+        return r;
+      }
+      break;
+
     default:
       sorry ("use of %qs in template",
             tree_code_name [(int) TREE_CODE (t)]);
@@ -7679,15 +9602,15 @@ tsubst_baselink (tree baselink, tree object_type,
     tree template_args = 0;
     bool template_id_p = false;
 
-    /* A baselink indicates a function from a base class.  The
-       BASELINK_ACCESS_BINFO and BASELINK_BINFO are going to have
-       non-dependent types; otherwise, the lookup could not have
-       succeeded.  However, they may indicate bases of the template
-       class, rather than the instantiated class.
-
-       In addition, lookups that were not ambiguous before may be
-       ambiguous now.  Therefore, we perform the lookup again.  */
+    /* A baselink indicates a function from a base class.  Both the
+       BASELINK_ACCESS_BINFO and the base class referenced may
+       indicate bases of the template class, rather than the
+       instantiated class.  In addition, lookups that were not
+       ambiguous before may be ambiguous now.  Therefore, we perform
+       the lookup again.  */
     qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
+    qualifying_scope = tsubst (qualifying_scope, args,
+                              complain, in_decl);
     fns = BASELINK_FUNCTIONS (baselink);
     optype = BASELINK_OPTYPE (baselink);
     if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
@@ -7816,7 +9739,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
       if (complain & tf_error)
        qualified_name_lookup_error (scope,
                                     TREE_OPERAND (qualified_id, 1),
-                                    expr);
+                                    expr, input_location);
       return error_mark_node;
     }
 
@@ -7825,7 +9748,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
 
   if (expr == error_mark_node && complain & tf_error)
     qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
-                                expr);
+                                expr, input_location);
   else if (TYPE_P (scope))
     {
       expr = (adjust_result_of_qualified_name_lookup
@@ -7836,7 +9759,11 @@ tsubst_qualified_id (tree qualified_id, tree args,
               /*template_arg_p=*/false));
     }
 
-  if (TREE_CODE (expr) != SCOPE_REF)
+  /* Expressions do not generally have reference type.  */
+  if (TREE_CODE (expr) != SCOPE_REF
+      /* However, if we're about to form a pointer-to-member, we just
+        want the referenced member referenced.  */
+      && TREE_CODE (expr) != OFFSET_REF)
     expr = convert_from_reference (expr);
 
   return expr;
@@ -7862,6 +9789,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case PARM_DECL:
       r = retrieve_local_specialization (t);
       gcc_assert (r != NULL);
+      if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
+       r = ARGUMENT_PACK_SELECT_ARG (r);
       mark_used (r);
       return r;
 
@@ -7981,13 +9910,45 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
         tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
 
+    case SIZEOF_EXPR:
+      if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+        {
+          /* We only want to compute the number of arguments.  */
+          tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
+                                                complain, in_decl);
+         int len = 0;
+
+         if (TREE_CODE (expanded) == TREE_VEC)
+           len = TREE_VEC_LENGTH (expanded);
+
+         if (expanded == error_mark_node)
+           return error_mark_node;
+         else if (PACK_EXPANSION_P (expanded)
+                  || (TREE_CODE (expanded) == TREE_VEC
+                      && len > 0
+                      && PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1))))
+           {
+             if (TREE_CODE (expanded) == TREE_VEC)
+               expanded = TREE_VEC_ELT (expanded, len - 1);
+
+             if (TYPE_P (expanded))
+               return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR, 
+                                                  complain & tf_error);
+             else
+               return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR,
+                                                   complain & tf_error);
+           }
+         else
+           return build_int_cst (size_type_node, len);
+        }
+      /* Fall through */
+
     case INDIRECT_REF:
     case NEGATE_EXPR:
     case TRUTH_NOT_EXPR:
     case BIT_NOT_EXPR:
     case ADDR_EXPR:
     case UNARY_PLUS_EXPR:      /* Unary + */
-    case SIZEOF_EXPR:
     case ALIGNOF_EXPR:
     case ARROW_EXPR:
     case THROW_EXPR:
@@ -8090,12 +10051,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
         NULL_TREE, NULL_TREE);
 
     case CALL_EXPR:
-      return build_nt (code,
-                      tsubst_copy (TREE_OPERAND (t, 0), args,
-                                   complain, in_decl),
-                      tsubst_copy (TREE_OPERAND (t, 1), args, complain,
-                                   in_decl),
-                      NULL_TREE);
+      {
+       int n = VL_EXP_OPERAND_LENGTH (t);
+       tree result = build_vl_exp (CALL_EXPR, n);
+       int i;
+       for (i = 0; i < n; i++)
+         TREE_OPERAND (t, i) = tsubst_copy (TREE_OPERAND (t, i), args,
+                                            complain, in_decl);
+       return result;
+      }
 
     case COND_EXPR:
     case MODOP_EXPR:
@@ -8182,6 +10146,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);
 
@@ -8213,6 +10178,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       mark_used (TREE_OPERAND (t, 1));
       return t;
 
+    case EXPR_PACK_EXPANSION:
+      error ("invalid use of pack expansion expression");
+      return error_mark_node;
+
+    case NONTYPE_ARGUMENT_PACK:
+      error ("use %<...%> to expand argument pack");
+      return error_mark_node;
+
     default:
       return t;
     }
@@ -8234,22 +10207,34 @@ tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
 
       switch (OMP_CLAUSE_CODE (nc))
        {
+       case OMP_CLAUSE_LASTPRIVATE:
+         if (OMP_CLAUSE_LASTPRIVATE_STMT (oc))
+           {
+             OMP_CLAUSE_LASTPRIVATE_STMT (nc) = push_stmt_list ();
+             tsubst_expr (OMP_CLAUSE_LASTPRIVATE_STMT (oc), args, complain,
+                          in_decl, /*integral_constant_expression_p=*/false);
+             OMP_CLAUSE_LASTPRIVATE_STMT (nc)
+               = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (nc));
+           }
+         /* FALLTHRU */
        case OMP_CLAUSE_PRIVATE:
        case OMP_CLAUSE_SHARED:
        case OMP_CLAUSE_FIRSTPRIVATE:
-       case OMP_CLAUSE_LASTPRIVATE:
        case OMP_CLAUSE_REDUCTION:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_SCHEDULE:
+       case OMP_CLAUSE_COLLAPSE:
          OMP_CLAUSE_OPERAND (nc, 0)
-           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
+           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, 
+                          in_decl, /*integral_constant_expression_p=*/false);
          break;
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
+       case OMP_CLAUSE_UNTIED:
          break;
        default:
          gcc_unreachable ();
@@ -8274,7 +10259,8 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
 
   if (TREE_CODE (t) != TREE_LIST)
     return tsubst_copy_and_build (t, args, complain, in_decl,
-                                 /*function_p=*/false);
+                                 /*function_p=*/false,
+                                 /*integral_constant_expression_p=*/false);
 
   if (t == void_list_node)
     return t;
@@ -8292,12 +10278,148 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
 #undef RECUR
 }
 
+/* Substitute one OMP_FOR iterator.  */
+
+static void
+tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
+                        tree condv, tree incrv, tree *clauses,
+                        tree args, tsubst_flags_t complain, tree in_decl,
+                        bool integral_constant_expression_p)
+{
+#define RECUR(NODE)                            \
+  tsubst_expr ((NODE), args, complain, in_decl,        \
+              integral_constant_expression_p)
+  tree decl, init, cond, incr;
+
+  init = TREE_VEC_ELT (OMP_FOR_INIT (t), i);
+  gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+  decl = RECUR (TREE_OPERAND (init, 0));
+  init = TREE_OPERAND (init, 1);
+  gcc_assert (!type_dependent_expression_p (decl));
+
+  if (!CLASS_TYPE_P (TREE_TYPE (decl)))
+    {
+      cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
+      incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
+      if (TREE_CODE (incr) == MODIFY_EXPR)
+       incr = build_x_modify_expr (RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR,
+                                   RECUR (TREE_OPERAND (incr, 1)),
+                                   complain);
+      else
+       incr = RECUR (incr);
+      TREE_VEC_ELT (declv, i) = decl;
+      TREE_VEC_ELT (initv, i) = init;
+      TREE_VEC_ELT (condv, i) = cond;
+      TREE_VEC_ELT (incrv, i) = incr;
+      return;
+    }
+
+  if (init && TREE_CODE (init) != DECL_EXPR)
+    {
+      tree c;
+      for (c = *clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+       {
+         if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+             && OMP_CLAUSE_DECL (c) == decl)
+           break;
+         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+                  && OMP_CLAUSE_DECL (c) == decl)
+           error ("iteration variable %qD should not be firstprivate", decl);
+         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+                  && OMP_CLAUSE_DECL (c) == decl)
+           error ("iteration variable %qD should not be reduction", decl);
+       }
+      if (c == NULL)
+       {
+         c = build_omp_clause (OMP_CLAUSE_PRIVATE);
+         OMP_CLAUSE_DECL (c) = decl;
+         c = finish_omp_clauses (c);
+         if (c)
+           {
+             OMP_CLAUSE_CHAIN (c) = *clauses;
+             *clauses = c;
+           }
+       }
+    }
+  cond = TREE_VEC_ELT (OMP_FOR_COND (t), i);
+  if (COMPARISON_CLASS_P (cond))
+    cond = build2 (TREE_CODE (cond), boolean_type_node,
+                  RECUR (TREE_OPERAND (cond, 0)),
+                  RECUR (TREE_OPERAND (cond, 1)));
+  else
+    cond = RECUR (cond);
+  incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
+  switch (TREE_CODE (incr))
+    {
+    case PREINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+      incr = build2 (TREE_CODE (incr), TREE_TYPE (decl),
+                    RECUR (TREE_OPERAND (incr, 0)), NULL_TREE);
+      break;
+    case MODIFY_EXPR:
+      if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+         || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+       {
+         tree rhs = TREE_OPERAND (incr, 1);
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
+                        RECUR (TREE_OPERAND (incr, 0)),
+                        build2 (TREE_CODE (rhs), TREE_TYPE (decl),
+                                RECUR (TREE_OPERAND (rhs, 0)),
+                                RECUR (TREE_OPERAND (rhs, 1))));
+       }
+      else
+       incr = RECUR (incr);
+      break;
+    case MODOP_EXPR:
+      if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+         || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+       {
+         tree lhs = RECUR (TREE_OPERAND (incr, 0));
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl), lhs,
+                        build2 (TREE_CODE (TREE_OPERAND (incr, 1)),
+                                TREE_TYPE (decl), lhs,
+                                RECUR (TREE_OPERAND (incr, 2))));
+       }
+      else if (TREE_CODE (TREE_OPERAND (incr, 1)) == NOP_EXPR
+              && (TREE_CODE (TREE_OPERAND (incr, 2)) == PLUS_EXPR
+                  || (TREE_CODE (TREE_OPERAND (incr, 2)) == MINUS_EXPR)))
+       {
+         tree rhs = TREE_OPERAND (incr, 2);
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
+                        RECUR (TREE_OPERAND (incr, 0)),
+                        build2 (TREE_CODE (rhs), TREE_TYPE (decl),
+                                RECUR (TREE_OPERAND (rhs, 0)),
+                                RECUR (TREE_OPERAND (rhs, 1))));
+       }
+      else
+       incr = RECUR (incr);
+      break;
+    default:
+      incr = RECUR (incr);
+      break;
+    }
+
+  TREE_VEC_ELT (declv, i) = decl;
+  TREE_VEC_ELT (initv, i) = init;
+  TREE_VEC_ELT (condv, i) = cond;
+  TREE_VEC_ELT (incrv, i) = incr;
+#undef RECUR
+}
+
 /* Like tsubst_copy for expressions, etc. but also does semantic
    processing.  */
 
 static tree
-tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
+            bool integral_constant_expression_p)
 {
+#define RECUR(NODE)                            \
+  tsubst_expr ((NODE), args, complain, in_decl,        \
+              integral_constant_expression_p)
+
   tree stmt, tmp;
 
   if (t == NULL_TREE || t == error_mark_node)
@@ -8314,7 +10436,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree_stmt_iterator i;
        for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
-         tsubst_expr (tsi_stmt (i), args, complain, in_decl);
+         RECUR (tsi_stmt (i));
        break;
       }
 
@@ -8324,12 +10446,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case RETURN_EXPR:
-      finish_return_stmt (tsubst_expr (TREE_OPERAND (t, 0),
-                                      args, complain, in_decl));
+      finish_return_stmt (RECUR (TREE_OPERAND (t, 0)));
       break;
 
     case EXPR_STMT:
-      tmp = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
+      tmp = RECUR (EXPR_STMT_EXPR (t));
       if (EXPR_STMT_STMT_EXPR_RESULT (t))
        finish_stmt_expr_expr (tmp, cur_stmt_expr);
       else
@@ -8337,8 +10458,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case USING_STMT:
-      do_using_directive (tsubst_expr (USING_STMT_NAMESPACE (t),
-                                      args, complain, in_decl));
+      do_using_directive (RECUR (USING_STMT_NAMESPACE (t)));
       break;
 
     case DECL_EXPR:
@@ -8355,12 +10475,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            tree name = DECL_NAME (decl);
            tree decl;
 
-           scope = tsubst_expr (scope, args, complain, in_decl);
+           scope = RECUR (scope);
            decl = lookup_qualified_name (scope, name,
                                          /*is_type_p=*/false,
                                          /*complain=*/false);
            if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
-             qualified_name_lookup_error (scope, name, decl);
+             qualified_name_lookup_error (scope, name, decl, input_location);
            else
              do_local_using_decl (decl, scope, name);
          }
@@ -8394,7 +10514,23 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                        init = cp_fname_init (name, &TREE_TYPE (decl));
                      }
                    else
-                     init = tsubst_expr (init, args, complain, in_decl);
+                     {
+                       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);
                  }
              }
@@ -8407,43 +10543,43 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case FOR_STMT:
       stmt = begin_for_stmt ();
-      tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
+                         RECUR (FOR_INIT_STMT (t));
       finish_for_init_stmt (stmt);
-      tmp = tsubst_expr (FOR_COND (t), args, complain, in_decl);
+      tmp = RECUR (FOR_COND (t));
       finish_for_cond (tmp, stmt);
-      tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
+      tmp = RECUR (FOR_EXPR (t));
       finish_for_expr (tmp, stmt);
-      tsubst_expr (FOR_BODY (t), args, complain, in_decl);
+      RECUR (FOR_BODY (t));
       finish_for_stmt (stmt);
       break;
 
     case WHILE_STMT:
       stmt = begin_while_stmt ();
-      tmp = tsubst_expr (WHILE_COND (t), args, complain, in_decl);
+      tmp = RECUR (WHILE_COND (t));
       finish_while_stmt_cond (tmp, stmt);
-      tsubst_expr (WHILE_BODY (t), args, complain, in_decl);
+      RECUR (WHILE_BODY (t));
       finish_while_stmt (stmt);
       break;
 
     case DO_STMT:
       stmt = begin_do_stmt ();
-      tsubst_expr (DO_BODY (t), args, complain, in_decl);
+      RECUR (DO_BODY (t));
       finish_do_body (stmt);
-      tmp = tsubst_expr (DO_COND (t), args, complain, in_decl);
+      tmp = RECUR (DO_COND (t));
       finish_do_stmt (tmp, stmt);
       break;
 
     case IF_STMT:
       stmt = begin_if_stmt ();
-      tmp = tsubst_expr (IF_COND (t), args, complain, in_decl);
+      tmp = RECUR (IF_COND (t));
       finish_if_stmt_cond (tmp, stmt);
-      tsubst_expr (THEN_CLAUSE (t), args, complain, in_decl);
+      RECUR (THEN_CLAUSE (t));
       finish_then_clause (stmt);
 
       if (ELSE_CLAUSE (t))
        {
          begin_else_clause (stmt);
-         tsubst_expr (ELSE_CLAUSE (t), args, complain, in_decl);
+         RECUR (ELSE_CLAUSE (t));
          finish_else_clause (stmt);
        }
 
@@ -8457,7 +10593,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        stmt = begin_compound_stmt (BIND_EXPR_TRY_BLOCK (t)
                                    ? BCS_TRY_BLOCK : 0);
 
-      tsubst_expr (BIND_EXPR_BODY (t), args, complain, in_decl);
+      RECUR (BIND_EXPR_BODY (t));
 
       if (BIND_EXPR_BODY_BLOCK (t))
        finish_function_body (stmt);
@@ -8475,16 +10611,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case SWITCH_STMT:
       stmt = begin_switch_stmt ();
-      tmp = tsubst_expr (SWITCH_STMT_COND (t), args, complain, in_decl);
+      tmp = RECUR (SWITCH_STMT_COND (t));
       finish_switch_cond (tmp, stmt);
-      tsubst_expr (SWITCH_STMT_BODY (t), args, complain, in_decl);
+      RECUR (SWITCH_STMT_BODY (t));
       finish_switch_stmt (stmt);
       break;
 
     case CASE_LABEL_EXPR:
-      finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl),
-                        tsubst_expr (CASE_HIGH (t), args, complain,
-                                     in_decl));
+      finish_case_label (RECUR (CASE_LOW (t)),
+                        RECUR (CASE_HIGH (t)));
       break;
 
     case LABEL_EXPR:
@@ -8497,7 +10632,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        /* Computed goto's must be tsubst'd into.  On the other hand,
           non-computed gotos must not be; the identifier in question
           will have no binding.  */
-       tmp = tsubst_expr (tmp, args, complain, in_decl);
+       tmp = RECUR (tmp);
       else
        tmp = DECL_NAME (tmp);
       finish_goto_stmt (tmp);
@@ -8506,7 +10641,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case ASM_EXPR:
       tmp = finish_asm_stmt
        (ASM_VOLATILE_P (t),
-        tsubst_expr (ASM_STRING (t), args, complain, in_decl),
+        RECUR (ASM_STRING (t)),
         tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
         tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
         tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl));
@@ -8522,11 +10657,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       if (CLEANUP_P (t))
        {
          stmt = begin_try_block ();
-         tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
+         RECUR (TRY_STMTS (t));
          finish_cleanup_try_block (stmt);
-         finish_cleanup (tsubst_expr (TRY_HANDLERS (t), args,
-                                      complain, in_decl),
-                         stmt);
+         finish_cleanup (RECUR (TRY_HANDLERS (t)), stmt);
        }
       else
        {
@@ -8537,14 +10670,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          else
            stmt = begin_try_block ();
 
-         tsubst_expr (TRY_STMTS (t), args, complain, in_decl);
+         RECUR (TRY_STMTS (t));
 
          if (FN_TRY_BLOCK_P (t))
            finish_function_try_block (stmt);
          else
            finish_try_block (stmt);
 
-         tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
+         RECUR (TRY_HANDLERS (t));
          if (FN_TRY_BLOCK_P (t))
            finish_function_handler_sequence (stmt, compound_stmt);
          else
@@ -8567,7 +10700,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          }
        stmt = begin_handler ();
        finish_handler_parms (decl, stmt);
-       tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
+       RECUR (HANDLER_BODY (t));
        finish_handler (stmt);
       }
       break;
@@ -8576,42 +10709,88 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
       break;
 
+    case STATIC_ASSERT:
+      {
+        tree condition = 
+          tsubst_expr (STATIC_ASSERT_CONDITION (t), 
+                       args,
+                       complain, in_decl,
+                       /*integral_constant_expression_p=*/true);
+        finish_static_assert (condition,
+                              STATIC_ASSERT_MESSAGE (t),
+                              STATIC_ASSERT_SOURCE_LOCATION (t),
+                              /*member_p=*/false);
+      }
+      break;
+
     case OMP_PARALLEL:
       tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t),
                                args, complain, in_decl);
       stmt = begin_omp_parallel ();
-      tsubst_expr (OMP_PARALLEL_BODY (t), args, complain, in_decl);
+      RECUR (OMP_PARALLEL_BODY (t));
       OMP_PARALLEL_COMBINED (finish_omp_parallel (tmp, stmt))
        = OMP_PARALLEL_COMBINED (t);
       break;
 
+    case OMP_TASK:
+      tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t),
+                               args, complain, in_decl);
+      stmt = begin_omp_task ();
+      RECUR (OMP_TASK_BODY (t));
+      finish_omp_task (tmp, stmt);
+      break;
+
     case OMP_FOR:
       {
-       tree clauses, decl, init, cond, incr, body, pre_body;
+       tree clauses, body, pre_body;
+       tree declv, initv, condv, incrv;
+       int i;
 
        clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t),
                                      args, complain, in_decl);
-       init = OMP_FOR_INIT (t);
-       gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
-       decl = tsubst_expr (TREE_OPERAND (init, 0), args, complain, in_decl);
-       init = tsubst_expr (TREE_OPERAND (init, 1), args, complain, in_decl);
-       cond = tsubst_expr (OMP_FOR_COND (t), args, complain, in_decl);
-       incr = tsubst_expr (OMP_FOR_INCR (t), args, complain, in_decl);
+       declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+       initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+       condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+       incrv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
+
+       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
+         tsubst_omp_for_iterator (t, i, declv, initv, condv, incrv,
+                                  &clauses, args, complain, in_decl,
+                                  integral_constant_expression_p);
 
        stmt = begin_omp_structured_block ();
 
+       for (i = 0; i < TREE_VEC_LENGTH (initv); i++)
+         if (TREE_VEC_ELT (initv, i) == NULL
+             || TREE_CODE (TREE_VEC_ELT (initv, i)) != DECL_EXPR)
+           TREE_VEC_ELT (initv, i) = RECUR (TREE_VEC_ELT (initv, i));
+         else if (CLASS_TYPE_P (TREE_TYPE (TREE_VEC_ELT (initv, i))))
+           {
+             tree init = RECUR (TREE_VEC_ELT (initv, i));
+             gcc_assert (init == TREE_VEC_ELT (declv, i));
+             TREE_VEC_ELT (initv, i) = NULL_TREE;
+           }
+         else
+           {
+             tree decl_expr = TREE_VEC_ELT (initv, i);
+             tree init = DECL_INITIAL (DECL_EXPR_DECL (decl_expr));
+             gcc_assert (init != NULL);
+             TREE_VEC_ELT (initv, i) = RECUR (init);
+             DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = NULL;
+             RECUR (decl_expr);
+             DECL_INITIAL (DECL_EXPR_DECL (decl_expr)) = init;
+           }
+
        pre_body = push_stmt_list ();
-       tsubst_expr (OMP_FOR_PRE_BODY (t), args, complain, in_decl);
+       RECUR (OMP_FOR_PRE_BODY (t));
        pre_body = pop_stmt_list (pre_body);
 
        body = push_stmt_list ();
-       tsubst_expr (OMP_FOR_BODY (t), args, complain, in_decl);
+       RECUR (OMP_FOR_BODY (t));
        body = pop_stmt_list (body);
 
-       t = finish_omp_for (EXPR_LOCATION (t), decl, init, cond, incr, body,
-                           pre_body);
-       if (t)
-         OMP_FOR_CLAUSES (t) = clauses;
+       t = finish_omp_for (EXPR_LOCATION (t), declv, initv, condv, incrv,
+                           body, pre_body, clauses);
 
        add_stmt (finish_omp_structured_block (stmt));
       }
@@ -8621,7 +10800,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OMP_SINGLE:
       tmp = tsubst_omp_clauses (OMP_CLAUSES (t), args, complain, in_decl);
       stmt = push_stmt_list ();
-      tsubst_expr (OMP_BODY (t), args, complain, in_decl);
+      RECUR (OMP_BODY (t));
       stmt = pop_stmt_list (stmt);
 
       t = copy_node (t);
@@ -8635,7 +10814,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OMP_MASTER:
     case OMP_ORDERED:
       stmt = push_stmt_list ();
-      tsubst_expr (OMP_BODY (t), args, complain, in_decl);
+      RECUR (OMP_BODY (t));
       stmt = pop_stmt_list (stmt);
 
       t = copy_node (t);
@@ -8644,22 +10823,33 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case OMP_ATOMIC:
+      gcc_assert (OMP_ATOMIC_DEPENDENT_P (t));
       {
-       tree op0, op1;
-       op0 = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl);
-       op1 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
-       finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
+       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:
+      error ("invalid use of pack expansion expression");
+      return error_mark_node;
+
+    case NONTYPE_ARGUMENT_PACK:
+      error ("use %<...%> to expand argument pack");
+      return error_mark_node;
+
     default:
       gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
 
       return tsubst_copy_and_build (t, args, complain, in_decl,
-                                   /*function_p=*/false);
+                                   /*function_p=*/false,
+                                   integral_constant_expression_p);
     }
 
   return NULL_TREE;
+#undef RECUR
 }
 
 /* T is a postfix-expression that is not being used in a function
@@ -8675,7 +10865,8 @@ tsubst_non_call_postfix_expression (tree t, tree args,
                             /*done=*/false, /*address_p=*/false);
   else
     t = tsubst_copy_and_build (t, args, complain, in_decl,
-                              /*function_p=*/false);
+                              /*function_p=*/false,
+                              /*integral_constant_expression_p=*/false);
 
   return t;
 }
@@ -8688,10 +10879,13 @@ tsubst_copy_and_build (tree t,
                       tree args,
                       tsubst_flags_t complain,
                       tree in_decl,
-                      bool function_p)
+                      bool function_p,
+                      bool integral_constant_expression_p)
 {
-#define RECUR(NODE) \
-  tsubst_copy_and_build (NODE, args, complain, in_decl, /*function_p=*/false)
+#define RECUR(NODE)                                            \
+  tsubst_copy_and_build (NODE, args, complain, in_decl,        \
+                        /*function_p=*/false,                  \
+                        integral_constant_expression_p)
 
   tree op1;
 
@@ -8726,14 +10920,15 @@ tsubst_copy_and_build (tree t,
 
        decl = finish_id_expression (t, decl, NULL_TREE,
                                     &idk,
-                                    /*integral_constant_expression_p=*/false,
+                                    integral_constant_expression_p,
                                     /*allow_non_integral_constant_expression_p=*/false,
                                     &non_integral_constant_expression_p,
                                     /*template_p=*/false,
                                     /*done=*/true,
                                     /*address_p=*/false,
                                     /*template_arg_p=*/false,
-                                    &error_msg);
+                                    &error_msg,
+                                    input_location);
        if (error_msg)
          error (error_msg);
        if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE)
@@ -8744,26 +10939,26 @@ tsubst_copy_and_build (tree t,
     case TEMPLATE_ID_EXPR:
       {
        tree object;
-       tree template = RECUR (TREE_OPERAND (t, 0));
+       tree templ = RECUR (TREE_OPERAND (t, 0));
        tree targs = TREE_OPERAND (t, 1);
 
        if (targs)
          targs = tsubst_template_args (targs, args, complain, in_decl);
 
-       if (TREE_CODE (template) == COMPONENT_REF)
+       if (TREE_CODE (templ) == COMPONENT_REF)
          {
-           object = TREE_OPERAND (template, 0);
-           template = TREE_OPERAND (template, 1);
+           object = TREE_OPERAND (templ, 0);
+           templ = TREE_OPERAND (templ, 1);
          }
        else
          object = NULL_TREE;
-       template = lookup_template_function (template, targs);
+       templ = lookup_template_function (templ, targs);
 
        if (object)
-         return build3 (COMPONENT_REF, TREE_TYPE (template),
-                        object, template, NULL_TREE);
+         return build3 (COMPONENT_REF, TREE_TYPE (templ),
+                        object, templ, NULL_TREE);
        else
-         return template;
+         return baselink_for_fns (templ);
       }
 
     case INDIRECT_REF:
@@ -8779,7 +10974,7 @@ tsubst_copy_and_build (tree t,
              r = convert_from_reference (r);
          }
        else
-         r = build_x_indirect_ref (r, "unary *");
+         r = build_x_indirect_ref (r, "unary *", complain);
        return r;
       }
 
@@ -8789,35 +10984,48 @@ tsubst_copy_and_build (tree t,
         RECUR (TREE_OPERAND (t, 0)));
 
     case CAST_EXPR:
-      return build_functional_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case REINTERPRET_CAST_EXPR:
-      return build_reinterpret_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case CONST_CAST_EXPR:
-      return build_const_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case DYNAMIC_CAST_EXPR:
-      return build_dynamic_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
-
     case STATIC_CAST_EXPR:
-      return build_static_cast
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0)));
+      {
+       tree type;
+       tree op;
+
+       type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       if (integral_constant_expression_p
+           && !cast_valid_in_integral_constant_expression_p (type))
+         {
+            if (complain & tf_error)
+              error ("a cast to a type other than an integral or "
+                     "enumeration type cannot appear in a constant-expression");
+           return error_mark_node; 
+         }
+
+       op = RECUR (TREE_OPERAND (t, 0));
+
+       switch (TREE_CODE (t))
+         {
+         case CAST_EXPR:
+           return build_functional_cast (type, op, complain);
+         case REINTERPRET_CAST_EXPR:
+           return build_reinterpret_cast (type, op, complain);
+         case CONST_CAST_EXPR:
+           return build_const_cast (type, op, complain);
+         case DYNAMIC_CAST_EXPR:
+           return build_dynamic_cast (type, op, complain);
+         case STATIC_CAST_EXPR:
+           return build_static_cast (type, op, complain);
+         default:
+           gcc_unreachable ();
+         }
+      }
 
     case POSTDECREMENT_EXPR:
     case POSTINCREMENT_EXPR:
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
                                                args, complain, in_decl);
-      return build_x_unary_op (TREE_CODE (t), op1);
+      return build_x_unary_op (TREE_CODE (t), op1, complain);
 
     case PREDECREMENT_EXPR:
     case PREINCREMENT_EXPR:
@@ -8828,7 +11036,8 @@ tsubst_copy_and_build (tree t,
     case UNARY_PLUS_EXPR:  /* Unary + */
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)));
+      return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)),
+                               complain);
 
     case ADDR_EXPR:
       op1 = TREE_OPERAND (t, 0);
@@ -8840,7 +11049,7 @@ tsubst_copy_and_build (tree t,
                                                  in_decl);
       if (TREE_CODE (op1) == LABEL_DECL)
        return finish_label_address_expr (DECL_NAME (op1));
-      return build_x_unary_op (ADDR_EXPR, op1);
+      return build_x_unary_op (ADDR_EXPR, op1, complain);
 
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -8876,8 +11085,15 @@ tsubst_copy_and_build (tree t,
       return build_x_binary_op
        (TREE_CODE (t),
         RECUR (TREE_OPERAND (t, 0)),
+        (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+         ? ERROR_MARK
+         : TREE_CODE (TREE_OPERAND (t, 0))),
         RECUR (TREE_OPERAND (t, 1)),
-        /*overloaded_p=*/NULL);
+        (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+         ? ERROR_MARK
+         : TREE_CODE (TREE_OPERAND (t, 1))),
+        /*overloaded_p=*/NULL,
+        complain);
 
     case SCOPE_REF:
       return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
@@ -8885,10 +11101,22 @@ tsubst_copy_and_build (tree t,
     case ARRAY_REF:
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
                                                args, complain, in_decl);
-      return build_x_binary_op (ARRAY_REF, op1, RECUR (TREE_OPERAND (t, 1)),
-                               /*overloaded_p=*/NULL);
+      return build_x_binary_op (ARRAY_REF, op1,
+                               (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+                                ? ERROR_MARK
+                                : TREE_CODE (TREE_OPERAND (t, 0))),
+                               RECUR (TREE_OPERAND (t, 1)),
+                               (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+                                ? ERROR_MARK
+                                : TREE_CODE (TREE_OPERAND (t, 1))),
+                               /*overloaded_p=*/NULL,
+                               complain);
 
     case SIZEOF_EXPR:
+      if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
+       return tsubst_copy (t, args, complain, in_decl);
+      /* Fall through */
+      
     case ALIGNOF_EXPR:
       op1 = TREE_OPERAND (t, 0);
       if (!args)
@@ -8902,20 +11130,25 @@ tsubst_copy_and_build (tree t,
       else
        {
          ++skip_evaluation;
-         op1 = RECUR (op1);
+         op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
+                                      /*function_p=*/false,
+                                      /*integral_constant_expression_p=*/false);
          --skip_evaluation;
        }
       if (TYPE_P (op1))
-       return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true);
+       return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), 
+                                           complain & tf_error);
       else
-       return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
+       return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t), 
+                                           complain & tf_error);
 
     case MODOP_EXPR:
       {
        tree r = build_x_modify_expr
          (RECUR (TREE_OPERAND (t, 0)),
           TREE_CODE (TREE_OPERAND (t, 1)),
-          RECUR (TREE_OPERAND (t, 2)));
+          RECUR (TREE_OPERAND (t, 2)),
+          complain);
        /* TREE_NO_WARNING must be set if either the expression was
           parenthesized or it uses an operator such as >>= rather
           than plain assignment.  In the former case, it was already
@@ -8936,12 +11169,26 @@ 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 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),
+           complain);
+      }
 
     case DELETE_EXPR:
      return delete_sanity
@@ -8952,7 +11199,8 @@ tsubst_copy_and_build (tree t,
 
     case COMPOUND_EXPR:
       return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)),
-                                   RECUR (TREE_OPERAND (t, 1)));
+                                   RECUR (TREE_OPERAND (t, 1)),
+                                    complain);
 
     case CALL_EXPR:
       {
@@ -8961,7 +11209,7 @@ tsubst_copy_and_build (tree t,
        bool qualified_p;
        bool koenig_p;
 
-       function = TREE_OPERAND (t, 0);
+       function = CALL_EXPR_FN (t);
        /* When we parsed the expression,  we determined whether or
           not Koenig lookup should be performed.  */
        koenig_p = KOENIG_LOOKUP_P (t);
@@ -8987,12 +11235,15 @@ tsubst_copy_and_build (tree t,
 
            function = tsubst_copy_and_build (function, args, complain,
                                              in_decl,
-                                             !qualified_p);
+                                             !qualified_p,
+                                             integral_constant_expression_p);
+
            if (BASELINK_P (function))
              qualified_p = true;
          }
 
-       call_args = RECUR (TREE_OPERAND (t, 1));
+       /* FIXME:  Rewrite this so as not to construct an arglist.  */
+       call_args = RECUR (CALL_EXPR_ARGS (t));
 
        /* We do not perform argument-dependent lookup if normal
           lookup finds a non-function, in accordance with the
@@ -9023,25 +11274,29 @@ tsubst_copy_and_build (tree t,
            if (!BASELINK_P (TREE_OPERAND (function, 1)))
              return finish_call_expr (function, call_args,
                                       /*disallow_virtual=*/false,
-                                      /*koenig_p=*/false);
+                                      /*koenig_p=*/false,
+                                      complain);
            else
              return (build_new_method_call
                      (TREE_OPERAND (function, 0),
                       TREE_OPERAND (function, 1),
                       call_args, NULL_TREE,
                       qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
-                      /*fn_p=*/NULL));
+                      /*fn_p=*/NULL,
+                      complain));
          }
        return finish_call_expr (function, call_args,
                                 /*disallow_virtual=*/qualified_p,
-                                koenig_p);
+                                koenig_p,
+                                complain);
       }
 
     case COND_EXPR:
       return build_x_conditional_expr
        (RECUR (TREE_OPERAND (t, 0)),
         RECUR (TREE_OPERAND (t, 1)),
-        RECUR (TREE_OPERAND (t, 2)));
+        RECUR (TREE_OPERAND (t, 2)),
+         complain);
 
     case PSEUDO_DTOR_EXPR:
       return finish_pseudo_destructor_expr
@@ -9056,6 +11311,69 @@ tsubst_copy_and_build (tree t,
        if (t == void_list_node)
          return t;
 
+        if ((TREE_PURPOSE (t) && PACK_EXPANSION_P (TREE_PURPOSE (t)))
+            || (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))))
+          {
+            /* We have pack expansions, so expand those and
+               create a new list out of it.  */
+            tree purposevec = NULL_TREE;
+            tree valuevec = NULL_TREE;
+            tree chain;
+            int i, len = -1;
+
+            /* Expand the argument expressions.  */
+            if (TREE_PURPOSE (t))
+              purposevec = tsubst_pack_expansion (TREE_PURPOSE (t), args,
+                                                 complain, in_decl);
+            if (TREE_VALUE (t))
+              valuevec = tsubst_pack_expansion (TREE_VALUE (t), args,
+                                               complain, in_decl);
+
+            /* Build the rest of the list.  */
+            chain = TREE_CHAIN (t);
+            if (chain && chain != void_type_node)
+              chain = RECUR (chain);
+
+            /* Determine the number of arguments.  */
+            if (purposevec && TREE_CODE (purposevec) == TREE_VEC)
+              {
+                len = TREE_VEC_LENGTH (purposevec);
+                gcc_assert (!valuevec || len == TREE_VEC_LENGTH (valuevec));
+              }
+            else if (TREE_CODE (valuevec) == TREE_VEC)
+              len = TREE_VEC_LENGTH (valuevec);
+            else
+              {
+                /* Since we only performed a partial substitution into
+                   the argument pack, we only return a single list
+                   node.  */
+                if (purposevec == TREE_PURPOSE (t)
+                    && valuevec == TREE_VALUE (t)
+                    && chain == TREE_CHAIN (t))
+                  return t;
+
+                return tree_cons (purposevec, valuevec, chain);
+              }
+            
+            /* Convert the argument vectors into a TREE_LIST */
+            i = len;
+            while (i > 0)
+              {
+                /* Grab the Ith values.  */
+                i--;
+                purpose = purposevec ? TREE_VEC_ELT (purposevec, i) 
+                                    : NULL_TREE;
+                value 
+                 = valuevec ? convert_from_reference (TREE_VEC_ELT (valuevec, i)) 
+                             : NULL_TREE;
+
+                /* Build the list (backwards).  */
+                chain = tree_cons (purpose, value, chain);
+              }
+
+            return chain;
+          }
+
        purpose = TREE_PURPOSE (t);
        if (purpose)
          purpose = RECUR (purpose);
@@ -9097,15 +11415,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)
@@ -9131,7 +11457,8 @@ tsubst_copy_and_build (tree t,
              }
            else
              {
-               qualified_name_lookup_error (object_type, tmpl, member);
+               qualified_name_lookup_error (object_type, tmpl, member,
+                                            input_location);
                return error_mark_node;
              }
          }
@@ -9154,7 +11481,8 @@ tsubst_copy_and_build (tree t,
          return finish_non_static_data_member (member, object, NULL_TREE);
 
        return finish_class_member_access_expr (object, member,
-                                               /*template_p=*/false);
+                                               /*template_p=*/false,
+                                               complain);
       }
 
     case THROW_EXPR:
@@ -9166,9 +11494,14 @@ tsubst_copy_and_build (tree t,
        VEC(constructor_elt,gc) *n;
        constructor_elt *ce;
        unsigned HOST_WIDE_INT idx;
-       tree r;
        tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
        bool process_index_p;
+        int newlen;
+        bool need_copy_p = false;
+       tree r;
+
+       if (type == error_mark_node)
+         return error_mark_node;
 
        /* digest_init will do the wrong thing if we let it.  */
        if (type && TYPE_PTRMEMFUNC_P (type))
@@ -9177,21 +11510,64 @@ tsubst_copy_and_build (tree t,
        /* We do not want to process the index of aggregate
           initializers as they are identifier nodes which will be
           looked up by digest_init.  */
-       process_index_p = !(type && IS_AGGR_TYPE (type));
+       process_index_p = !(type && MAYBE_CLASS_TYPE_P (type));
 
        n = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t));
+        newlen = VEC_length (constructor_elt, n);
        for (idx = 0; VEC_iterate (constructor_elt, n, idx, ce); idx++)
          {
            if (ce->index && process_index_p)
              ce->index = RECUR (ce->index);
-           ce->value = RECUR (ce->value);
+
+            if (PACK_EXPANSION_P (ce->value))
+              {
+                /* Substitute into the pack expansion.  */
+                ce->value = tsubst_pack_expansion (ce->value, args, complain,
+                                                  in_decl);
+
+               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
+                  {
+                    /* Update the length of the final CONSTRUCTOR
+                       arguments vector, and note that we will need to
+                       copy.*/
+                    newlen = newlen + TREE_VEC_LENGTH (ce->value) - 1;
+                    need_copy_p = true;
+                  }
+              }
+            else
+              ce->value = RECUR (ce->value);
          }
 
-       r = build_constructor (NULL_TREE, n);
-       TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
+        if (need_copy_p)
+          {
+            VEC(constructor_elt,gc) *old_n = n;
+
+            n = VEC_alloc (constructor_elt, gc, newlen);
+            for (idx = 0; VEC_iterate (constructor_elt, old_n, idx, ce); 
+                 idx++)
+              {
+                if (TREE_CODE (ce->value) == TREE_VEC)
+                  {
+                    int i, len = TREE_VEC_LENGTH (ce->value);
+                    for (i = 0; i < len; ++i)
+                      CONSTRUCTOR_APPEND_ELT (n, 0,
+                                              TREE_VEC_ELT (ce->value, i));
+                  }
+                else
+                  CONSTRUCTOR_APPEND_ELT (n, 0, ce->value);
+              }
+          }
+
+       r = build_constructor (init_list_type_node, n);
+
+       if (TREE_HAS_CONSTRUCTOR (t))
+         return finish_compound_literal (type, r);
 
-       if (type)
-         return digest_init (type, r);
        return r;
       }
 
@@ -9227,13 +11603,26 @@ 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;
        tree stmt_expr = begin_stmt_expr ();
 
        cur_stmt_expr = stmt_expr;
-       tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
+       tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl,
+                    integral_constant_expression_p);
        stmt_expr = finish_stmt_expr (stmt_expr, false);
        cur_stmt_expr = old_stmt_expr;
 
@@ -9476,6 +11865,7 @@ fn_type_unification (tree fn,
   tree parms;
   tree fntype;
   int result;
+  bool incomplete_argument_packs_p = false;
 
   gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
 
@@ -9499,16 +11889,16 @@ fn_type_unification (tree fn,
         specified template argument values.  If a substitution in a
         template parameter or in the function type of the function
         template results in an invalid type, type deduction fails.  */
-      int i;
+      tree tparms = DECL_INNERMOST_TEMPLATE_PARMS (fn);
+      int i, len = TREE_VEC_LENGTH (tparms);
       tree converted_args;
-      bool incomplete;
+      bool incomplete = false;
 
       if (explicit_targs == error_mark_node)
        return 1;
 
       converted_args
-       = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
-                                 explicit_targs, NULL_TREE, tf_none,
+       = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, tf_none,
                                  /*require_all_args=*/false,
                                  /*use_default_args=*/false));
       if (converted_args == error_mark_node)
@@ -9520,7 +11910,53 @@ fn_type_unification (tree fn,
         an incomplete set of explicit args, we must not do semantic
         processing during substitution as we could create partial
         instantiations.  */
-      incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
+      for (i = 0; i < len; i++)
+        {
+          tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+          bool parameter_pack = false;
+
+          /* Dig out the actual parm.  */
+          if (TREE_CODE (parm) == TYPE_DECL
+              || TREE_CODE (parm) == TEMPLATE_DECL)
+            {
+              parm = TREE_TYPE (parm);
+              parameter_pack = TEMPLATE_TYPE_PARAMETER_PACK (parm);
+            }
+          else if (TREE_CODE (parm) == PARM_DECL)
+            {
+              parm = DECL_INITIAL (parm);
+              parameter_pack = TEMPLATE_PARM_PARAMETER_PACK (parm);
+            }
+
+          if (parameter_pack)
+            {
+              int level, idx;
+              tree targ;
+              template_parm_level_and_index (parm, &level, &idx);
+
+              /* Mark the argument pack as "incomplete". We could
+                 still deduce more arguments during unification.  */
+              targ = TMPL_ARG (converted_args, level, idx);
+              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;
+            }
+        }
+
+      if (incomplete_argument_packs_p)
+        /* Any substitution is guaranteed to be incomplete if there
+           are incomplete argument packs, because we can still deduce
+           more arguments.  */
+        incomplete = 1;
+      else
+        incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
+
       processing_template_decl += incomplete;
       fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
       processing_template_decl -= incomplete;
@@ -9533,10 +11969,8 @@ fn_type_unification (tree fn,
        TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
     }
 
-  parms = TYPE_ARG_TYPES (fntype);
   /* Never do unification on the 'this' parameter.  */
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
-    parms = TREE_CHAIN (parms);
+  parms = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (fntype));
 
   if (return_type)
     {
@@ -9552,6 +11986,48 @@ fn_type_unification (tree fn,
                                  targs, parms, args, /*subr=*/0,
                                  strict, flags);
 
+  if (result == 0 && incomplete_argument_packs_p)
+    {
+      int i, len = NUM_TMPL_ARGS (targs);
+
+      /* Clear the "incomplete" flags on all argument packs.  */
+      for (i = 0; i < len; i++)
+        {
+          tree arg = TREE_VEC_ELT (targs, i);
+          if (ARGUMENT_PACK_P (arg))
+            {
+              ARGUMENT_PACK_INCOMPLETE_P (arg) = 0;
+              ARGUMENT_PACK_EXPLICIT_ARGS (arg) = 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.  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:
 
@@ -9574,12 +12050,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;
 
@@ -9633,6 +12111,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
@@ -9669,7 +12157,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;
@@ -9707,10 +12195,14 @@ type_unification_real (tree tparms,
   while (parms && parms != void_list_node
         && args && args != void_list_node)
     {
+      if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
+        break;
+
       parm = TREE_VALUE (parms);
       parms = TREE_CHAIN (parms);
       arg = TREE_VALUE (args);
       args = TREE_CHAIN (args);
+      arg_expr = NULL;
 
       if (arg == error_mark_node)
        return 1;
@@ -9747,19 +12239,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;
        }
@@ -9768,13 +12262,49 @@ 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 (arg == init_list_type_node && arg_expr)
+         arg = arg_expr;
        if (unify (tparms, targs, parm, arg, arg_strict))
          return 1;
       }
     }
 
+
+  if (parms 
+      && parms != void_list_node
+      && TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
+    {
+      /* Unify the remaining arguments with the pack expansion type.  */
+      tree argvec;
+      tree parmvec = make_tree_vec (1);
+      int len = 0;
+      tree t;
+
+      /* Count the number of arguments that remain.  */
+      for (t = args; t && t != void_list_node; t = TREE_CHAIN (t))
+        len++;
+        
+      /* Allocate a TREE_VEC and copy in all of the arguments */ 
+      argvec = make_tree_vec (len);
+      for (i = 0; args && args != void_list_node; args = TREE_CHAIN (args))
+        {
+          TREE_VEC_ELT (argvec, i) = TREE_VALUE (args);
+          ++i;
+        }
+
+      /* Copy the parameter into parmvec.  */
+      TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
+      if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict,
+                                /*call_args_p=*/true, /*subr=*/subr))
+        return 1;
+
+      /* Advance to the end of the list of parameters.  */
+      parms = TREE_CHAIN (parms);
+    }
+
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
   if (args && args != void_list_node && parms == void_list_node)
@@ -9788,7 +12318,12 @@ type_unification_real (tree tparms,
     for (i = 0; i < ntparms; i++)
       if (!TREE_VEC_ELT (targs, i))
        {
-         tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+         tree tparm;
+
+          if (TREE_VEC_ELT (tparms, i) == error_mark_node)
+            continue;
+
+          tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
 
          /* If this is an undeduced nontype parameter that depends on
             a type parameter, try another pass; its type may have been
@@ -9799,18 +12334,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,
@@ -9859,6 +12437,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)
@@ -9867,18 +12446,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
@@ -9896,9 +12477,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
@@ -9938,7 +12519,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
@@ -10047,7 +12628,7 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
   tree rval = NULL_TREE;
   tree binfo;
 
-  gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
+  gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (arg)));
 
   binfo = TYPE_BINFO (complete_type (arg));
   if (!binfo)
@@ -10141,6 +12722,259 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
   return 1;
 }
 
+/* Determines the LEVEL and INDEX for the template parameter PARM.  */
+void 
+template_parm_level_and_index (tree parm, int* level, int* index)
+{
+  if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+      || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+      || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+    {
+      *index = TEMPLATE_TYPE_IDX (parm);
+      *level = TEMPLATE_TYPE_LEVEL (parm);
+    }
+  else
+    {
+      *index = TEMPLATE_PARM_IDX (parm);
+      *level = TEMPLATE_PARM_LEVEL (parm);
+    }
+}
+
+/* Unifies the remaining arguments in PACKED_ARGS with the pack
+   expansion at the end of PACKED_PARMS. Returns 0 if the type
+   deduction succeeds, 1 otherwise. STRICT is the same as in
+   unify. CALL_ARGS_P is true iff PACKED_ARGS is actually a function
+   call argument list. We'll need to adjust the arguments to make them
+   types. SUBR tells us if this is from a recursive call to
+   type_unification_real.  */
+int
+unify_pack_expansion (tree tparms, tree targs, tree packed_parms, 
+                      tree packed_args, int strict, bool call_args_p,
+                      bool subr)
+{
+  tree parm 
+    = TREE_VEC_ELT (packed_parms, TREE_VEC_LENGTH (packed_parms) - 1);
+  tree pattern = PACK_EXPANSION_PATTERN (parm);
+  tree pack, packs = NULL_TREE;
+  int i, start = TREE_VEC_LENGTH (packed_parms) - 1;
+  int len = TREE_VEC_LENGTH (packed_args);
+
+  /* Determine the parameter packs we will be deducing from the
+     pattern, and record their current deductions.  */
+  for (pack = PACK_EXPANSION_PARAMETER_PACKS (parm); 
+       pack; pack = TREE_CHAIN (pack))
+    {
+      tree parm_pack = TREE_VALUE (pack);
+      int idx, level;
+
+      /* Determine the index and level of this parameter pack.  */
+      template_parm_level_and_index (parm_pack, &level, &idx);
+
+      /* Keep track of the parameter packs and their corresponding
+         argument packs.  */
+      packs = tree_cons (parm_pack, TMPL_ARG (targs, level, idx), packs);
+      TREE_TYPE (packs) = make_tree_vec (len - start);
+    }
+  
+  /* Loop through all of the arguments that have not yet been
+     unified and unify each with the pattern.  */
+  for (i = start; i < len; i++)
+    {
+      tree parm = pattern;
+
+      /* For each parameter pack, clear out the deduced value so that
+         we can deduce it again.  */
+      for (pack = packs; pack; pack = TREE_CHAIN (pack))
+        {
+          int idx, level;
+          template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+          TMPL_ARG (targs, level, idx) = NULL_TREE;
+        }
+
+      /* 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;
+
+        if (call_args_p)
+          {
+            int sub_strict;
+
+            /* This mirrors what we do in type_unification_real.  */
+            switch (strict)
+              {
+              case DEDUCE_CALL:
+                sub_strict = (UNIFY_ALLOW_OUTER_LEVEL 
+                              | UNIFY_ALLOW_MORE_CV_QUAL
+                              | UNIFY_ALLOW_DERIVED);
+                break;
+                
+              case DEDUCE_CONV:
+                sub_strict = UNIFY_ALLOW_LESS_CV_QUAL;
+                break;
+                
+              case DEDUCE_EXACT:
+                sub_strict = UNIFY_ALLOW_NONE;
+                break;
+                
+              default:
+                gcc_unreachable ();
+              }
+
+            if (!TYPE_P (arg))
+              {
+                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.  */
+
+                    if (resolve_overloaded_unification
+                        (tparms, targs, parm, arg, strict, sub_strict)
+                        != 0)
+                      return 1;
+                    skip_arg_p = true;
+                  }
+
+                if (!skip_arg_p)
+                  {
+                   arg_expr = arg;
+                    arg = unlowered_expr_type (arg);
+                    if (arg == error_mark_node)
+                      return 1;
+                  }
+              }
+      
+            arg_strict = sub_strict;
+
+            if (!subr)
+              arg_strict |= 
+                maybe_adjust_types_for_deduction (strict, &parm, &arg, 
+                                                 arg_expr);
+          }
+
+        if (!skip_arg_p)
+          {
+            if (unify (tparms, targs, parm, arg, arg_strict))
+              return 1;
+          }
+      }
+
+      /* For each parameter pack, collect the deduced value.  */
+      for (pack = packs; pack; pack = TREE_CHAIN (pack))
+        {
+          int idx, level;
+          template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+          TREE_VEC_ELT (TREE_TYPE (pack), i - start) = 
+            TMPL_ARG (targs, level, idx);
+        }
+    }
+
+  /* Verify that the results of unification with the parameter packs
+     produce results consistent with what we've seen before, and make
+     the deduced argument packs available.  */
+  for (pack = packs; pack; pack = TREE_CHAIN (pack))
+    {
+      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))
+        {
+          /* Prepend the explicit arguments onto NEW_ARGS.  */
+          tree explicit_args = ARGUMENT_PACK_EXPLICIT_ARGS (old_pack);
+          tree old_args = new_args;
+          int i, explicit_len = TREE_VEC_LENGTH (explicit_args);
+          int len = explicit_len + TREE_VEC_LENGTH (old_args);
+
+          /* Copy the explicit arguments.  */
+          new_args = make_tree_vec (len);
+          for (i = 0; i < explicit_len; i++)
+            TREE_VEC_ELT (new_args, i) = TREE_VEC_ELT (explicit_args, i);
+
+          /* Copy the deduced arguments.  */
+          for (; i < len; i++)
+            TREE_VEC_ELT (new_args, i) =
+              TREE_VEC_ELT (old_args, i - explicit_len);
+        }
+
+      if (!old_pack)
+        {
+          tree result;
+          int idx, level;
+          
+          template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+          /* Build the deduced *_ARGUMENT_PACK.  */
+          if (TREE_CODE (TREE_PURPOSE (pack)) == TEMPLATE_PARM_INDEX)
+            {
+              result = make_node (NONTYPE_ARGUMENT_PACK);
+              TREE_TYPE (result) = 
+                TREE_TYPE (TEMPLATE_PARM_DECL (TREE_PURPOSE (pack)));
+              TREE_CONSTANT (result) = 1;
+            }
+          else
+            result = make_node (TYPE_ARGUMENT_PACK);
+
+          SET_ARGUMENT_PACK_ARGS (result, new_args);
+
+          /* Note the deduced argument packs for this parameter
+             pack.  */
+          TMPL_ARG (targs, level, idx) = result;
+        }
+      else if (ARGUMENT_PACK_INCOMPLETE_P (old_pack)
+               && (ARGUMENT_PACK_ARGS (old_pack) 
+                   == ARGUMENT_PACK_EXPLICIT_ARGS (old_pack)))
+        {
+          /* We only had the explicitly-provided arguments before, but
+             now we have a complete set of arguments.  */
+          int idx, level;
+          tree explicit_args = ARGUMENT_PACK_EXPLICIT_ARGS (old_pack);
+          template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+          /* Keep the original deduced argument pack.  */
+          TMPL_ARG (targs, level, idx) = old_pack;
+
+          SET_ARGUMENT_PACK_ARGS (old_pack, new_args);
+          ARGUMENT_PACK_INCOMPLETE_P (old_pack) = 1;
+          ARGUMENT_PACK_EXPLICIT_ARGS (old_pack) = explicit_args;
+        }
+      else if (!comp_template_args (ARGUMENT_PACK_ARGS (old_pack),
+                                    new_args))
+        /* Inconsistent unification of this parameter pack.  */
+        return 1;
+      else
+        {
+          int idx, level;
+          
+          template_parm_level_and_index (TREE_PURPOSE (pack), &level, &idx);
+
+          /* Keep the original deduced argument pack.  */
+          TMPL_ARG (targs, level, idx) = old_pack;
+        }
+    }
+
+  return 0;
+}
+
 /* Deduce the value of template parameters.  TPARMS is the (innermost)
    set of template parameters to a template.  TARGS is the bindings
    for those template parameters, as determined thus far; TARGS may
@@ -10199,7 +13033,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
   if (arg == error_mark_node)
     return 1;
-  if (arg == unknown_type_node)
+  if (arg == unknown_type_node
+      || arg == init_list_type_node)
     /* We can't deduce anything from this, but we might get all the
        template args from other function args.  */
     return 0;
@@ -10211,6 +13046,31 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
   if (arg == parm && !uses_template_parms (parm))
     return 0;
 
+  /* Handle init lists early, so the rest of the function can assume
+     we're dealing with a type. */
+  if (BRACE_ENCLOSED_INITIALIZER_P (arg))
+    {
+      tree elt, elttype;
+      unsigned i;
+
+      if (!is_std_init_list (parm))
+       /* We can only deduce from an initializer list argument if the
+          parameter is std::initializer_list; otherwise this is a
+          non-deduced context. */
+       return 0;
+
+      elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+
+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+       {
+         if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+           elt = TREE_TYPE (elt);
+         if (unify (tparms, targs, elttype, elt, UNIFY_ALLOW_NONE))
+           return 1;
+       }
+      return 0;
+    }
+
   /* Immediately reject some pairs that won't unify because of
      cv-qualification mismatches.  */
   if (TREE_CODE (arg) == TREE_CODE (parm)
@@ -10249,6 +13109,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))
@@ -10278,9 +13140,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          {
            tree parmvec = TYPE_TI_ARGS (parm);
            tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
-           tree argtmplvec
-             = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
-           int i;
+           tree parm_parms 
+              = DECL_INNERMOST_TEMPLATE_PARMS
+                 (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm));
+           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
@@ -10309,7 +13173,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
              Here, if Lvalue_proxy is permitted to bind to View, then
              the global operator+ will be used; if they are not, the
              Lvalue_proxy will be converted to float.  */
-           if (coerce_template_parms (argtmplvec, parmvec,
+           if (coerce_template_parms (parm_parms,
+                                       argvec,
                                       TYPE_TI_TEMPLATE (parm),
                                       tf_none,
                                       /*require_all_args=*/true,
@@ -10322,7 +13187,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),
@@ -10330,6 +13209,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);
 
@@ -10381,6 +13268,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            return 1;
        }
 
+      /* If ARG is a parameter pack or an expansion, we cannot unify
+        against it unless PARM is also a parameter pack.  */
+      if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
+         && !template_parameter_pack_p (parm))
+       return 1;
+
       TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return 0;
 
@@ -10431,6 +13324,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       else
        return 1;
 
+      /* If ARG is a parameter pack or an expansion, we cannot unify
+        against it unless PARM is also a parameter pack.  */
+      if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
+         && !TEMPLATE_PARM_PARAMETER_PACK (parm))
+       return 1;
+
       TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return 0;
 
@@ -10495,21 +13394,56 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
        {
          tree parm_max;
          tree arg_max;
-
-         parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
-         arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
+         bool parm_cst;
+         bool arg_cst;
 
          /* Our representation of array types uses "N - 1" as the
             TYPE_MAX_VALUE for an array with "N" elements, if "N" is
-            not an integer constant.  */
-         if (TREE_CODE (parm_max) == MINUS_EXPR)
+            not an integer constant.  We cannot unify arbitrarily
+            complex expressions, so we eliminate the MINUS_EXPRs
+            here.  */
+         parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
+         parm_cst = TREE_CODE (parm_max) == INTEGER_CST;
+         if (!parm_cst)
            {
-             arg_max = fold_build2 (PLUS_EXPR,
-                                    integer_type_node,
-                                    arg_max,
-                                    TREE_OPERAND (parm_max, 1));
+             gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR);
              parm_max = TREE_OPERAND (parm_max, 0);
            }
+         arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
+         arg_cst = TREE_CODE (arg_max) == INTEGER_CST;
+         if (!arg_cst)
+           {
+             /* The ARG_MAX may not be a simple MINUS_EXPR, if we are
+                trying to unify the type of a variable with the type
+                of a template parameter.  For example:
+
+                   template <unsigned int N>
+                  void f (char (&) [N]);
+                  int g(); 
+                  void h(int i) {
+                     char a[g(i)];
+                    f(a); 
+                   }
+
+                Here, the type of the ARG will be "int [g(i)]", and
+                may be a SAVE_EXPR, etc.  */
+             if (TREE_CODE (arg_max) != MINUS_EXPR)
+               return 1;
+             arg_max = TREE_OPERAND (arg_max, 0);
+           }
+
+         /* If only one of the bounds used a MINUS_EXPR, compensate
+            by adding one to the other bound.  */
+         if (parm_cst && !arg_cst)
+           parm_max = fold_build2 (PLUS_EXPR,
+                                   integer_type_node,
+                                   parm_max,
+                                   integer_one_node);
+         else if (arg_cst && !parm_cst)
+           arg_max = fold_build2 (PLUS_EXPR,
+                                  integer_type_node,
+                                  arg_max,
+                                  integer_one_node);
 
          if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER))
            return 1;
@@ -10629,7 +13563,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       /* CV qualifications for methods can never be deduced, they must
         match exactly.  We need to check them explicitly here,
         because type_unification_real treats them as any other
-        cvqualified parameter.  */
+        cv-qualified parameter.  */
       if (TREE_CODE (parm) == METHOD_TYPE
          && (!check_cv_quals_for_unify
              (UNIFY_ALLOW_NONE,
@@ -10696,6 +13630,69 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       /* Matched cases are handled by the ARG == PARM test above.  */
       return 1;
 
+    case TYPE_ARGUMENT_PACK:
+    case NONTYPE_ARGUMENT_PACK:
+      {
+        tree packed_parms = ARGUMENT_PACK_ARGS (parm);
+        tree packed_args = ARGUMENT_PACK_ARGS (arg);
+        int i, len = TREE_VEC_LENGTH (packed_parms);
+        int argslen = TREE_VEC_LENGTH (packed_args);
+        int parm_variadic_p = 0;
+
+       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
+           too many arguments for a parameter list that doesn't end in
+           a pack expression, we can't unify.  */
+        if (argslen < (len - parm_variadic_p)
+            || (argslen > len && !parm_variadic_p))
+          return 1;
+
+        /* Unify all of the parameters that precede the (optional)
+           pack expression.  */
+        for (i = 0; i < len - parm_variadic_p; ++i)
+          {
+            if (unify (tparms, targs, TREE_VEC_ELT (packed_parms, i),
+                       TREE_VEC_ELT (packed_args, i), strict))
+              return 1;
+          }
+
+        if (parm_variadic_p)
+          return unify_pack_expansion (tparms, targs, 
+                                       packed_parms, packed_args,
+                                       strict, /*call_args_p=*/false,
+                                       /*subr=*/false);
+        return 0;
+      }
+
+      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));
 
@@ -10858,7 +13855,9 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
   processing_template_decl++;
 
-  while (len--)
+  while (len--
+        /* Stop when an ellipsis is seen.  */
+        && args1 != NULL_TREE && args2 != NULL_TREE)
     {
       tree arg1 = TREE_VALUE (args1);
       tree arg2 = TREE_VALUE (args2);
@@ -10866,6 +13865,18 @@ more_specialized_fn (tree pat1, tree pat2, int len)
       int quals1 = -1;
       int quals2 = -1;
 
+      if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION
+          && TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
+        {
+          /* When both arguments are pack expansions, we need only
+             unify the patterns themselves.  */
+          arg1 = PACK_EXPANSION_PATTERN (arg1);
+          arg2 = PACK_EXPANSION_PATTERN (arg2);
+
+          /* This is the last comparison we need to do.  */
+          len = 0;
+        }
+
       if (TREE_CODE (arg1) == REFERENCE_TYPE)
        {
          arg1 = TREE_TYPE (arg1);
@@ -10921,8 +13932,62 @@ more_specialized_fn (tree pat1, tree pat2, int len)
       arg1 = TYPE_MAIN_VARIANT (arg1);
       arg2 = TYPE_MAIN_VARIANT (arg2);
 
-      deduce1 = !unify (tparms1, targs1, arg1, arg2, UNIFY_ALLOW_NONE);
-      deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE);
+      if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION)
+        {
+          int i, len2 = list_length (args2);
+          tree parmvec = make_tree_vec (1);
+          tree argvec = make_tree_vec (len2);
+          tree ta = args2;
+
+          /* Setup the parameter vector, which contains only ARG1.  */
+          TREE_VEC_ELT (parmvec, 0) = arg1;
+
+          /* Setup the argument vector, which contains the remaining
+             arguments.  */
+          for (i = 0; i < len2; i++, ta = TREE_CHAIN (ta))
+            TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta);
+
+          deduce1 = !unify_pack_expansion (tparms1, targs1, parmvec, 
+                                          argvec, UNIFY_ALLOW_NONE, 
+                                           /*call_args_p=*/false, 
+                                          /*subr=*/0);
+
+          /* We cannot deduce in the other direction, because ARG1 is
+             a pack expansion but ARG2 is not.  */
+          deduce2 = 0;
+        }
+      else if (TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
+        {
+          int i, len1 = list_length (args1);
+          tree parmvec = make_tree_vec (1);
+          tree argvec = make_tree_vec (len1);
+          tree ta = args1;
+
+          /* Setup the parameter vector, which contains only ARG1.  */
+          TREE_VEC_ELT (parmvec, 0) = arg2;
+
+          /* Setup the argument vector, which contains the remaining
+             arguments.  */
+          for (i = 0; i < len1; i++, ta = TREE_CHAIN (ta))
+            TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta);
+
+          deduce2 = !unify_pack_expansion (tparms2, targs2, parmvec, 
+                                          argvec, UNIFY_ALLOW_NONE, 
+                                           /*call_args_p=*/false, 
+                                          /*subr=*/0);
+
+          /* We cannot deduce in the other direction, because ARG2 is
+             a pack expansion but ARG1 is not.*/
+          deduce1 = 0;
+        }
+
+      else
+        {
+          /* The normal case, where neither argument is a pack
+             expansion.  */
+          deduce1 = !unify (tparms1, targs1, arg1, arg2, UNIFY_ALLOW_NONE);
+          deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE);
+        }
 
       if (!deduce1)
        better2 = -1;
@@ -10947,12 +14012,31 @@ more_specialized_fn (tree pat1, tree pat2, int len)
       if (deduce2 && !deduce1 && !better1)
        better1 = 1;
 
+      if (TREE_CODE (arg1) == TYPE_PACK_EXPANSION
+          || TREE_CODE (arg2) == TYPE_PACK_EXPANSION)
+        /* We have already processed all of the arguments in our
+           handing of the pack expansion type.  */
+        len = 0;
+
       args1 = TREE_CHAIN (args1);
       args2 = TREE_CHAIN (args2);
     }
 
   processing_template_decl--;
 
+  /* All things being equal, if the next argument is a pack expansion
+     for one function but not for the other, prefer the
+     non-variadic function.  */
+  if ((better1 > 0) - (better2 > 0) == 0
+      && args1 && TREE_VALUE (args1)
+      && args2 && TREE_VALUE (args2))
+    {
+      if (TREE_CODE (TREE_VALUE (args1)) == TYPE_PACK_EXPANSION)
+        return TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION ? 0 : -1;
+      else if (TREE_CODE (TREE_VALUE (args2)) == TYPE_PACK_EXPANSION)
+        return 1;
+    }
+
   return (better1 > 0) - (better2 > 0);
 }
 
@@ -10976,6 +14060,7 @@ more_specialized_class (tree pat1, tree pat2)
   tree targs;
   tree tmpl1, tmpl2;
   int winner = 0;
+  bool any_deductions = false;
 
   tmpl1 = TREE_TYPE (pat1);
   tmpl2 = TREE_TYPE (pat2);
@@ -10989,15 +14074,46 @@ more_specialized_class (tree pat1, tree pat2)
                              CLASSTYPE_TI_ARGS (tmpl1),
                              CLASSTYPE_TI_ARGS (tmpl2));
   if (targs)
-    --winner;
+    {
+      --winner;
+      any_deductions = true;
+    }
 
   targs = get_class_bindings (TREE_VALUE (pat2),
                              CLASSTYPE_TI_ARGS (tmpl2),
                              CLASSTYPE_TI_ARGS (tmpl1));
   if (targs)
-    ++winner;
+    {
+      ++winner;
+      any_deductions = true;
+    }
   --processing_template_decl;
 
+  /* In the case of a tie where at least one of the class templates
+     has a parameter pack at the end, the template with the most
+     non-packed parameters wins.  */
+  if (winner == 0
+      && any_deductions
+      && (template_args_variadic_p (TREE_PURPOSE (pat1))
+          || template_args_variadic_p (TREE_PURPOSE (pat2))))
+    {
+      tree args1 = INNERMOST_TEMPLATE_ARGS (TREE_PURPOSE (pat1));
+      tree args2 = INNERMOST_TEMPLATE_ARGS (TREE_PURPOSE (pat2));
+      int len1 = TREE_VEC_LENGTH (args1);
+      int len2 = TREE_VEC_LENGTH (args2);
+
+      /* We don't count the pack expansion at the end.  */
+      if (template_args_variadic_p (TREE_PURPOSE (pat1)))
+        --len1;
+      if (template_args_variadic_p (TREE_PURPOSE (pat2)))
+        --len2;
+
+      if (len1 > len2)
+        return 1;
+      else if (len1 < len2)
+        return -1;
+    }
+
   return winner;
 }
 
@@ -11044,10 +14160,9 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
        return NULL_TREE;
     }
 
-  decl_arg_types = TYPE_ARG_TYPES (decl_type);
   /* Never do unification on the 'this' parameter.  */
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
-    decl_arg_types = TREE_CHAIN (decl_arg_types);
+  decl_arg_types = skip_artificial_parms_for (decl, 
+                                             TYPE_ARG_TYPES (decl_type));
 
   if (fn_type_unification (fn, explicit_args, targs,
                           decl_arg_types,
@@ -11122,6 +14237,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;
 }
 
@@ -11273,20 +14396,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);
        }
@@ -11372,12 +14532,24 @@ 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)
        {
          error ("no matching template for %qD found", decl);
          return;
        }
+      if (!same_type_p (TREE_TYPE (result), TREE_TYPE (decl)))
+       {
+         error ("type %qT for explicit instantiation %qD does not match "
+                "declared type %qT", TREE_TYPE (result), decl,
+                TREE_TYPE (decl));
+         return;
+       }
     }
   else if (TREE_CODE (decl) != FUNCTION_DECL)
     {
@@ -11417,7 +14589,7 @@ do_decl_instantiation (tree decl, tree storage)
         the first instantiation was `extern' and the second is not,
         and EXTERN_P for the opposite case.  */
       if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
-       pedwarn ("duplicate explicit instantiation of %q#D", result);
+       permerror ("duplicate explicit instantiation of %q#D", result);
       /* If an "extern" explicit instantiation follows an ordinary
         explicit instantiation, the template is instantiated.  */
       if (extern_p)
@@ -11430,7 +14602,7 @@ do_decl_instantiation (tree decl, tree storage)
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      pedwarn ("explicit instantiation of non-template %q#D", result);
+      permerror ("explicit instantiation of non-template %q#D", result);
       return;
     }
 
@@ -11438,8 +14610,8 @@ do_decl_instantiation (tree decl, tree storage)
     ;
   else if (storage == ridpointers[(int) RID_EXTERN])
     {
-      if (pedantic && !in_system_header)
-       pedwarn ("ISO C++ forbids the use of %<extern%> on explicit "
+      if (pedantic && !in_system_header && (cxx_dialect == cxx98))
+       pedwarn ("ISO C++ 1998 forbids the use of %<extern%> on explicit "
                 "instantiations");
       extern_p = 1;
     }
@@ -11474,7 +14646,7 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
 {
   tree storage = *(tree *) data;
 
-  if (IS_AGGR_TYPE (entry->type)
+  if (MAYBE_CLASS_TYPE_P (entry->type)
       && !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
     do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
 }
@@ -11526,8 +14698,17 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
   if (storage != NULL_TREE)
     {
       if (pedantic && !in_system_header)
-       pedwarn("ISO C++ forbids the use of %qE on explicit instantiations",
-               storage);
+       {
+         if (storage == ridpointers[(int) RID_EXTERN])
+           {
+             if (cxx_dialect == cxx98)
+               pedwarn("ISO C++ 1998 forbids the use of %<extern%> on "
+                       "explicit instantiations");
+           }
+         else
+           pedwarn("ISO C++ forbids the use of %qE on explicit "
+                   "instantiations", storage);
+       }
 
       if (storage == ridpointers[(int) RID_INLINE])
        nomem_p = 1;
@@ -11571,7 +14752,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
 
       if (!previous_instantiation_extern_p && !extern_p
          && (complain & tf_error))
-       pedwarn ("duplicate explicit instantiation of %q#T", t);
+       permerror ("duplicate explicit instantiation of %q#T", t);
 
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
@@ -11680,11 +14861,11 @@ regenerate_decl_from_template (tree decl, tree tmpl)
       pattern_parm
        = skip_artificial_parms_for (code_pattern,
                                     DECL_ARGUMENTS (code_pattern));
-      while (decl_parm)
+      while (decl_parm && !FUNCTION_PARAMETER_PACK_P (pattern_parm))
        {
          tree parm_type;
          tree attributes;
-
+          
          if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
            DECL_NAME (decl_parm) = DECL_NAME (pattern_parm);
          parm_type = tsubst (TREE_TYPE (pattern_parm), args, tf_error,
@@ -11701,7 +14882,39 @@ regenerate_decl_from_template (tree decl, tree tmpl)
          decl_parm = TREE_CHAIN (decl_parm);
          pattern_parm = TREE_CHAIN (pattern_parm);
        }
-
+      /* Merge any parameters that match with the function parameter
+         pack.  */
+      if (pattern_parm && FUNCTION_PARAMETER_PACK_P (pattern_parm))
+        {
+          int i, len;
+          tree expanded_types;
+          /* Expand the TYPE_PACK_EXPANSION that provides the types for
+             the parameters in this function parameter pack.  */
+          expanded_types = tsubst_pack_expansion (TREE_TYPE (pattern_parm), 
+                                                 args, tf_error, NULL_TREE);
+          len = TREE_VEC_LENGTH (expanded_types);
+          for (i = 0; i < len; i++)
+            {
+              tree parm_type;
+              tree attributes;
+          
+              if (DECL_NAME (decl_parm) != DECL_NAME (pattern_parm))
+                /* Rename the parameter to include the index.  */
+                DECL_NAME (decl_parm) = 
+                  make_ith_pack_parameter_name (DECL_NAME (pattern_parm), i);
+              parm_type = TREE_VEC_ELT (expanded_types, i);
+              parm_type = type_decays_to (parm_type);
+              if (!same_type_p (TREE_TYPE (decl_parm), parm_type))
+                TREE_TYPE (decl_parm) = parm_type;
+              attributes = DECL_ATTRIBUTES (pattern_parm);
+              if (DECL_ATTRIBUTES (decl_parm) != attributes)
+                {
+                  DECL_ATTRIBUTES (decl_parm) = attributes;
+                  cplus_decl_attributes (&decl_parm, attributes, /*flags=*/0);
+                }
+              decl_parm = TREE_CHAIN (decl_parm);
+            }
+        }
       /* Merge additional specifiers from the CODE_PATTERN.  */
       if (DECL_DECLARED_INLINE_P (code_pattern)
          && !DECL_DECLARED_INLINE_P (decl))
@@ -11712,7 +14925,8 @@ regenerate_decl_from_template (tree decl, tree tmpl)
   else if (TREE_CODE (decl) == VAR_DECL)
     DECL_INITIAL (decl) =
       tsubst_expr (DECL_INITIAL (code_pattern), args,
-                  tf_error, DECL_TI_TEMPLATE (decl));
+                  tf_error, DECL_TI_TEMPLATE (decl),
+                  /*integral_constant_expression_p=*/false);
   else
     gcc_unreachable ();
 
@@ -11907,8 +15121,8 @@ instantiate_decl (tree d, int defer_ok,
       if (TREE_CODE (gen) == FUNCTION_DECL)
        {
          tsubst (DECL_ARGUMENTS (gen), gen_args, tf_warning_or_error, d);
-         tsubst (TYPE_RAISES_EXCEPTIONS (type), gen_args,
-                 tf_warning_or_error, d);
+          tsubst_exception_specification (type, gen_args, tf_warning_or_error,
+                                          d);
          /* Don't simply tsubst the function type, as that will give
             duplicate warnings about poor parameter qualifications.
             The function arguments are the same as the decl_arguments
@@ -11961,7 +15175,8 @@ instantiate_decl (tree d, int defer_ok,
          push_nested_class (DECL_CONTEXT (d));
          init = tsubst_expr (DECL_INITIAL (code_pattern),
                              args,
-                             tf_warning_or_error, NULL_TREE);
+                             tf_warning_or_error, NULL_TREE,
+                             /*integral_constant_expression_p=*/false);
          cp_finish_decl (d, init, /*init_const_expr_p=*/false,
                          /*asmspec_tree=*/NULL_TREE,
                          LOOKUP_ONLYCONVERTING);
@@ -11982,7 +15197,7 @@ instantiate_decl (tree d, int defer_ok,
           member function or static data member of a class template
           shall be present in every translation unit in which it is
           explicitly instantiated.  */
-       pedwarn
+       permerror
          ("explicit instantiation of %qD but no definition available", d);
 
       /* ??? Historically, we have instantiated inline functions, even
@@ -12082,17 +15297,56 @@ instantiate_decl (tree d, int defer_ok,
          spec_parm = skip_artificial_parms_for (d, spec_parm);
          tmpl_parm = skip_artificial_parms_for (subst_decl, tmpl_parm);
        }
-      while (tmpl_parm)
+      while (tmpl_parm && !FUNCTION_PARAMETER_PACK_P (tmpl_parm))
        {
          register_local_specialization (spec_parm, tmpl_parm);
          tmpl_parm = TREE_CHAIN (tmpl_parm);
          spec_parm = TREE_CHAIN (spec_parm);
        }
+      if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm))
+        {
+          /* Collect all of the extra "packed" parameters into an
+             argument pack.  */
+          tree parmvec;
+          tree parmtypevec;
+          tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
+          tree argtypepack = make_node (TYPE_ARGUMENT_PACK);
+          int i, len = 0;
+          tree t;
+          
+          /* Count how many parameters remain.  */
+          for (t = spec_parm; t; t = TREE_CHAIN (t))
+            len++;
+
+          /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters.  */
+          parmvec = make_tree_vec (len);
+          parmtypevec = make_tree_vec (len);
+          for(i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm))
+            {
+              TREE_VEC_ELT (parmvec, i) = spec_parm;
+              TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm);
+            }
+
+          /* Build the argument packs.  */
+          SET_ARGUMENT_PACK_ARGS (argpack, parmvec);
+          SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec);
+          TREE_TYPE (argpack) = argtypepack;
+          
+          /* Register the (value) argument pack as a specialization of
+             TMPL_PARM, then move on.  */
+          register_local_specialization (argpack, tmpl_parm);
+          tmpl_parm = TREE_CHAIN (tmpl_parm);
+        }
       gcc_assert (!spec_parm);
 
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
-                  tf_warning_or_error, tmpl);
+                  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);
@@ -12126,18 +15380,15 @@ 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;
 
   /* Instantiating templates may trigger vtable generation.  This in turn
      may require further template instantiations.  We place a limit here
      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"
@@ -12151,14 +15402,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))
            {
@@ -12179,15 +15429,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
            {
@@ -12202,26 +15444,27 @@ 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;
     }
   while (reconsider);
 
   input_location = saved_loc;
-  in_system_header = saved_in_system_header;
 }
 
 /* Substitute ARGVEC into T, which is a list of initializers for
@@ -12238,23 +15481,113 @@ tsubst_initializer_list (tree t, tree argvec)
     {
       tree decl;
       tree init;
+      tree expanded_bases = NULL_TREE;
+      tree expanded_arguments = NULL_TREE;
+      int i, len = 1;
 
-      decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_warning_or_error,
-                         NULL_TREE);
-      decl = expand_member_init (decl);
-      if (decl && !DECL_P (decl))
-       in_base_initializer = 1;
+      if (TREE_CODE (TREE_PURPOSE (t)) == TYPE_PACK_EXPANSION)
+        {
+          tree expr;
+          tree arg;
+
+          /* Expand the base class expansion type into separate base
+             classes.  */
+          expanded_bases = tsubst_pack_expansion (TREE_PURPOSE (t), argvec,
+                                                 tf_warning_or_error,
+                                                 NULL_TREE);
+          if (expanded_bases == error_mark_node)
+            continue;
+          
+          /* We'll be building separate TREE_LISTs of arguments for
+             each base.  */
+          len = TREE_VEC_LENGTH (expanded_bases);
+          expanded_arguments = make_tree_vec (len);
+          for (i = 0; i < len; i++)
+            TREE_VEC_ELT (expanded_arguments, i) = NULL_TREE;
+
+          /* Build a dummy EXPR_PACK_EXPANSION that will be used to
+             expand each argument in the TREE_VALUE of t.  */
+          expr = make_node (EXPR_PACK_EXPANSION);
+          PACK_EXPANSION_PARAMETER_PACKS (expr) =
+            PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
+
+         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);
+                 if (expanded_exprs == error_mark_node)
+                   continue;
+
+                 /* 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;
 
-      init = tsubst_expr (TREE_VALUE (t), argvec, tf_warning_or_error,
-                         NULL_TREE);
-      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));
+               }
+           }
+        }
 
-      if (decl)
-       {
-         init = build_tree_list (decl, init);
-         TREE_CHAIN (init) = inits;
-         inits = init;
-       }
+      for (i = 0; i < len; ++i)
+        {
+          if (expanded_bases)
+            {
+              decl = TREE_VEC_ELT (expanded_bases, i);
+              decl = expand_member_init (decl);
+              init = TREE_VEC_ELT (expanded_arguments, i);
+            }
+          else
+            {
+              decl = tsubst_copy (TREE_PURPOSE (t), argvec, 
+                                  tf_warning_or_error, NULL_TREE);
+
+              decl = expand_member_init (decl);
+              if (decl && !DECL_P (decl))
+                in_base_initializer = 1;
+
+              init = tsubst_expr (TREE_VALUE (t), argvec, 
+                                 tf_warning_or_error, NULL_TREE,
+                                  /*integral_constant_expression_p=*/false);
+              in_base_initializer = 0;
+            }
+
+          if (decl)
+            {
+              init = build_tree_list (decl, init);
+              TREE_CHAIN (init) = inits;
+              inits = init;
+            }
+        }
     }
   return inits;
 }
@@ -12290,7 +15623,8 @@ tsubst_enum (tree tag, tree newtag, tree args)
       /* Note that in a template enum, the TREE_VALUE is the
         CONST_DECL, not the corresponding INTEGER_CST.  */
       value = tsubst_expr (DECL_INITIAL (decl),
-                          args, tf_warning_or_error, NULL_TREE);
+                          args, tf_warning_or_error, NULL_TREE,
+                          /*integral_constant_expression_p=*/true);
 
       /* Give this enumeration constant the correct access.  */
       set_current_access_from_decl (decl);
@@ -12386,7 +15720,7 @@ record_last_problematic_instantiation (void)
   last_template_error_tick = tinst_level_tick;
 }
 
-tree
+struct tinst_level *
 current_instantiation (void)
 {
   return current_tinst_level;
@@ -12469,13 +15803,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 ...  */
@@ -12488,10 +15827,27 @@ 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
+     arguments are.  */
+  if (TREE_CODE (type) == TYPE_ARGUMENT_PACK)
+    {
+      tree args = ARGUMENT_PACK_ARGS (type);
+      int i, len = TREE_VEC_LENGTH (args);
+      for (i = 0; i < len; ++i)
+        if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
+          return true;
+    }
+
+  /* All TYPE_PACK_EXPANSIONs are dependent, because parameter packs must
+     be template parameters.  */
+  if (TREE_CODE (type) == TYPE_PACK_EXPANSION)
     return true;
 
   /* The standard does not specifically mention types that are local
@@ -12614,7 +15970,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
@@ -12652,12 +16008,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);
       }
@@ -12665,9 +16016,11 @@ value_dependent_expression_p (tree expression)
     case SIZEOF_EXPR:
     case ALIGNOF_EXPR:
       /* A `sizeof' expression is value-dependent if the operand is
-        type-dependent.  */
+        type-dependent or is a pack expansion.  */
       expression = TREE_OPERAND (expression, 0);
-      if (TYPE_P (expression))
+      if (PACK_EXPANSION_P (expression))
+        return true;
+      else if (TYPE_P (expression))
        return dependent_type_p (expression);
       return type_dependent_expression_p (expression);
 
@@ -12684,6 +16037,31 @@ value_dependent_expression_p (tree expression)
         such calls are value-dependent.  */
       return true;
 
+    case NONTYPE_ARGUMENT_PACK:
+      /* A NONTYPE_ARGUMENT_PACK is value-dependent if any packed argument
+         is value-dependent.  */
+      {
+        tree values = ARGUMENT_PACK_ARGS (expression);
+        int i, len = TREE_VEC_LENGTH (values);
+        
+        for (i = 0; i < len; ++i)
+          if (value_dependent_expression_p (TREE_VEC_ELT (values, i)))
+            return true;
+        
+        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.  */
@@ -12702,9 +16080,10 @@ value_dependent_expression_p (tree expression)
                      (TREE_OPERAND (expression, 1))));
 
        case tcc_expression:
+       case tcc_vl_exp:
          {
            int i;
-           for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (expression)); ++i)
+           for (i = 0; i < TREE_OPERAND_LENGTH (expression); ++i)
              /* In some cases, some of the operands may be missing.
                 (For example, in the case of PREDECREMENT_EXPR, the
                 amount to increment by may be missing.)  That doesn't
@@ -12738,13 +16117,15 @@ type_dependent_expression_p (tree expression)
     return false;
 
   /* An unresolved name is always dependent.  */
-  if (TREE_CODE (expression) == IDENTIFIER_NODE)
+  if (TREE_CODE (expression) == IDENTIFIER_NODE
+      || TREE_CODE (expression) == USING_DECL)
     return true;
 
   /* Some expression forms are never type-dependent.  */
   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
@@ -12795,6 +16176,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)
@@ -12843,7 +16227,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)
     {
@@ -12856,9 +16240,22 @@ 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.  */
 
-static bool
+bool
 dependent_template_arg_p (tree arg)
 {
   if (!processing_template_decl)
@@ -12867,6 +16264,18 @@ dependent_template_arg_p (tree arg)
   if (TREE_CODE (arg) == TEMPLATE_DECL
       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
     return dependent_template_p (arg);
+  else if (ARGUMENT_PACK_P (arg))
+    {
+      tree args = ARGUMENT_PACK_ARGS (arg);
+      int i, len = TREE_VEC_LENGTH (args);
+      for (i = 0; i < len; ++i)
+        {
+          if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
+            return true;
+        }
+
+      return false;
+    }
   else if (TYPE_P (arg))
     return dependent_type_p (arg);
   else
@@ -12875,10 +16284,10 @@ dependent_template_arg_p (tree arg)
 }
 
 /* Returns true if ARGS (a collection of template arguments) contains
-   any dependent arguments.  */
+   any types that require structural equality testing.  */
 
 bool
-any_dependent_template_arguments_p (tree args)
+any_template_arguments_need_structural_equality_p (tree args)
 {
   int i;
   int j;
@@ -12892,6 +16301,58 @@ any_dependent_template_arguments_p (tree args)
     {
       tree level = TMPL_ARGS_LEVEL (args, i + 1);
       for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
+       {
+         tree arg = TREE_VEC_ELT (level, j);
+         tree packed_args = NULL_TREE;
+         int k, len = 1;
+
+         if (ARGUMENT_PACK_P (arg))
+           {
+             /* Look inside the argument pack.  */
+             packed_args = ARGUMENT_PACK_ARGS (arg);
+             len = TREE_VEC_LENGTH (packed_args);
+           }
+
+         for (k = 0; k < len; ++k)
+           {
+             if (packed_args)
+               arg = TREE_VEC_ELT (packed_args, k);
+
+             if (error_operand_p (arg))
+               return true;
+             else if (TREE_CODE (arg) == TEMPLATE_DECL
+                      || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+               continue;
+             else if (TYPE_P (arg) && TYPE_STRUCTURAL_EQUALITY_P (arg))
+               return true;
+             else if (!TYPE_P (arg) && TREE_TYPE (arg)
+                      && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg)))
+               return true;
+           }
+       }
+    }
+
+  return false;
+}
+
+/* Returns true if ARGS (a collection of template arguments) contains
+   any dependent arguments.  */
+
+bool
+any_dependent_template_arguments_p (const_tree args)
+{
+  int i;
+  int j;
+
+  if (!args)
+    return false;
+  if (args == error_mark_node)
+    return true;
+
+  for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+    {
+      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;
     }
@@ -12938,12 +16399,70 @@ dependent_template_id_p (tree tmpl, tree args)
          || any_dependent_template_arguments_p (args));
 }
 
+/* Returns TRUE if OMP_FOR with DECLV, INITV, CONDV and INCRV vectors
+   is dependent.  */
+
+bool
+dependent_omp_for_p (tree declv, tree initv, tree condv, tree incrv)
+{
+  int i;
+
+  if (!processing_template_decl)
+    return false;
+
+  for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
+    {
+      tree decl = TREE_VEC_ELT (declv, i);
+      tree init = TREE_VEC_ELT (initv, i);
+      tree cond = TREE_VEC_ELT (condv, i);
+      tree incr = TREE_VEC_ELT (incrv, i);
+
+      if (type_dependent_expression_p (decl))
+       return true;
+
+      if (init && type_dependent_expression_p (init))
+       return true;
+
+      if (type_dependent_expression_p (cond))
+       return true;
+
+      if (COMPARISON_CLASS_P (cond)
+         && (type_dependent_expression_p (TREE_OPERAND (cond, 0))
+             || type_dependent_expression_p (TREE_OPERAND (cond, 1))))
+       return true;
+
+      if (TREE_CODE (incr) == MODOP_EXPR)
+       {
+         if (type_dependent_expression_p (TREE_OPERAND (incr, 0))
+             || type_dependent_expression_p (TREE_OPERAND (incr, 2)))
+           return true;
+       }
+      else if (type_dependent_expression_p (incr))
+       return true;
+      else if (TREE_CODE (incr) == MODIFY_EXPR)
+       {
+         if (type_dependent_expression_p (TREE_OPERAND (incr, 0)))
+           return true;
+         else if (BINARY_CLASS_P (TREE_OPERAND (incr, 1)))
+           {
+             tree t = TREE_OPERAND (incr, 1);
+             if (type_dependent_expression_p (TREE_OPERAND (t, 0))
+                 || type_dependent_expression_p (TREE_OPERAND (t, 1)))
+               return true;
+           }
+       }
+    }
+
+  return false;
+}
+
 /* 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)
@@ -12953,6 +16472,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);
 
@@ -12965,8 +16485,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)
@@ -12974,25 +16494,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))
     {
@@ -13002,19 +16534,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
@@ -13033,6 +16583,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)