OSDN Git Service

gcc/cp/ChangeLog:
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index f25f2c4..de70e53 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, 2007  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).
 
@@ -125,7 +125,7 @@ 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 bool inline_needs_template_parms (tree);
@@ -236,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))
        {
@@ -382,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);
@@ -709,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 (input_location, "specialization of %qD in different namespace", tmpl);
+      permerror (input_location, "  from definition of %q+#D", tmpl);
       return false;
     }
 }
@@ -727,9 +728,9 @@ 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 (input_location, "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
@@ -771,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);
@@ -806,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 (input_location, "specializing %q#T in different namespace", type);
+             permerror (input_location, "  from definition of %q+#D",
+                        CLASSTYPE_TI_TEMPLATE (type));
            }
 
          /* Check for invalid specialization after instantiation:
@@ -976,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;
 }
 
@@ -1012,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;
@@ -1023,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]
@@ -1065,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();
@@ -1112,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));
@@ -1122,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)),
@@ -1134,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;
@@ -1147,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);
@@ -1160,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)
@@ -1174,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)),
@@ -1187,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;
@@ -1279,12 +1289,8 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
                to the primary function; now copy the inline bits to
                the various clones.  */
              FOR_EACH_CLONE (clone, fn)
-               {
-                 DECL_DECLARED_INLINE_P (clone)
-                   = DECL_DECLARED_INLINE_P (fn);
-                 DECL_INLINE (clone)
-                   = DECL_INLINE (fn);
-               }
+               DECL_DECLARED_INLINE_P (clone)
+                 = DECL_DECLARED_INLINE_P (fn);
              check_specialization_namespace (fn);
 
              return fn;
@@ -1996,8 +2002,8 @@ check_explicit_specialization (tree declarator,
       for (; t; t = TREE_CHAIN (t))
        if (TREE_PURPOSE (t))
          {
-           pedwarn
-             ("default argument specified in explicit specialization");
+           permerror (input_location, 
+                      "default argument specified in explicit specialization");
            break;
          }
     }
@@ -2086,7 +2092,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]:
@@ -2429,10 +2435,6 @@ struct find_parameter_pack_data
 
   /* Set of AST nodes that have been visited by the traversal.  */
   struct pointer_set_t *visited;
-
-  /* Whether we should replace parameter packs with
-     ERROR_MARK_NODE. Used by check_for_bare_parameter_packs.  */
-  bool set_packs_to_error;
 };
 
 /* Identifies all of the argument packs that occur in a template
@@ -2447,15 +2449,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     (struct find_parameter_pack_data*)data;
   bool parameter_pack_p = false;
 
-  /* Don't visit nodes twice, except when we're clearing out parameter
-     packs.  */
-  if (pointer_set_contains (ppd->visited, *tp))
-    {
-      *walk_subtrees = 0;
-      return NULL_TREE;
-    }
-
-recheck:
   /* Identify whether this is a parameter pack or not.  */
   switch (TREE_CODE (t))
     {
@@ -2480,16 +2473,6 @@ recheck:
         }
       break;
 
-    case POINTER_TYPE:
-      if (ppd->set_packs_to_error)
-       /* Pointer types are shared, set in that case the outermost
-          POINTER_TYPE to error_mark_node rather than the parameter pack.  */
-       {
-         t = TREE_TYPE (t);
-         goto recheck;
-       }
-      break;
-
     default:
       /* Not a parameter pack.  */
       break;
@@ -2499,23 +2482,11 @@ recheck:
     {
       /* Add this parameter pack to the list.  */
       *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
-
-      if (ppd->set_packs_to_error)
-       /* The caller requested that we set the parameter packs to
-          ERROR_MARK_NODE so that they will not trip up the compiler
-          later.  The caller is responsible for emitting an error.  */
-       *tp = error_mark_node;
-      else
-       /* Make sure we do not visit this node again.  */
-       pointer_set_insert (ppd->visited, *tp);
     }
-  else
-    /* Make sure we do not visit this node again.  */
-    pointer_set_insert (ppd->visited, *tp);
 
   if (TYPE_P (t))
     cp_walk_tree (&TYPE_CONTEXT (t), 
-                 &find_parameter_packs_r, ppd, NULL);
+                 &find_parameter_packs_r, ppd, ppd->visited);
 
   /* This switch statement will return immediately if we don't find a
      parameter pack.  */
@@ -2527,10 +2498,10 @@ recheck:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Check the template itself.  */
       cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)), 
-                   &find_parameter_packs_r, ppd, NULL);
+                   &find_parameter_packs_r, ppd, ppd->visited);
       /* Check the template arguments.  */
       cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, 
-                   NULL);
+                   ppd->visited);
       *walk_subtrees = 0;
       return NULL_TREE;
 
@@ -2550,19 +2521,19 @@ recheck:
     case ENUMERAL_TYPE:
       if (TYPE_TEMPLATE_INFO (t))
        cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), 
-                     &find_parameter_packs_r, ppd, NULL);
+                     &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, NULL);
+                   &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, NULL);
+                   ppd, ppd->visited);
       *walk_subtrees = 0;
       return NULL_TREE;
       
@@ -2573,7 +2544,13 @@ recheck:
 
     case INTEGER_TYPE:
       cp_walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r, 
-                   ppd, NULL);
+                   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;
 
@@ -2592,8 +2569,7 @@ uses_parameter_packs (tree t)
   struct find_parameter_pack_data ppd;
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = pointer_set_create ();
-  ppd.set_packs_to_error = false;
-  cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL);
+  cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
   pointer_set_destroy (ppd.visited);
   return parameter_packs != NULL_TREE;
 }
@@ -2611,8 +2587,6 @@ make_pack_expansion (tree arg)
   bool for_types = false;
   struct find_parameter_pack_data ppd;
 
-  ppd.set_packs_to_error = false;
-
   if (!arg || arg == error_mark_node)
     return arg;
 
@@ -2646,7 +2620,7 @@ make_pack_expansion (tree arg)
       ppd.visited = pointer_set_create ();
       ppd.parameter_packs = &parameter_packs;
       cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r, 
-                    &ppd, NULL);
+                    &ppd, ppd.visited);
 
       if (parameter_packs == NULL_TREE)
         {
@@ -2664,7 +2638,7 @@ make_pack_expansion (tree arg)
               /* Determine which parameter packs will be expanded in this
                  argument.  */
               cp_walk_tree (&TREE_VALUE (value), &find_parameter_packs_r, 
-                            &ppd, NULL);
+                            &ppd, ppd.visited);
             }
         }
 
@@ -2702,7 +2676,7 @@ make_pack_expansion (tree arg)
   /* 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, NULL);
+  cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
   pointer_set_destroy (ppd.visited);
 
   /* Make sure we found some parameter packs.  */
@@ -2731,29 +2705,28 @@ make_pack_expansion (tree arg)
    g(h(args)), or f(g(h(args))), because we would produce erroneous
    error messages. 
 
-   Returns TRUE if there were no bare parameter packs, returns FALSE
-   (and emits an error) if there were bare parameter packs.*/
+   Returns TRUE and emits an error if there were bare parameter packs,
+   returns FALSE otherwise.  */
 bool 
-check_for_bare_parameter_packs (tree* t)
+check_for_bare_parameter_packs (tree t)
 {
   tree parameter_packs = NULL_TREE;
   struct find_parameter_pack_data ppd;
 
-  if (!processing_template_decl || !t || !*t || *t == error_mark_node)
-    return true;
+  if (!processing_template_decl || !t || t == error_mark_node)
+    return false;
 
-  if (TREE_CODE (*t) == TYPE_DECL)
-    t = &TREE_TYPE (*t);
+  if (TREE_CODE (t) == TYPE_DECL)
+    t = TREE_TYPE (t);
 
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = pointer_set_create ();
-  ppd.set_packs_to_error = false;
-  cp_walk_tree (t, &find_parameter_packs_r, &ppd, NULL);
+  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 `...':");
+      error ("parameter packs not expanded with %<...%>:");
       while (parameter_packs)
         {
           tree pack = TREE_VALUE (parameter_packs);
@@ -2768,25 +2741,17 @@ check_for_bare_parameter_packs (tree* t)
             name = DECL_NAME (pack);
 
          if (name)
-           inform ("        %qD", name);
+           inform (input_location, "        %qD", name);
          else
-           inform ("        <anonymous>");
+           inform (input_location, "        <anonymous>");
 
           parameter_packs = TREE_CHAIN (parameter_packs);
         }
 
-      /* Clean up any references to these parameter packs within the
-        tree.  */
-      ppd.parameter_packs = &parameter_packs;
-      ppd.visited = pointer_set_create ();
-      ppd.set_packs_to_error = true;
-      cp_walk_tree (t, &find_parameter_packs_r, &ppd, NULL);
-      pointer_set_destroy (ppd.visited);
-
-      return false;
+      return true;
     }
 
-  return true;
+  return false;
 }
 
 /* Expand any parameter packs that occur in the template arguments in
@@ -2844,12 +2809,15 @@ expand_template_argument_pack (tree args)
   return result_args;
 }
 
-/* Complain if DECL shadows a template parameter.
+/* Checks if DECL shadows a template parameter.
 
    [temp.local]: A template-parameter shall not be redeclared within its
-   scope (including nested scopes).  */
+   scope (including nested scopes).
 
-void
+   Emits an error and returns TRUE if the DECL shadows a parameter,
+   returns FALSE otherwise.  */
+
+bool
 check_template_shadow (tree decl)
 {
   tree olddecl;
@@ -2857,7 +2825,7 @@ check_template_shadow (tree decl)
   /* If we're not in a template, we can't possibly shadow a template
      parameter.  */
   if (!current_template_parms)
-    return;
+    return true;
 
   /* Figure out what we're shadowing.  */
   if (TREE_CODE (decl) == OVERLOAD)
@@ -2867,24 +2835,25 @@ check_template_shadow (tree decl)
   /* If there's no previous binding for this name, we're not shadowing
      anything, let alone a template parameter.  */
   if (!olddecl)
-    return;
+    return true;
 
   /* 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;
+    return true;
 
   /* 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;
+    return true;
 
   error ("declaration of %q+#D", decl);
   error (" shadows template parm %q+#D", olddecl);
+  return false;
 }
 
 /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
@@ -2904,7 +2873,6 @@ build_template_parm_index (int index,
   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;
@@ -2957,7 +2925,6 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
 
       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);
@@ -3045,7 +3012,7 @@ process_template_parm (tree list, tree parm, bool is_non_type,
          {
            /* 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));
+           check_for_bare_parameter_packs (TREE_TYPE (parm));
            
            /* Recover by calling this a parameter pack.  */
            is_parameter_pack = true;
@@ -3054,11 +3021,9 @@ process_template_parm (tree list, tree parm, bool is_non_type,
 
       /* 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,
@@ -3075,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;
@@ -3084,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);
        }
@@ -3327,15 +3292,20 @@ process_partial_specialization (tree decl)
   tree maintmpl = CLASSTYPE_TI_TEMPLATE (type);
   tree specargs = CLASSTYPE_TI_ARGS (type);
   tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs);
-  tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
   tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl);
+  tree inner_parms;
   int nargs = TREE_VEC_LENGTH (inner_args);
-  int ntparms = TREE_VEC_LENGTH (inner_parms);
+  int ntparms;
   int  i;
   int did_error_intro = 0;
   struct template_parm_data tpd;
   struct template_parm_data tpd2;
 
+  gcc_assert (current_template_parms);
+
+  inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+  ntparms = TREE_VEC_LENGTH (inner_parms);
+
   /* We check that each of the template parameters given in the
      partial specialization is used in the argument list to the
      specialization.  For example:
@@ -3378,7 +3348,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)
@@ -3501,7 +3472,8 @@ process_partial_specialization (tree decl)
                   for_each_template_parm (type,
                                           &mark_template_parm,
                                           &tpd2,
-                                          NULL);
+                                          NULL,
+                                         /*include_nondeduced_p=*/false);
 
                   if (tpd2.arg_uses_template_parms [i])
                     {
@@ -3537,10 +3509,11 @@ process_partial_specialization (tree decl)
   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.
    
 
    IS_FRIEND_DECL is nonzero if DECL is a friend function template
@@ -3617,7 +3590,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
 
               if (TREE_PURPOSE (parm))
                 seen_def_arg_p = 1;
-              else if (seen_def_arg_p)
+              else if (seen_def_arg_p
+                      && !template_parameter_pack_p (TREE_VALUE (parm)))
                 {
                   error ("no default argument for %qD", TREE_VALUE (parm));
                   /* For better subsequent error-recovery, we indicate that
@@ -3625,6 +3599,32 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
                   TREE_PURPOSE (parm) = error_mark_node;
                   no_errors = false;
                 }
+             else if (is_primary
+                      && !is_partial
+                      && !is_friend_decl
+                      /* Don't complain about an enclosing partial
+                         specialization.  */
+                      && parm_level == parms
+                      && TREE_CODE (decl) == TYPE_DECL
+                      && i < ntparms - 1
+                      && template_parameter_pack_p (TREE_VALUE (parm)))
+               {
+                 /* A primary class template can only have one
+                    parameter pack, at the end of the template
+                    parameter list.  */
+
+                 if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL)
+                   error ("parameter pack %qE must be at the end of the"
+                          " template parameter list", TREE_VALUE (parm));
+                 else
+                   error ("parameter pack %qT must be at the end of the"
+                          " template parameter list", 
+                          TREE_TYPE (TREE_VALUE (parm)));
+
+                 TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) 
+                   = error_mark_node;
+                 no_errors = false;
+               }
             }
         }
     }
@@ -3758,8 +3758,8 @@ push_template_decl_real (tree decl, bool is_friend)
      [temp.mem].  */
   bool member_template_p = false;
 
-  if (decl == error_mark_node)
-    return decl;
+  if (decl == error_mark_node || !current_template_parms)
+    return error_mark_node;
 
   /* See if this is a partial specialization.  */
   is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl)
@@ -3804,7 +3804,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))
@@ -3859,7 +3862,7 @@ push_template_decl_real (tree decl, bool is_friend)
       while (arg && argtype)
         {
           if (!FUNCTION_PARAMETER_PACK_P (arg)
-              && !check_for_bare_parameter_packs (&TREE_TYPE (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
@@ -3875,44 +3878,23 @@ push_template_decl_real (tree decl, bool is_friend)
 
       /* Check for bare parameter packs in the return type and the
          exception specifiers.  */
-      if (!check_for_bare_parameter_packs (&TREE_TYPE (type)))
+      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;
-      check_for_bare_parameter_packs (&TYPE_RAISES_EXCEPTIONS (type));
+      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;
     }
-  else if (!check_for_bare_parameter_packs (&TREE_TYPE (decl)))
-    return error_mark_node;
 
   if (is_partial)
     return process_partial_specialization (decl);
 
-  /* A primary class template can only have one parameter pack, at the
-     end of the template parameter list.  */
-  if (primary && TREE_CODE (decl) == TYPE_DECL)
-    {
-      tree inner_parms 
-       = INNERMOST_TEMPLATE_PARMS (current_template_parms);
-      int i, len = TREE_VEC_LENGTH (inner_parms);
-      for (i = 0; i < len - 1; i++)
-        {
-          tree parm = TREE_VALUE (TREE_VEC_ELT (inner_parms, i));
-
-         if (template_parameter_pack_p (parm))
-           {
-             if (TREE_CODE (parm) == PARM_DECL)
-               error ("parameter pack %qE must be at the end of the"
-                      " template parameter list", parm);
-             else
-               error ("parameter pack %qT must be at the end of the"
-                      " template parameter list", TREE_TYPE (parm));
-
-             TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) = error_mark_node;
-           }
-        }
-    }
-
   args = current_template_args ();
 
   if (!ctx
@@ -3966,7 +3948,7 @@ push_template_decl_real (tree decl, bool is_friend)
       if (!tinfo)
        {
          error ("template definition of non-template %q#D", decl);
-         return decl;
+         return error_mark_node;
        }
 
       tmpl = TI_TEMPLATE (tinfo);
@@ -4047,7 +4029,7 @@ push_template_decl_real (tree decl, bool is_friend)
 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");
+           inform (input_location, "use template<> for an explicit specialization");
          /* Avoid crash in import_export_decl.  */
          DECL_INTERFACE_KNOWN (decl) = 1;
          return error_mark_node;
@@ -4168,7 +4150,7 @@ redeclare_class_template (tree type, tree parms)
     {
       error ("redeclared with %d template parameter(s)", 
              TREE_VEC_LENGTH (parms));
-      inform ("previous declaration %q+D used %d template parameter(s)", 
+      inform (input_location, "previous declaration %q+D used %d template parameter(s)", 
              tmpl, TREE_VEC_LENGTH (tmpl_parms));
       return false;
     }
@@ -4192,9 +4174,15 @@ redeclare_class_template (tree type, tree parms)
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
         TEMPLATE_DECL.  */
       if (tmpl_parm != error_mark_node
-          && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-          || (TREE_CODE (tmpl_parm) != TYPE_DECL
-              && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
+         && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+             || (TREE_CODE (tmpl_parm) != TYPE_DECL
+                 && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))
+             || (TREE_CODE (tmpl_parm) != PARM_DECL
+                 && (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (tmpl_parm))
+                     != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm))))
+             || (TREE_CODE (tmpl_parm) == PARM_DECL
+                 && (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (tmpl_parm))
+                     != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))))))
        {
          error ("template parameter %q+#D", tmpl_parm);
          error ("redeclared here as %q#D", parm);
@@ -4208,7 +4196,7 @@ redeclare_class_template (tree type, tree parms)
             A template-parameter may not be given default arguments
             by two different declarations in the same scope.  */
          error ("redefinition of default argument for %q#D", parm);
-         inform ("%Joriginal definition appeared here", tmpl_parm);
+         inform (input_location, "%Joriginal definition appeared here", tmpl_parm);
          return false;
        }
 
@@ -4262,7 +4250,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
@@ -4591,7 +4579,7 @@ convert_nontype_argument (tree type, tree expr)
        {
          error ("%qE is not a valid template argument for type %qT "
                 "because it is a pointer", expr, type);
-         inform ("try using %qE instead", TREE_OPERAND (expr, 0));
+         inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0));
          return NULL_TREE;
        }
 
@@ -4629,7 +4617,7 @@ convert_nontype_argument (tree type, tree expr)
          error ("%qE is not a valid template argument for type %qT "
                 "because it is of type %qT", expr, type,
                 TREE_TYPE (expr));
-         inform ("standard conversions are not allowed in this context");
+         inform (input_location, "standard conversions are not allowed in this context");
          return NULL_TREE;
        }
     }
@@ -4653,6 +4641,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 (!uses_template_parms (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
@@ -4675,6 +4734,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);
@@ -4682,10 +4742,37 @@ 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
           || TREE_VEC_ELT (arg_parms, i) == error_mark_node)
@@ -4694,60 +4781,35 @@ coerce_template_template_parms (tree parm_parms,
       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)
-       return 0;
-
-      if (TREE_CODE (arg) != TREE_CODE (parm))
+      if (!coerce_template_template_parm (parm, arg, complain, in_decl,
+                                          outer_args))
        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 (parm))
-             != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (arg)))
-           /* One is a parameter pack, the other 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 (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;
 
-         if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm))
-             != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (arg)))
-           /* One is a parameter pack, the other is not.  */
-           return 0;
-         break;
+      parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
 
-       default:
-         gcc_unreachable ();
-       }
+      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;
+        }
     }
+
   return 1;
 }
 
@@ -4763,6 +4825,10 @@ bool
 template_template_parm_bindings_ok_p (tree tparms, tree targs)
 {
   int i, ntparms = TREE_VEC_LENGTH (tparms);
+  bool ret = true;
+
+  /* We're dealing with template parms in this process.  */
+  ++processing_template_decl;
 
   targs = INNERMOST_TEMPLATE_ARGS (targs);
 
@@ -4813,13 +4879,18 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs)
                        tf_none,
                        tparm,
                        targs))
-               return false;
+               {
+                 ret = false;
+                 goto out;
+               }
            }
        }
     }
 
-  /* Everything is okay.  */
-  return true;
+ out:
+
+  --processing_template_decl;
+  return ret;
 }
 
 /* Convert the indicated template ARG as necessary to match the
@@ -4880,8 +4951,8 @@ 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%>", orig_arg);
+      permerror (input_location, "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),
@@ -4993,7 +5064,19 @@ convert_template_argument (tree parm,
       if (invalid_nontype_parm_type_p (t, complain))
        return error_mark_node;
 
-      if (!uses_template_parms (orig_arg) && !uses_template_parms (t))
+      if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg))
+       {
+         if (same_type_p (t, TREE_TYPE (orig_arg)))
+           val = orig_arg;
+         else
+           {
+             /* Not sure if this is reachable, but it doesn't hurt
+                to be robust.  */
+             error ("type mismatch in nontype parameter pack");
+             val = error_mark_node;
+           }
+       }
+      else 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
@@ -5126,7 +5209,7 @@ coerce_template_parameter_pack (tree parms,
     {
       argument_pack = make_node (NONTYPE_ARGUMENT_PACK);
       TREE_TYPE (argument_pack) 
-        = tsubst (TREE_TYPE (TREE_VALUE (parm)), args, complain, in_decl);
+        = tsubst (TREE_TYPE (TREE_VALUE (parm)), new_args, complain, in_decl);
       TREE_CONSTANT (argument_pack) = 1;
     }
 
@@ -5166,10 +5249,6 @@ coerce_template_parms (tree parms,
      parameters.  */
   int variadic_p = 0;
 
-  inner_args 
-    = expand_template_argument_pack (INNERMOST_TEMPLATE_ARGS (args));
-
-  nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
   nparms = TREE_VEC_LENGTH (parms);
 
   /* Determine if there are any parameter packs.  */
@@ -5177,13 +5256,22 @@ coerce_template_parms (tree parms,
     {
       tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx));
       if (template_parameter_pack_p (tparm))
-        {
-          variadic_p = 1;
-          break;
-        }
+       ++variadic_p;
     }
 
-  if ((nargs > nparms - variadic_p && !variadic_p)
+  inner_args = INNERMOST_TEMPLATE_ARGS (args);
+  /* If there are 0 or 1 parameter packs, we need to expand any argument
+     packs so that we can deduce a parameter pack from some non-packed args
+     followed by an argument pack, as in variadic85.C.  If there are more
+     than that, we need to leave argument packs intact so the arguments are
+     assigned to the right parameter packs.  This should only happen when
+     dealing with a nested class inside a partial specialization of a class
+     template, as in variadic92.C.  */
+  if (variadic_p <= 1)
+    inner_args = expand_template_argument_pack (inner_args);
+
+  nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
+  if ((nargs > nparms && !variadic_p)
       || (nargs < nparms - variadic_p
          && require_all_args
          && (!use_default_args
@@ -5230,42 +5318,48 @@ coerce_template_parms (tree parms,
       }
 
       /* Calculate the next argument.  */
-      if (template_parameter_pack_p (TREE_VALUE (parm)))
+      if (arg_idx < nargs)
+       arg = TREE_VEC_ELT (inner_args, arg_idx);
+      else
+       arg = NULL_TREE;
+
+      if (template_parameter_pack_p (TREE_VALUE (parm))
+         && !(arg && ARGUMENT_PACK_P (arg)))
         {
-          /* All remaining arguments will be placed in the
-             template parameter pack PARM.  */
-          arg = coerce_template_parameter_pack (parms, parm_idx, args, 
-                                                inner_args, arg_idx,
-                                                new_args, &lost,
-                                                in_decl, complain);
-          
+         /* 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;
-
+         /* We are done with all of the arguments.  */
+         arg_idx = nargs;
+          
           continue;
         }
-      else if (arg_idx < nargs)
-        {
-          arg = TREE_VEC_ELT (inner_args, arg_idx);
-
-          if (arg && PACK_EXPANSION_P (arg))
+      else if (arg)
+       {
+          if (PACK_EXPANSION_P (arg))
             {
              if (complain & tf_error)
                {
+                 /* FIXME this restriction was removed by N2555; see
+                    bug 35722.  */
                  /* 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 "
+                   sorry ("cannot expand %<%E%> into a fixed-length "
                           "argument list", arg);
                  else
-                   error ("cannot expand %<%T%> into a fixed-length "
+                   sorry ("cannot expand %<%T%> into a fixed-length "
                           "argument list", arg);
                }
              return error_mark_node;
@@ -5322,6 +5416,25 @@ template_args_equal (tree ot, tree nt)
     return PACK_EXPANSION_P (nt) 
       && template_args_equal (PACK_EXPANSION_PATTERN (ot),
                               PACK_EXPANSION_PATTERN (nt));
+  else if (ARGUMENT_PACK_P (ot))
+    {
+      int i, len;
+      tree opack, npack;
+
+      if (!ARGUMENT_PACK_P (nt))
+       return 0;
+
+      opack = ARGUMENT_PACK_ARGS (ot);
+      npack = ARGUMENT_PACK_ARGS (nt);
+      len = TREE_VEC_LENGTH (opack);
+      if (TREE_VEC_LENGTH (npack) != len)
+       return 0;
+      for (i = 0; i < len; ++i)
+       if (!template_args_equal (TREE_VEC_ELT (opack, i),
+                                 TREE_VEC_ELT (npack, i)))
+         return 0;
+      return 1;
+    }
   else if (TYPE_P (nt))
     return TYPE_P (ot) && same_type_p (ot, nt);
   else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
@@ -5338,9 +5451,6 @@ comp_template_args (tree oldargs, tree newargs)
 {
   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;
 
@@ -5474,7 +5584,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);
@@ -5483,20 +5593,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);
 
@@ -5507,37 +5617,38 @@ 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
+           && DECL_TEMPLATE_RESULT (d1)
           && 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)
        {
@@ -5550,7 +5661,7 @@ 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 */
@@ -5559,7 +5670,7 @@ lookup_template_class (tree d1,
       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
 
@@ -5577,7 +5688,7 @@ lookup_template_class (tree d1,
         level 1, and T at level 2, while the template arguments at level 1
         becomes {std::vector} and the inner level 2 is {int}.  */
 
-      outer = DECL_CONTEXT (template);
+      outer = DECL_CONTEXT (templ);
       if (outer)
        outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
       else if (current_template_parms)
@@ -5588,21 +5699,21 @@ lookup_template_class (tree d1,
       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;
@@ -5610,7 +5721,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);
@@ -5630,7 +5741,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);
        }
@@ -5640,7 +5751,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
@@ -5654,12 +5765,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);
@@ -5690,7 +5801,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);
@@ -5712,7 +5823,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;
 
@@ -5734,7 +5845,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);
@@ -5748,22 +5859,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;
@@ -5774,18 +5885,24 @@ lookup_template_class (tree d1,
          if (!is_partial_instantiation)
            {
              set_current_access_from_decl (TYPE_NAME (template_type));
-             t = start_enum (TYPE_IDENTIFIER (template_type));
+             t = start_enum (TYPE_IDENTIFIER (template_type),
+                              tsubst (ENUM_UNDERLYING_TYPE (template_type),
+                                      arglist, complain, in_decl),
+                              SCOPED_ENUM_P (template_type));
            }
          else
-           /* We don't want to call start_enum for this type, since
-              the values for the enumeration constants may involve
-              template parameters.  And, no one should be interested
-              in the enumeration constants for such a type.  */
-           t = make_node (ENUMERAL_TYPE);
+            {
+              /* We don't want to call start_enum for this type, since
+                 the values for the enumeration constants may involve
+                 template parameters.  And, no one should be interested
+                 in the enumeration constants for such a type.  */
+              t = make_node (ENUMERAL_TYPE);
+              SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
+            }
        }
       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);
@@ -5793,7 +5910,7 @@ 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
@@ -5813,7 +5930,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)
@@ -5826,8 +5943,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;
@@ -5838,15 +5953,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;
@@ -5891,15 +6006,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)
@@ -5930,6 +6045,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;
 };
 
@@ -5944,7 +6062,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))
@@ -5959,15 +6079,18 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       if (!TYPE_TEMPLATE_INFO (t))
        *walk_subtrees = 0;
       else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
-                                      fn, data, pfd->visited))
+                                      fn, data, pfd->visited, 
+                                      pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case INTEGER_TYPE:
       if (for_each_template_parm (TYPE_MIN_VALUE (t),
-                                 fn, data, pfd->visited)
+                                 fn, data, pfd->visited, 
+                                 pfd->include_nondeduced_p)
          || for_each_template_parm (TYPE_MAX_VALUE (t),
-                                    fn, data, pfd->visited))
+                                    fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5975,13 +6098,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
@@ -5995,7 +6119,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
@@ -6005,8 +6129,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;
 
@@ -6014,7 +6140,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.  */
 
@@ -6022,17 +6148,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.  */
 
@@ -6048,7 +6176,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 */
@@ -6058,15 +6187,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;
 
@@ -6107,11 +6238,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;
@@ -6119,6 +6255,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
@@ -6190,7 +6327,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;
@@ -6207,7 +6345,7 @@ static int last_template_error_tick;
 static int
 push_tinst_level (tree d)
 {
-  struct tinst_level *new;
+  struct tinst_level *new_level;
 
   if (tinst_depth >= max_tinst_depth)
     {
@@ -6227,12 +6365,12 @@ push_tinst_level (tree d)
       return 0;
     }
 
-  new = GGC_NEW (struct tinst_level);
-  new->decl = d;
-  new->locus = input_location;
-  new->in_system_header_p = in_system_header;
-  new->next = current_tinst_level;
-  current_tinst_level = new;
+  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
@@ -6253,7 +6391,6 @@ pop_tinst_level (void)
   /* Restore the filename and line number stashed away when we started
      this instantiation.  */
   input_location = current_tinst_level->locus;
-  in_system_header = current_tinst_level->in_system_header_p;
   current_tinst_level = current_tinst_level->next;
   --tinst_depth;
   ++tinst_level_tick;
@@ -6290,6 +6427,30 @@ outermost_tinst_level (void)
   return level;
 }
 
+/* Returns TRUE if PARM is a parameter of the template TEMPL.  */
+
+bool
+parameter_of_template_p (tree parm, tree templ)
+{
+  tree parms;
+  int i;
+
+  if (!parm || !templ)
+    return false;
+
+  gcc_assert (DECL_TEMPLATE_PARM_P (parm));
+  gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
+
+  parms = DECL_TEMPLATE_PARMS (templ);
+  parms = INNERMOST_TEMPLATE_PARMS (parms);
+
+  for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
+    if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i)))
+      return true;
+
+  return false;
+}
+
 /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL.  ARGS is the
    vector of template arguments, as for tsubst.
 
@@ -6319,7 +6480,7 @@ 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,
@@ -6717,9 +6878,29 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
            {
              *p = TREE_CHAIN (t);
              TREE_CHAIN (t) = NULL_TREE;
-             TREE_VALUE (t)
-               = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
-                              /*integral_constant_expression_p=*/false);
+             /* 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);
            }
@@ -6734,7 +6915,7 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int 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;
@@ -6748,12 +6929,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;
@@ -6776,7 +6957,7 @@ instantiate_class_template (tree type)
     }
   else
     {
-      pattern = TREE_TYPE (template);
+      pattern = TREE_TYPE (templ);
       args = CLASSTYPE_TI_ARGS (type);
     }
 
@@ -6805,9 +6986,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);
@@ -7003,7 +7183,7 @@ instantiate_class_template (tree type)
                {
                  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.  */
@@ -7162,7 +7342,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.  */
@@ -7198,7 +7378,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
@@ -7270,10 +7450,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
       tree orig_arg = NULL_TREE;
 
       if (TREE_CODE (parm_pack) == PARM_DECL)
-        {
-          if (local_specializations)
-            arg_pack = retrieve_local_specialization (parm_pack);
-        }
+       arg_pack = retrieve_local_specialization (parm_pack);
       else
         {
           int level, idx, levels;
@@ -7653,8 +7830,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:
@@ -8043,7 +8226,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        /* Clear out the mangled name and RTL for the instantiation.  */
        SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
        SET_DECL_RTL (r, NULL_RTX);
-       DECL_INITIAL (r) = NULL_TREE;
+       /* Leave DECL_INITIAL set on deleted instantiations.  */
+       if (!DECL_DELETED_FN (r))
+         DECL_INITIAL (r) = NULL_TREE;
        DECL_CONTEXT (r) = ctx;
 
        if (member && DECL_CONV_FN_P (r))
@@ -8067,6 +8252,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        DECL_PENDING_INLINE_INFO (r) = 0;
        DECL_PENDING_INLINE_P (r) = 0;
        DECL_SAVED_TREE (r) = NULL_TREE;
+       DECL_STRUCT_FUNCTION (r) = NULL;
        TREE_USED (r) = 0;
        if (DECL_CLONED_FUNCTION (r))
          {
@@ -8166,9 +8352,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                substitution from inside tsubst_pack_expansion. Just
                return the local specialization (which will be a single
                parm).  */
-            tree spec = NULL_TREE;
-            if (local_specializations)
-              spec = retrieve_local_specialization (t);
+            tree spec = retrieve_local_specialization (t);
             if (spec 
                 && TREE_CODE (spec) == PARM_DECL
                 && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION)
@@ -8659,20 +8843,13 @@ tsubst_function_type (tree t,
   if (arg_types == error_mark_node)
     return error_mark_node;
 
-  if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED
-      && in_decl != NULL_TREE
-      && !TREE_NO_WARNING (in_decl)
-      && (SCALAR_TYPE_P (return_type) || VOID_TYPE_P (return_type)))
-    warning (OPT_Wignored_qualifiers,
-            "type qualifiers ignored on function return type");
-
   /* Construct a new type node and return it.  */
   if (TREE_CODE (t) == FUNCTION_TYPE)
     fntype = build_function_type (return_type, arg_types);
   else
     {
       tree r = TREE_TYPE (TREE_VALUE (arg_types));
-      if (! IS_AGGR_TYPE (r))
+      if (! MAYBE_CLASS_TYPE_P (r))
        {
          /* [temp.deduct]
 
@@ -8814,17 +8991,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       tree decl = TYPE_NAME (t);
       
       if (DECL_CLASS_SCOPE_P (decl)
-         && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (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))
+      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
-       r = NULL_TREE;
-       
+       /* The typedef is from a non-template context.  */
+       return t;
+
       if (r)
        {
          r = TREE_TYPE (r);
@@ -8880,9 +9061,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                           /*integral_constant_expression_p=*/false);
        max = fold_decl_constant_value (max);
 
-       if (TREE_CODE (max) != INTEGER_CST 
-           && TREE_CODE (max) != TEMPLATE_PARM_INDEX
-           && !at_function_scope_p ())
+       if (TREE_CODE (max) != INTEGER_CST
+           && !at_function_scope_p ()
+           && !value_dependent_expression_p (max))
          {
            if (complain & tf_error)
              error ("array bound is not an integer constant");
@@ -9151,13 +9332,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");
@@ -9203,7 +9378,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]
 
@@ -9346,7 +9521,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);
@@ -9455,11 +9630,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree type;
 
-       type = 
-          finish_decltype_type (tsubst_expr 
-                                (DECLTYPE_TYPE_EXPR (t), args,
-                                 complain, in_decl,
-                                 /*integral_constant_expression_p=*/false),
+       ++skip_evaluation;
+
+       type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args,
+                           complain, in_decl,
+                           /*integral_constant_expression_p=*/false);
+
+       --skip_evaluation;
+
+       type =
+          finish_decltype_type (type,
                                 DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t));
        return cp_build_qualified_type_real (type,
                                             cp_type_quals (t)
@@ -9627,7 +9807,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
            {
              error ("dependent-name %qE is parsed as a non-type, but "
                     "instantiation yields a type", qualified_id);
-             inform ("say %<typename %E%> if a type is meant", qualified_id);
+             inform (input_location, "say %<typename %E%> if a type is meant", qualified_id);
            }
          return error_mark_node;
        }
@@ -9646,7 +9826,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;
     }
 
@@ -9655,7 +9835,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
@@ -9695,7 +9875,22 @@ 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 (r == NULL)
+       {
+         /* This can happen for a parameter name used later in a function
+            declaration (such as in a late-specified return type).
+            Replace it with an arbitrary expression with the same type
+            (*(T*)0).  This should only occur in an unevaluated context
+            (i.e. decltype).  */
+         gcc_assert (skip_evaluation);
+         r = non_reference (TREE_TYPE (t));
+         r = tsubst (r, args, complain, in_decl);
+         r = build_pointer_type (r);
+         r = build_c_cast (r, null_node);
+         return cp_build_indirect_ref (r, NULL, tf_warning_or_error);
+       }
+      
       if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
        r = ARGUMENT_PACK_SELECT_ARG (r);
       mark_used (r);
@@ -9823,9 +10018,30 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
           /* We only want to compute the number of arguments.  */
           tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
                                                 complain, in_decl);
+         int len = 0;
+
+         if (TREE_CODE (expanded) == TREE_VEC)
+           len = TREE_VEC_LENGTH (expanded);
+
          if (expanded == error_mark_node)
            return error_mark_node;
-          return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
+         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 */
 
@@ -10093,16 +10309,26 @@ 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, /*integral_constant_expression_p=*/false);
@@ -10110,6 +10336,7 @@ tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
+       case OMP_CLAUSE_UNTIED:
          break;
        default:
          gcc_unreachable ();
@@ -10153,6 +10380,147 @@ 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, auto_node;
+
+  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);
+  auto_node = type_uses_auto (TREE_TYPE (decl));
+  if (auto_node && init)
+    {
+      tree init_expr = init;
+      if (TREE_CODE (init_expr) == DECL_EXPR)
+       init_expr = DECL_INITIAL (DECL_EXPR_DECL (init_expr));
+      init_expr = RECUR (init_expr);
+      TREE_TYPE (decl)
+       = do_auto_deduction (TREE_TYPE (decl), init_expr, auto_node);
+    }
+  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.  */
 
@@ -10224,7 +10592,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                                          /*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);
          }
@@ -10269,8 +10637,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                             pack expansion where the parameter packs
                             used in that expansion were of length
                             zero.  */
-                         init = build_default_init (TREE_TYPE (decl),
-                                                     NULL_TREE);
+                         init = build_value_init (TREE_TYPE (decl));
                        else
                          init = t;
                      }
@@ -10476,21 +10843,55 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        = 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 = RECUR (TREE_OPERAND (init, 0));
-       init = RECUR (TREE_OPERAND (init, 1));
-       cond = RECUR (OMP_FOR_COND (t));
-       incr = RECUR (OMP_FOR_INCR (t));
+       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 ();
        RECUR (OMP_FOR_PRE_BODY (t));
        pre_body = pop_stmt_list (pre_body);
@@ -10499,10 +10900,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree 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));
       }
@@ -10639,7 +11038,8 @@ tsubst_copy_and_build (tree t,
                                     /*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)
@@ -10650,26 +11050,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 baselink_for_fns (template);
+         return baselink_for_fns (templ);
       }
 
     case INDIRECT_REF:
@@ -10685,7 +11085,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;
       }
 
@@ -10707,8 +11107,9 @@ tsubst_copy_and_build (tree t,
        if (integral_constant_expression_p
            && !cast_valid_in_integral_constant_expression_p (type))
          {
-           error ("a cast to a type other than an integral or "
-                  "enumeration type cannot appear in a constant-expression");
+            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; 
          }
 
@@ -10717,15 +11118,15 @@ tsubst_copy_and_build (tree t,
        switch (TREE_CODE (t))
          {
          case CAST_EXPR:
-           return build_functional_cast (type, op);
+           return build_functional_cast (type, op, complain);
          case REINTERPRET_CAST_EXPR:
-           return build_reinterpret_cast (type, op);
+           return build_reinterpret_cast (type, op, complain);
          case CONST_CAST_EXPR:
-           return build_const_cast (type, op);
+           return build_const_cast (type, op, complain);
          case DYNAMIC_CAST_EXPR:
-           return build_dynamic_cast (type, op);
+           return build_dynamic_cast (type, op, complain);
          case STATIC_CAST_EXPR:
-           return build_static_cast (type, op);
+           return build_static_cast (type, op, complain);
          default:
            gcc_unreachable ();
          }
@@ -10735,7 +11136,7 @@ tsubst_copy_and_build (tree t,
     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:
@@ -10746,7 +11147,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);
@@ -10757,8 +11159,9 @@ tsubst_copy_and_build (tree t,
        op1 = tsubst_non_call_postfix_expression (op1, args, complain,
                                                  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 finish_label_address_expr (DECL_NAME (op1),
+                                         EXPR_LOCATION (op1));
+      return build_x_unary_op (ADDR_EXPR, op1, complain);
 
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -10801,7 +11204,8 @@ tsubst_copy_and_build (tree t,
         (TREE_NO_WARNING (TREE_OPERAND (t, 1))
          ? ERROR_MARK
          : TREE_CODE (TREE_OPERAND (t, 1))),
-        /*overloaded_p=*/NULL);
+        /*overloaded_p=*/NULL,
+        complain);
 
     case SCOPE_REF:
       return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
@@ -10817,18 +11221,12 @@ tsubst_copy_and_build (tree t,
                                (TREE_NO_WARNING (TREE_OPERAND (t, 1))
                                 ? ERROR_MARK
                                 : TREE_CODE (TREE_OPERAND (t, 1))),
-                               /*overloaded_p=*/NULL);
+                               /*overloaded_p=*/NULL,
+                               complain);
 
     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);
-         if (expanded == error_mark_node)
-           return error_mark_node;
-          return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
-        }
+       return tsubst_copy (t, args, complain, in_decl);
       /* Fall through */
       
     case ALIGNOF_EXPR:
@@ -10850,16 +11248,19 @@ tsubst_copy_and_build (tree t,
          --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
@@ -10884,7 +11285,7 @@ tsubst_copy_and_build (tree t,
        tree init = RECUR (TREE_OPERAND (t, 3));
 
        if (TREE_OPERAND (t, 3) && !init)
-         /* If there was an initializer in the the original tree, but
+         /* 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
@@ -10897,7 +11298,8 @@ tsubst_copy_and_build (tree t,
           RECUR (TREE_OPERAND (t, 1)),
           RECUR (TREE_OPERAND (t, 2)),
           init,
-          NEW_EXPR_USE_GLOBAL (t));
+          NEW_EXPR_USE_GLOBAL (t),
+           complain);
       }
 
     case DELETE_EXPR:
@@ -10909,7 +11311,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:
       {
@@ -10983,25 +11386,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
@@ -11162,7 +11569,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;
              }
          }
@@ -11185,7 +11593,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:
@@ -11201,6 +11610,7 @@ tsubst_copy_and_build (tree t,
        bool process_index_p;
         int newlen;
         bool need_copy_p = false;
+       tree r;
 
        if (type == error_mark_node)
          return error_mark_node;
@@ -11212,7 +11622,7 @@ 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);
@@ -11265,10 +11675,13 @@ tsubst_copy_and_build (tree t,
               }
           }
 
+       r = build_constructor (init_list_type_node, n);
+       CONSTRUCTOR_IS_DIRECT_INIT (r) = CONSTRUCTOR_IS_DIRECT_INIT (t);
+
        if (TREE_HAS_CONSTRUCTOR (t))
-         return finish_compound_literal (type, n);
+         return finish_compound_literal (type, r);
 
-       return build_constructor (NULL_TREE, n);
+       return r;
       }
 
     case TYPEID_EXPR:
@@ -11361,58 +11774,76 @@ tsubst_copy_and_build (tree t,
    Emit an error under control of COMPLAIN, and return TRUE on error.  */
 
 static bool
-check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
+check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain)
 {
-  int ix, len = DECL_NTPARMS (tmpl);
-  bool result = false;
-
-  for (ix = 0; ix != len; ix++)
+  if (ARGUMENT_PACK_P (t))
     {
-      tree t = TREE_VEC_ELT (args, ix);
+      tree vec = ARGUMENT_PACK_ARGS (t);
+      int len = TREE_VEC_LENGTH (vec);
+      bool result = false;
+      int i;
 
-      if (TYPE_P (t))
+      for (i = 0; i < len; ++i)
+       if (check_instantiated_arg (tmpl, TREE_VEC_ELT (vec, i), complain))
+         result = true;
+      return result;
+    }
+  else if (TYPE_P (t))
+    {
+      /* [basic.link]: A name with no linkage (notably, the name
+        of a class or enumeration declared in a local scope)
+        shall not be used to declare an entity with linkage.
+        This implies that names with no linkage cannot be used as
+        template arguments.  */
+      tree nt = no_linkage_check (t, /*relaxed_p=*/false);
+
+      if (nt)
        {
-         /* [basic.link]: A name with no linkage (notably, the name
-            of a class or enumeration declared in a local scope)
-            shall not be used to declare an entity with linkage.
-            This implies that names with no linkage cannot be used as
-            template arguments.  */
-         tree nt = no_linkage_check (t, /*relaxed_p=*/false);
-
-         if (nt)
-           {
-             /* DR 488 makes use of a type with no linkage cause
-                type deduction to fail.  */
-             if (complain & tf_error)
-               {
-                 if (TYPE_ANONYMOUS_P (nt))
-                   error ("%qT is/uses anonymous type", t);
-                 else
-                   error ("template argument for %qD uses local type %qT",
-                          tmpl, t);
-               }
-             result = true;
-           }
-         /* In order to avoid all sorts of complications, we do not
-            allow variably-modified types as template arguments.  */
-         else if (variably_modified_type_p (t, NULL_TREE))
+         /* DR 488 makes use of a type with no linkage cause
+            type deduction to fail.  */
+         if (complain & tf_error)
            {
-             if (complain & tf_error)
-               error ("%qT is a variably modified type", t);
-             result = true;
+             if (TYPE_ANONYMOUS_P (nt))
+               error ("%qT is/uses anonymous type", t);
+             else
+               error ("template argument for %qD uses local type %qT",
+                      tmpl, t);
            }
+         return true;
        }
-      /* A non-type argument of integral or enumerated type must be a
-        constant.  */
-      else if (TREE_TYPE (t)
-              && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t))
-              && !TREE_CONSTANT (t))
+      /* In order to avoid all sorts of complications, we do not
+        allow variably-modified types as template arguments.  */
+      else if (variably_modified_type_p (t, NULL_TREE))
        {
          if (complain & tf_error)
-           error ("integral expression %qE is not constant", t);
-         result = true;
+           error ("%qT is a variably modified type", t);
+         return true;
        }
     }
+  /* A non-type argument of integral or enumerated type must be a
+     constant.  */
+  else if (TREE_TYPE (t)
+          && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t))
+          && !TREE_CONSTANT (t))
+    {
+      if (complain & tf_error)
+       error ("integral expression %qE is not constant", t);
+      return true;
+    }
+  return false;
+}
+
+static bool
+check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
+{
+  int ix, len = DECL_NTPARMS (tmpl);
+  bool result = false;
+
+  for (ix = 0; ix != len; ix++)
+    {
+      if (check_instantiated_arg (tmpl, TREE_VEC_ELT (args, ix), complain))
+       result = true;
+    }
   if (result && (complain & tf_error))
     error ("  trying to instantiate %qD", tmpl);
   return result;
@@ -11965,6 +12396,8 @@ type_unification_real (tree tparms,
          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;
       }
@@ -12135,6 +12568,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)
@@ -12143,6 +12577,7 @@ 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
@@ -12324,7 +12759,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)
@@ -12729,7 +13164,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;
@@ -12741,6 +13177,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)
@@ -12810,8 +13271,9 @@ 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));
+           tree parm_parms 
+              = DECL_INNERMOST_TEMPLATE_PARMS
+                 (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm));
            int i, len;
             int parm_variadic_p = 0;
 
@@ -12842,7 +13304,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,
@@ -13231,7 +13694,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,
@@ -13523,7 +13986,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);
@@ -13686,10 +14151,6 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
       args1 = TREE_CHAIN (args1);
       args2 = TREE_CHAIN (args2);
-
-      /* Stop when an ellipsis is seen.  */
-      if (args1 == NULL_TREE || args2 == NULL_TREE)
-       break;
     }
 
   processing_template_decl--;
@@ -14259,7 +14720,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 (input_location, "duplicate explicit instantiation of %q#D", result);
       /* If an "extern" explicit instantiation follows an ordinary
         explicit instantiation, the template is instantiated.  */
       if (extern_p)
@@ -14272,7 +14733,7 @@ do_decl_instantiation (tree decl, tree storage)
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      pedwarn ("explicit instantiation of non-template %q#D", result);
+      permerror (input_location, "explicit instantiation of non-template %q#D", result);
       return;
     }
 
@@ -14280,8 +14741,9 @@ 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 (!in_system_header && (cxx_dialect == cxx98))
+       pedwarn (input_location, OPT_pedantic, 
+                "ISO C++ 1998 forbids the use of %<extern%> on explicit "
                 "instantiations");
       extern_p = 1;
     }
@@ -14316,7 +14778,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);
 }
@@ -14367,9 +14829,20 @@ 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 (!in_system_header)
+       {
+         if (storage == ridpointers[(int) RID_EXTERN])
+           {
+             if (cxx_dialect == cxx98)
+               pedwarn (input_location, OPT_pedantic, 
+                        "ISO C++ 1998 forbids the use of %<extern%> on "
+                        "explicit instantiations");
+           }
+         else
+           pedwarn (input_location, OPT_pedantic, 
+                    "ISO C++ forbids the use of %qE"
+                    " on explicit instantiations", storage);
+       }
 
       if (storage == ridpointers[(int) RID_INLINE])
        nomem_p = 1;
@@ -14413,7 +14886,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 (input_location, "duplicate explicit instantiation of %q#T", t);
 
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
@@ -14580,8 +15053,6 @@ regenerate_decl_from_template (tree decl, tree tmpl)
       if (DECL_DECLARED_INLINE_P (code_pattern)
          && !DECL_DECLARED_INLINE_P (decl))
        DECL_DECLARED_INLINE_P (decl) = 1;
-      if (DECL_INLINE (code_pattern) && !DECL_INLINE (decl))
-       DECL_INLINE (decl) = 1;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
     DECL_INITIAL (decl) =
@@ -14673,7 +15144,6 @@ instantiate_decl (tree d, int defer_ok,
   bool pattern_defined;
   int need_push;
   location_t saved_loc = input_location;
-  int saved_in_system_header = in_system_header;
   bool external_p;
 
   /* This function should only be used to instantiate templates for
@@ -14756,7 +15226,6 @@ instantiate_decl (tree d, int defer_ok,
     mark_definable (d);
 
   input_location = DECL_SOURCE_LOCATION (d);
-  in_system_header = DECL_IN_SYSTEM_HEADER (d);
 
   /* If D is a member of an explicitly instantiated class template,
      and no definition is available, treat it like an implicit
@@ -14805,7 +15274,8 @@ instantiate_decl (tree d, int defer_ok,
   if (external_p
       /* ... but we instantiate inline functions so that we can inline
         them and ... */
-      && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+      && ! (TREE_CODE (d) == FUNCTION_DECL
+           && possibly_inlined_p (d))
       /* ... we instantiate static data members whose values are
         needed in integral constant expressions.  */
       && ! (TREE_CODE (d) == VAR_DECL
@@ -14852,7 +15322,8 @@ instantiate_decl (tree d, int defer_ok,
       input_location = saved_loc;
 
       if (at_eof && !pattern_defined
-         && DECL_EXPLICIT_INSTANTIATION (d))
+         && DECL_EXPLICIT_INSTANTIATION (d)
+         && DECL_NOT_REALLY_EXTERN (d))
        /* [temp.explicit]
 
           The definition of a non-exported function template, a
@@ -14860,8 +15331,8 @@ 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
-         ("explicit instantiation of %qD but no definition available", d);
+       permerror (input_location,  "explicit instantiation of %qD "
+                  "but no definition available", d);
 
       /* ??? Historically, we have instantiated inline functions, even
         when marked as "extern template".  */
@@ -14882,9 +15353,7 @@ instantiate_decl (tree d, int defer_ok,
       /* Instantiate inline functions so that the inliner can do its
         job, even though we'll not be emitting a copy of this
         function.  */
-      if (!(TREE_CODE (d) == FUNCTION_DECL
-           && flag_inline_trees
-           && DECL_DECLARED_INLINE_P (d)))
+      if (!(TREE_CODE (d) == FUNCTION_DECL && possibly_inlined_p (d)))
        goto out;
     }
 
@@ -15028,7 +15497,6 @@ instantiate_decl (tree d, int defer_ok,
 
 out:
   input_location = saved_loc;
-  in_system_header = saved_in_system_header;
   pop_deferring_access_checks ();
   pop_tinst_level ();
 
@@ -15046,7 +15514,6 @@ instantiate_pending_templates (int retries)
 {
   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
@@ -15130,7 +15597,6 @@ instantiate_pending_templates (int retries)
   while (reconsider);
 
   input_location = saved_loc;
-  in_system_header = saved_in_system_header;
 }
 
 /* Substitute ARGVEC into T, which is a list of initializers for
@@ -15177,37 +15643,51 @@ tsubst_initializer_list (tree t, tree argvec)
           PACK_EXPANSION_PARAMETER_PACKS (expr) =
             PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
 
-          /* Substitute parameter packs into each argument in the
-             TREE_LIST.  */
-          in_base_initializer = 1;
-          for (arg = TREE_VALUE (t); arg; arg = TREE_CHAIN (arg))
-            {
-              tree expanded_exprs;
-
-              /* Expand the argument.  */
-              SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
-              expanded_exprs = tsubst_pack_expansion (expr, argvec,
-                                                      tf_warning_or_error,
-                                                      NULL_TREE);
+         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;
+                 /* Prepend each of the expanded expressions to the
+                    corresponding TREE_LIST in EXPANDED_ARGUMENTS.  */
+                 for (i = 0; i < len; i++)
+                   {
+                     TREE_VEC_ELT (expanded_arguments, i) = 
+                       tree_cons (NULL_TREE, 
+                                  TREE_VEC_ELT (expanded_exprs, i),
+                                  TREE_VEC_ELT (expanded_arguments, i));
+                   }
+               }
+             in_base_initializer = 0;
 
-          /* Reverse all of the TREE_LISTs in EXPANDED_ARGUMENTS,
-             since we built them backwards.  */
-          for (i = 0; i < len; i++)
-            {
-              TREE_VEC_ELT (expanded_arguments, i) = 
-                nreverse (TREE_VEC_ELT (expanded_arguments, i));
-            }
+             /* Reverse all of the TREE_LISTs in EXPANDED_ARGUMENTS,
+                since we built them backwards.  */
+             for (i = 0; i < len; i++)
+               {
+                 TREE_VEC_ELT (expanded_arguments, i) = 
+                   nreverse (TREE_VEC_ELT (expanded_arguments, i));
+               }
+           }
         }
 
       for (i = 0; i < len; ++i)
@@ -15536,7 +16016,7 @@ dependent_type_p (tree type)
       /* If we are not processing a template, then nobody should be
         providing us with a dependent type.  */
       gcc_assert (type);
-      gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM);
+      gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM || is_auto (type));
       return false;
     }
 
@@ -15622,7 +16102,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
@@ -15831,6 +16311,19 @@ type_dependent_expression_p (tree expression)
   if (TREE_CODE (expression) == STMT_EXPR)
     expression = stmt_expr_value_expr (expression);
 
+  if (BRACE_ENCLOSED_INITIALIZER_P (expression))
+    {
+      tree elt;
+      unsigned i;
+
+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), i, elt)
+       {
+         if (type_dependent_expression_p (elt))
+           return true;
+       }
+      return false;
+    }
+
   if (TREE_TYPE (expression) == unknown_type_node)
     {
       if (TREE_CODE (expression) == ADDR_EXPR)
@@ -16051,6 +16544,63 @@ 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 the original TYPENAME_TYPE if
    no such TYPE can be found.  Note that this function peers inside
@@ -16260,4 +16810,141 @@ build_non_dependent_args (tree args)
   return nreverse (new_args);
 }
 
+/* Returns a type which represents 'auto'.  We use a TEMPLATE_TYPE_PARM
+   with a level one deeper than the actual template parms.  */
+
+tree
+make_auto (void)
+{
+  tree au;
+
+  /* ??? Is it worth caching this for multiple autos at the same level?  */
+  au = cxx_make_type (TEMPLATE_TYPE_PARM);
+  TYPE_NAME (au) = build_decl (TYPE_DECL, get_identifier ("auto"), au);
+  TYPE_STUB_DECL (au) = TYPE_NAME (au);
+  TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
+    (0, processing_template_decl + 1, processing_template_decl + 1,
+     TYPE_NAME (au), NULL_TREE);
+  TYPE_CANONICAL (au) = canonical_type_parameter (au);
+  DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
+  SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));
+
+  return au;
+}
+
+/* Replace auto in TYPE with std::initializer_list<auto>.  */
+
+static tree
+listify_autos (tree type, tree auto_node)
+{
+  tree std_init_list = namespace_binding
+    (get_identifier ("initializer_list"), std_node);
+  tree argvec;
+  tree init_auto;
+  if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
+    {    
+      error ("deducing auto from brace-enclosed initializer list requires "
+            "#include <initializer_list>");
+      return error_mark_node;
+    }
+  argvec = make_tree_vec (1);
+  TREE_VEC_ELT (argvec, 0) = auto_node;
+  init_auto = lookup_template_class (std_init_list, argvec, NULL_TREE,
+                                    NULL_TREE, 0, tf_warning_or_error);
+
+  TREE_VEC_ELT (argvec, 0) = init_auto;
+  if (processing_template_decl)
+    argvec = add_to_template_args (current_template_args (), argvec);
+  return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
+}
+
+/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
+   from INIT.  AUTO_NODE is the TEMPLATE_TYPE_PARM used for 'auto' in TYPE.  */
+
+tree
+do_auto_deduction (tree type, tree init, tree auto_node)
+{
+  tree parms, args, tparms, targs;
+  int val;
+
+  /* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
+     with either a new invented type template parameter U or, if the
+     initializer is a braced-init-list (8.5.4), with
+     std::initializer_list<U>.  */
+  if (BRACE_ENCLOSED_INITIALIZER_P (init))
+    type = listify_autos (type, auto_node);
+
+  parms = build_tree_list (NULL_TREE, type);
+  args = build_tree_list (NULL_TREE, init);
+  tparms = make_tree_vec (1);
+  targs = make_tree_vec (1);
+  TREE_VEC_ELT (tparms, 0)
+    = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
+  val = type_unification_real (tparms, targs, parms, args, 0,
+                              DEDUCE_CALL, LOOKUP_NORMAL);
+  if (val > 0)
+    {
+      error ("unable to deduce %qT from %qE", type, init);
+      return error_mark_node;
+    }
+
+  if (processing_template_decl)
+    targs = add_to_template_args (current_template_args (), targs);
+  return tsubst (type, targs, tf_warning_or_error, NULL_TREE);
+}
+
+/* Substitutes LATE_RETURN_TYPE for 'auto' in TYPE and returns the
+   result.  */
+
+tree
+splice_late_return_type (tree type, tree late_return_type)
+{
+  tree argvec;
+
+  if (late_return_type == NULL_TREE)
+    return type;
+  argvec = make_tree_vec (1);
+  TREE_VEC_ELT (argvec, 0) = late_return_type;
+  if (processing_template_decl)
+    argvec = add_to_template_args (current_template_args (), argvec);
+  return tsubst (type, argvec, tf_warning_or_error, NULL_TREE);
+}
+
+/* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto'.  */
+
+bool
+is_auto (const_tree type)
+{
+  if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+      && TYPE_IDENTIFIER (type) == get_identifier ("auto"))
+    return true;
+  else
+    return false;
+}
+
+/* Returns true iff TYPE contains a use of 'auto'.  Since auto can only
+   appear as a type-specifier for the declaration in question, we don't
+   have to look through the whole type.  */
+
+tree
+type_uses_auto (tree type)
+{
+  enum tree_code code;
+  if (is_auto (type))
+    return type;
+
+  code = TREE_CODE (type);
+
+  if (code == POINTER_TYPE || code == REFERENCE_TYPE
+      || code == OFFSET_TYPE || code == FUNCTION_TYPE
+      || code == METHOD_TYPE || code == ARRAY_TYPE)
+    return type_uses_auto (TREE_TYPE (type));
+
+  if (TYPE_PTRMEMFUNC_P (type))
+    return type_uses_auto (TREE_TYPE (TREE_TYPE
+                                  (TYPE_PTRMEMFUNC_FN_TYPE (type))));
+
+  return NULL_TREE;
+}
+
 #include "gt-cp-pt.h"