OSDN Git Service

gcc/objc/
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index c3ce0d1..c609bd0 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle parameterized types (templates) for GNU C++.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 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,14 +125,14 @@ static tree convert_nontype_argument (tree, tree);
 static tree convert_template_argument (tree, tree, tree,
                                       tsubst_flags_t, int, tree);
 static int for_each_template_parm (tree, tree_fn_t, void*,
-                                  struct pointer_set_t*);
+                                  struct pointer_set_t*, bool);
 static tree expand_template_argument_pack (tree);
 static tree build_template_parm_index (int, int, int, tree, tree);
 static bool inline_needs_template_parms (tree);
 static void push_inline_template_parms_recursive (tree, int);
 static tree retrieve_local_specialization (tree);
 static void register_local_specialization (tree, tree);
-static tree reduce_template_parm_level (tree, tree, int);
+static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t);
 static int mark_template_parm (tree, void *);
 static int template_parm_this_level_p (tree, void *);
 static tree tsubst_friend_function (tree, tree);
@@ -158,6 +158,7 @@ static tree get_template_base (tree, tree, tree, tree);
 static tree try_class_unification (tree, tree, tree, tree);
 static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
                                           tree, tree);
+static bool template_template_parm_bindings_ok_p (tree, tree);
 static int template_args_equal (tree, tree);
 static void tsubst_default_arguments (tree);
 static tree for_each_template_parm_r (tree *, int *, void *);
@@ -235,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))
        {
@@ -263,6 +266,25 @@ finish_member_template_decl (tree decl)
   return error_mark_node;
 }
 
+/* Return the template info node corresponding to T, whatever T is.  */
+
+tree
+get_template_info (tree t)
+{
+  tree tinfo = NULL_TREE;
+
+  if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+    tinfo = DECL_TEMPLATE_INFO (t);
+
+  if (!tinfo && TREE_CODE (t) == TYPE_DECL)
+    t = TREE_TYPE (t);
+
+  if (TAGGED_TYPE_P (t))
+    tinfo = TYPE_TEMPLATE_INFO (t);
+
+  return tinfo;
+}
+
 /* Returns the template nesting level of the indicated class TYPE.
 
    For example, in:
@@ -291,20 +313,11 @@ template_class_depth (tree type)
        type = (TREE_CODE (type) == FUNCTION_DECL)
         ? CP_DECL_CONTEXT (type) : TYPE_CONTEXT (type))
     {
-      if (TREE_CODE (type) != FUNCTION_DECL)
-       {
-         if (CLASSTYPE_TEMPLATE_INFO (type)
-             && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
-             && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
-           ++depth;
-       }
-      else
-       {
-         if (DECL_TEMPLATE_INFO (type)
-             && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type))
-             && uses_template_parms (DECL_TI_ARGS (type)))
-           ++depth;
-       }
+      tree tinfo = get_template_info (type);
+
+      if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo))
+         && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo))))
+       ++depth;
     }
 
   return depth;
@@ -371,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);
@@ -698,8 +710,8 @@ check_specialization_namespace (tree tmpl)
     return true;
   else
     {
-      pedwarn ("specialization of %qD in different namespace", tmpl);
-      pedwarn ("  from definition of %q+#D", tmpl);
+      permerror ("specialization of %qD in different namespace", tmpl);
+      permerror ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
@@ -716,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 ("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
@@ -760,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);
@@ -795,9 +811,9 @@ maybe_process_partial_specialization (tree type)
          if (current_namespace
              != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
            {
-             pedwarn ("specializing %q#T in different namespace", type);
-             pedwarn ("  from definition of %q+#D",
-                      CLASSTYPE_TI_TEMPLATE (type));
+             permerror ("specializing %q#T in different namespace", type);
+             permerror ("  from definition of %q+#D",
+                        CLASSTYPE_TI_TEMPLATE (type));
            }
 
          /* Check for invalid specialization after instantiation:
@@ -965,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;
 }
 
@@ -1001,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;
@@ -1012,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]
@@ -1054,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();
@@ -1101,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));
@@ -1111,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)),
@@ -1123,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;
@@ -1136,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);
@@ -1149,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)
@@ -1163,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)),
@@ -1176,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;
@@ -1985,7 +2006,7 @@ check_explicit_specialization (tree declarator,
       for (; t; t = TREE_CHAIN (t))
        if (TREE_PURPOSE (t))
          {
-           pedwarn
+           permerror
              ("default argument specified in explicit specialization");
            break;
          }
@@ -2075,7 +2096,7 @@ check_explicit_specialization (tree declarator,
            {
              int is_constructor = DECL_CONSTRUCTOR_P (decl);
 
-             if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype)
+             if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype)
                  : !CLASSTYPE_DESTRUCTORS (ctype))
                {
                  /* From [temp.expl.spec]:
@@ -2409,16 +2430,20 @@ make_ith_pack_parameter_name (tree name, int i)
   return get_identifier (newname);
 }
 
-/* Structure used to track the progress of find_parameter_pack_r.  */
+/* Structure used to track the progress of find_parameter_packs_r.  */
 struct find_parameter_pack_data 
 {
+  /* TREE_LIST that will contain all of the parameter packs found by
+     the traversal.  */
   tree* parameter_packs;
+
+  /* Set of AST nodes that have been visited by the traversal.  */
   struct pointer_set_t *visited;
 };
 
-/* Identifiers all of the argument packs that occur in a template
+/* Identifies all of the argument packs that occur in a template
    argument and appends them to the TREE_LIST inside DATA, which is a
-   find_parameter_pack_Data structure. This is a subroutine of
+   find_parameter_pack_data structure. This is a subroutine of
    make_pack_expansion and uses_parameter_packs.  */
 static tree
 find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
@@ -2426,49 +2451,69 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
   tree t = *tp;
   struct find_parameter_pack_data* ppd = 
     (struct find_parameter_pack_data*)data;
+  bool parameter_pack_p = false;
 
-  if (TYPE_P (t))
+  /* Identify whether this is a parameter pack or not.  */
+  switch (TREE_CODE (t))
+    {
+    case TEMPLATE_PARM_INDEX:
+      if (TEMPLATE_PARM_PARAMETER_PACK (t))
+        parameter_pack_p = true;
+      break;
+
+    case TEMPLATE_TYPE_PARM:
+    case TEMPLATE_TEMPLATE_PARM:
+      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
+        parameter_pack_p = true;
+      break;
+
+    case PARM_DECL:
+      if (FUNCTION_PARAMETER_PACK_P (t))
+        {
+          /* We don't want to walk into the type of a PARM_DECL,
+             because we don't want to see the type parameter pack.  */
+          *walk_subtrees = 0;
+         parameter_pack_p = true;
+        }
+      break;
+
+    default:
+      /* Not a parameter pack.  */
+      break;
+    }
+
+  if (parameter_pack_p)
     {
-      tree context = TYPE_CONTEXT (t);
-      cp_walk_tree (&context, &find_parameter_packs_r, ppd, ppd->visited);
+      /* Add this parameter pack to the list.  */
+      *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
     }
 
+  if (TYPE_P (t))
+    cp_walk_tree (&TYPE_CONTEXT (t), 
+                 &find_parameter_packs_r, ppd, ppd->visited);
+
   /* This switch statement will return immediately if we don't find a
      parameter pack.  */
   switch (TREE_CODE (t)) 
     {
     case TEMPLATE_PARM_INDEX:
-      if (TEMPLATE_PARM_PARAMETER_PACK (t))
-        break;
       return NULL_TREE;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
+      /* Check the template itself.  */
+      cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)), 
+                   &find_parameter_packs_r, ppd, ppd->visited);
       /* Check the template arguments.  */
       cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, 
                    ppd->visited);
-
-      /* Dig out the underlying TEMPLATE_TEMPLATE_PARM.  */
-      t = TYPE_TI_TEMPLATE (t);
-      if (DECL_P (t) && TREE_TYPE (t))
-        t = TREE_TYPE (t);
       *walk_subtrees = 0;
-      
-      /* Fall through.  */
+      return NULL_TREE;
 
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
-      if (TEMPLATE_TYPE_PARAMETER_PACK (t))
-        break;
       return NULL_TREE;
 
     case PARM_DECL:
-      if (FUNCTION_PARAMETER_PACK_P (t))
-        {
-          /* We don't want to walk into the type of a PARM_DECL,
-             because we don't want to see the type parameter pack.*/
-          *walk_subtrees = 0;
-          break;
-        }
       return NULL_TREE;
 
     case RECORD_TYPE:
@@ -2479,22 +2524,23 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case UNION_TYPE:
     case ENUMERAL_TYPE:
       if (TYPE_TEMPLATE_INFO (t))
-        {
-          tree args = TREE_VALUE (TYPE_TEMPLATE_INFO (t));
-          cp_walk_tree (&args, &find_parameter_packs_r, ppd, ppd->visited);
-        }
+       cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), 
+                     &find_parameter_packs_r, ppd, ppd->visited);
 
       *walk_subtrees = 0;
       return NULL_TREE;
 
     case TEMPLATE_DECL:
-      if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
-         && TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
-       break;
-      
+      cp_walk_tree (&TREE_TYPE (t),
+                   &find_parameter_packs_r, ppd, ppd->visited);
+      return NULL_TREE;
+    case TYPENAME_TYPE:
+      cp_walk_tree (&TYPENAME_TYPE_FULLNAME (t), &find_parameter_packs_r,
+                   ppd, ppd->visited);
       *walk_subtrees = 0;
       return NULL_TREE;
-       
+      
     case TYPE_PACK_EXPANSION:
     case EXPR_PACK_EXPANSION:
       *walk_subtrees = 0;
@@ -2506,12 +2552,15 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
       *walk_subtrees = 0;
       return NULL_TREE;
 
+    case IDENTIFIER_NODE:
+      cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, 
+                   ppd->visited);
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
     default:
       return NULL_TREE;
     }
-  
-  /* Add this parameter pack to the list.  */
-  *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
 
   return NULL_TREE;
 }
@@ -2660,8 +2709,8 @@ 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)
 {
@@ -2669,7 +2718,7 @@ check_for_bare_parameter_packs (tree t)
   struct find_parameter_pack_data ppd;
 
   if (!processing_template_decl || !t || t == error_mark_node)
-    return true;
+    return false;
 
   if (TREE_CODE (t) == TYPE_DECL)
     t = TREE_TYPE (t);
@@ -2681,7 +2730,7 @@ check_for_bare_parameter_packs (tree t)
 
   if (parameter_packs) 
     {
-      error ("parameter packs not expanded with `...':");
+      error ("parameter packs not expanded with %<...%>:");
       while (parameter_packs)
         {
           tree pack = TREE_VALUE (parameter_packs);
@@ -2694,15 +2743,19 @@ check_for_bare_parameter_packs (tree t)
             name = DECL_NAME (TEMPLATE_PARM_DECL (pack));
           else
             name = DECL_NAME (pack);
-          inform ("        %qD", name);
+
+         if (name)
+           inform ("        %qD", name);
+         else
+           inform ("        <anonymous>");
 
           parameter_packs = TREE_CHAIN (parameter_packs);
         }
 
-      return false;
+      return true;
     }
 
-  return true;
+  return false;
 }
 
 /* Expand any parameter packs that occur in the template arguments in
@@ -2820,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;
@@ -2861,7 +2913,8 @@ canonical_type_parameter (tree type)
    new one is created.  */
 
 static tree
-reduce_template_parm_level (tree index, tree type, int levels)
+reduce_template_parm_level (tree index, tree type, int levels, tree args,
+                           tsubst_flags_t complain)
 {
   if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
       || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
@@ -2872,7 +2925,6 @@ reduce_template_parm_level (tree index, tree type, int levels)
 
       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);
@@ -2886,9 +2938,10 @@ reduce_template_parm_level (tree index, tree type, int levels)
        = TEMPLATE_PARM_PARAMETER_PACK (index);
 
        /* Template template parameters need this.  */
-      if (TREE_CODE (decl) != CONST_DECL)
-       DECL_TEMPLATE_PARMS (decl)
-         = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
+      if (TREE_CODE (decl) == TEMPLATE_DECL)
+       DECL_TEMPLATE_PARMS (decl) = tsubst_template_parms
+         (DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)),
+          args, complain);
     }
 
   return TEMPLATE_PARM_DESCENDANTS (index);
@@ -2968,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,
@@ -2989,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;
@@ -2998,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);
        }
@@ -3101,7 +3152,7 @@ current_template_args (void)
            {
              t = TREE_VALUE (t);
 
-             if (t != error_mark_node)
+             if (!error_operand_p (t))
                {
                  if (TREE_CODE (t) == TYPE_DECL
                      || TREE_CODE (t) == TEMPLATE_DECL)
@@ -3136,8 +3187,8 @@ current_template_args (void)
                           TREE_TYPE (t) = type;
                         }
                     }
+                 TREE_VEC_ELT (a, i) = t;
                 }
-             TREE_VEC_ELT (a, i) = t;
            }
        }
 
@@ -3292,7 +3343,8 @@ process_partial_specialization (tree decl)
       for_each_template_parm (TREE_VEC_ELT (inner_args, i),
                              &mark_template_parm,
                              &tpd,
-                             NULL);
+                             NULL,
+                             /*include_nondeduced_p=*/false);
     }
   for (i = 0; i < ntparms; ++i)
     if (tpd.parms[i] == 0)
@@ -3363,7 +3415,10 @@ process_partial_specialization (tree decl)
                   if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
                     error ("parameter pack argument %qE must be at the end of the template argument list", arg);
                   else
-                    error ("parameter pack argument %qT must be at the end of the template argument list", arg);                   
+                    error ("parameter pack argument %qT must be at the end of the template argument list", arg);
+
+                 if (packed_args)
+                   TREE_VEC_ELT (packed_args, j) = error_mark_node;
                 }
             }
 
@@ -3412,7 +3467,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])
                     {
@@ -3448,10 +3504,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
@@ -3536,6 +3593,29 @@ 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
+                      && 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;
+               }
             }
         }
     }
@@ -3715,7 +3795,10 @@ push_template_decl_real (tree decl, bool is_friend)
        member_template_p = true;
       if (TREE_CODE (decl) == TYPE_DECL
          && ANON_AGGRNAME_P (DECL_NAME (decl)))
-       error ("template class without a name");
+       {
+         error ("template class without a name");
+         return error_mark_node;
+       }
       else if (TREE_CODE (decl) == FUNCTION_DECL)
        {
          if (DECL_DESTRUCTOR_P (decl))
@@ -3770,7 +3853,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
@@ -3786,38 +3869,23 @@ push_template_decl_real (tree decl, bool is_friend)
 
       /* Check for bare parameter packs in the return type and the
          exception specifiers.  */
-      check_for_bare_parameter_packs (TREE_TYPE (type));
-      check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (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;
+      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
-    check_for_bare_parameter_packs (TREE_TYPE (decl));
 
   if (is_partial)
     return process_partial_specialization (decl);
 
-  /* A primary class template can only have one parameter pack, at the
-     end of the template parameter list.  */
-  if (primary && TREE_CODE (decl) == TYPE_DECL)
-    {
-      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));
-           }
-        }
-    }
-
   args = current_template_args ();
 
   if (!ctx
@@ -3866,27 +3934,15 @@ push_template_decl_real (tree decl, bool is_friend)
     {
       tree a, t, current, parms;
       int i;
+      tree tinfo = get_template_info (decl);
 
-      if (TREE_CODE (decl) == TYPE_DECL)
-       {
-         if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl)))
-              || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
-             && TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
-             && TYPE_TI_TEMPLATE (TREE_TYPE (decl)))
-           tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl));
-         else
-           {
-             error ("%qD does not declare a template type", decl);
-             return decl;
-           }
-       }
-      else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl))
+      if (!tinfo)
        {
          error ("template definition of non-template %q#D", decl);
-         return decl;
+         return error_mark_node;
        }
-      else
-       tmpl = DECL_TI_TEMPLATE (decl);
+
+      tmpl = TI_TEMPLATE (tinfo);
 
       if (DECL_FUNCTION_TEMPLATE_P (tmpl)
          && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
@@ -3946,9 +4002,6 @@ push_template_decl_real (tree decl, bool is_friend)
                return error_mark_node;
              }
 
-           /* Perhaps we should also check that the parms are used in the
-              appropriate qualifying scopes in the declarator?  */
-
            if (current == decl)
              current = ctx;
            else
@@ -3956,6 +4009,22 @@ push_template_decl_real (tree decl, bool is_friend)
                         ? TYPE_CONTEXT (current)
                         : DECL_CONTEXT (current));
          }
+
+      /* Check that the parms are used in the appropriate qualifying scopes
+        in the declarator.  */
+      if (!comp_template_args
+         (TI_ARGS (tinfo),
+          TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl)))))
+       {
+         error ("\
+template arguments to %qD do not match original template %qD",
+                decl, DECL_TEMPLATE_RESULT (tmpl));
+         if (!uses_template_parms (TI_ARGS (tinfo)))
+           inform ("use template<> for an explicit specialization");
+         /* Avoid crash in import_export_decl.  */
+         DECL_INTERFACE_KNOWN (decl) = 1;
+         return error_mark_node;
+       }
     }
 
   DECL_TEMPLATE_RESULT (tmpl) = decl;
@@ -3982,10 +4051,13 @@ push_template_decl_real (tree decl, bool is_friend)
 
   if (primary)
     {
+      tree parms = DECL_TEMPLATE_PARMS (tmpl);
+      int i;
+
       DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
       if (DECL_CONV_FN_P (tmpl))
        {
-         int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl));
+         int depth = TMPL_PARMS_DEPTH (parms);
 
          /* It is a conversion operator. See if the type converted to
             depends on innermost template operands.  */
@@ -3994,6 +4066,16 @@ push_template_decl_real (tree decl, bool is_friend)
                                         depth))
            DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
        }
+
+      /* Give template template parms a DECL_CONTEXT of the template
+        for which they are a parameter.  */
+      parms = INNERMOST_TEMPLATE_PARMS (parms);
+      for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
+       {
+         tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+         if (TREE_CODE (parm) == TEMPLATE_DECL)
+           DECL_CONTEXT (parm) = tmpl;
+       }
     }
 
   /* The DECL_TI_ARGS of DECL contains full set of arguments referring
@@ -4057,10 +4139,10 @@ redeclare_class_template (tree type, tree parms)
 
   if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
     {
-      error ("previous declaration %q+D", tmpl);
-      error ("used %d template parameter(s) instead of %d",
-            TREE_VEC_LENGTH (tmpl_parms),
-            TREE_VEC_LENGTH (parms));
+      error ("redeclared with %d template parameter(s)", 
+             TREE_VEC_LENGTH (parms));
+      inform ("previous declaration %q+D used %d template parameter(s)", 
+             tmpl, TREE_VEC_LENGTH (tmpl_parms));
       return false;
     }
 
@@ -4083,9 +4165,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);
@@ -4099,7 +4187,7 @@ redeclare_class_template (tree type, tree parms)
             A template-parameter may not be given default arguments
             by two different declarations in the same scope.  */
          error ("redefinition of default argument for %q#D", parm);
-         error ("%J  original definition appeared here", tmpl_parm);
+         inform ("%Joriginal definition appeared here", tmpl_parm);
          return false;
        }
 
@@ -4153,7 +4241,7 @@ fold_non_dependent_expr (tree expr)
 
 /* EXPR is an expression which is used in a constant-expression context.
    For instance, it could be a VAR_DECL with a constant initializer.
-   Extract the innest constant expression.
+   Extract the innermost constant expression.
 
    This is basically a more powerful version of
    integral_constant_value, which can be used also in templates where
@@ -4544,6 +4632,77 @@ convert_nontype_argument (tree type, tree expr)
   return expr;
 }
 
+/* Subroutine of coerce_template_template_parms, which returns 1 if
+   PARM_PARM and ARG_PARM match using the rule for the template
+   parameters of template template parameters. Both PARM and ARG are
+   template parameters; the rest of the arguments are the same as for
+   coerce_template_template_parms.
+ */
+static int
+coerce_template_template_parm (tree parm,
+                              tree arg,
+                              tsubst_flags_t complain,
+                              tree in_decl,
+                              tree outer_args)
+{
+  if (arg == NULL_TREE || arg == error_mark_node
+      || parm == NULL_TREE || parm == error_mark_node)
+    return 0;
+  
+  if (TREE_CODE (arg) != TREE_CODE (parm))
+    return 0;
+  
+  switch (TREE_CODE (parm))
+    {
+    case TEMPLATE_DECL:
+      /* We encounter instantiations of templates like
+        template <template <template <class> class> class TT>
+        class C;  */
+      {
+       tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+       tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+       
+       if (!coerce_template_template_parms
+           (parmparm, argparm, complain, in_decl, outer_args))
+         return 0;
+      }
+      /* Fall through.  */
+      
+    case TYPE_DECL:
+      if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (arg))
+         && !TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm)))
+       /* Argument is a parameter pack but parameter is not.  */
+       return 0;
+      break;
+      
+    case PARM_DECL:
+      /* The tsubst call is used to handle cases such as
+        
+           template <int> class C {};
+          template <class T, template <T> class TT> class D {};
+          D<int, C> d;
+
+        i.e. the parameter list of TT depends on earlier parameters.  */
+      if (!dependent_type_p (TREE_TYPE (arg))
+         && !same_type_p
+               (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
+                TREE_TYPE (arg)))
+       return 0;
+      
+      if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (arg))
+         && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
+       /* Argument is a parameter pack but parameter is not.  */
+       return 0;
+      
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return 1;
+}
+
 
 /* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for
    template template parameters.  Both PARM_PARMS and ARG_PARMS are
@@ -4566,6 +4725,7 @@ coerce_template_template_parms (tree parm_parms,
 {
   int nparms, nargs, i;
   tree parm, arg;
+  int variadic_p = 0;
 
   gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
   gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
@@ -4573,10 +4733,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)
@@ -4585,61 +4772,116 @@ 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)
+      if (!coerce_template_template_parm (parm, arg, complain, in_decl,
+                                          outer_args))
        return 0;
 
-      if (TREE_CODE (arg) != TREE_CODE (parm))
+    }
+
+  if (variadic_p)
+    {
+      /* Check each of the template parameters in the template
+        argument against the template parameter pack at the end of
+        the template template parameter.  */
+      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node)
        return 0;
 
-      switch (TREE_CODE (parm))
-       {
-       case 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);
+      parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
 
-           if (!coerce_template_template_parms
-               (parmparm, argparm, complain, in_decl, outer_args))
-             return 0;
-         }
-         /* Fall through.  */
+      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;
+        }
+    }
 
-       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;
+  return 1;
+}
 
-       case PARM_DECL:
-         /* The tsubst call is used to handle cases such as
+/* Verifies that the deduced template arguments (in TARGS) for the
+   template template parameters (in TPARMS) represent valid bindings,
+   by comparing the template parameter list of each template argument
+   to the template parameter list of its corresponding template
+   template parameter, in accordance with DR150. This
+   routine can only be called after all template arguments have been
+   deduced. It will return TRUE if all of the template template
+   parameter bindings are okay, FALSE otherwise.  */
+bool 
+template_template_parm_bindings_ok_p (tree tparms, tree targs)
+{
+  int i, ntparms = TREE_VEC_LENGTH (tparms);
+  bool ret = true;
 
-              template <int> class C {};
-              template <class T, template <T> class TT> class D {};
-              D<int, C> d;
+  /* We're dealing with template parms in this process.  */
+  ++processing_template_decl;
 
-            i.e. the parameter list of TT depends on earlier parameters.  */
-         if (!dependent_type_p (TREE_TYPE (arg))
-             && !same_type_p
-                   (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
-                            TREE_TYPE (arg)))
-           return 0;
+  targs = INNERMOST_TEMPLATE_ARGS (targs);
 
-         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;
+  for (i = 0; i < ntparms; ++i)
+    {
+      tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+      tree targ = TREE_VEC_ELT (targs, i);
 
-       default:
-         gcc_unreachable ();
+      if (TREE_CODE (tparm) == TEMPLATE_DECL && targ)
+       {
+         tree packed_args = NULL_TREE;
+         int idx, len = 1;
+
+         if (ARGUMENT_PACK_P (targ))
+           {
+             /* Look inside the argument pack.  */
+             packed_args = ARGUMENT_PACK_ARGS (targ);
+             len = TREE_VEC_LENGTH (packed_args);
+           }
+
+         for (idx = 0; idx < len; ++idx)
+           {
+             tree targ_parms = NULL_TREE;
+
+             if (packed_args)
+               /* Extract the next argument from the argument
+                  pack.  */
+               targ = TREE_VEC_ELT (packed_args, idx);
+
+             if (PACK_EXPANSION_P (targ))
+               /* Look at the pattern of the pack expansion.  */
+               targ = PACK_EXPANSION_PATTERN (targ);
+
+             /* Extract the template parameters from the template
+                argument.  */
+             if (TREE_CODE (targ) == TEMPLATE_DECL)
+               targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (targ);
+             else if (TREE_CODE (targ) == TEMPLATE_TEMPLATE_PARM)
+               targ_parms = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_NAME (targ));
+
+             /* Verify that we can coerce the template template
+                parameters from the template argument to the template
+                parameter.  This requires an exact match.  */
+             if (targ_parms
+                 && !coerce_template_template_parms
+                      (DECL_INNERMOST_TEMPLATE_PARMS (tparm),
+                       targ_parms,
+                       tf_none,
+                       tparm,
+                       targs))
+               {
+                 ret = false;
+                 goto out;
+               }
+           }
        }
     }
-  return 1;
+
+ out:
+
+  --processing_template_decl;
+  return ret;
 }
 
 /* Convert the indicated template ARG as necessary to match the
@@ -4657,9 +4899,9 @@ convert_template_argument (tree parm,
                           int i,
                           tree in_decl)
 {
+  tree orig_arg;
   tree val;
   int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
-  tree check_arg = arg;
 
   if (TREE_CODE (arg) == TREE_LIST
       && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
@@ -4669,24 +4911,26 @@ convert_template_argument (tree parm,
         invalid, but static members are OK.  In any
         case, grab the underlying fields/functions
         and issue an error later if required.  */
-      arg = TREE_VALUE (arg);
+      orig_arg = TREE_VALUE (arg);
       TREE_TYPE (arg) = unknown_type_node;
     }
 
+  orig_arg = arg;
+
   requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
   requires_type = (TREE_CODE (parm) == TYPE_DECL
                   || requires_tmpl_type);
 
   /* When determining whether an argument pack expansion is a template,
      look at the pattern.  */
-  if (TREE_CODE (check_arg) == TYPE_PACK_EXPANSION)
-    check_arg = PACK_EXPANSION_PATTERN (check_arg);
+  if (TREE_CODE (arg) == TYPE_PACK_EXPANSION)
+    arg = PACK_EXPANSION_PATTERN (arg);
 
   is_tmpl_type = 
-    ((TREE_CODE (check_arg) == TEMPLATE_DECL
-      && TREE_CODE (DECL_TEMPLATE_RESULT (check_arg)) == TYPE_DECL)
-     || TREE_CODE (check_arg) == TEMPLATE_TEMPLATE_PARM
-     || TREE_CODE (check_arg) == UNBOUND_CLASS_TEMPLATE);
+    ((TREE_CODE (arg) == TEMPLATE_DECL
+      && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+     || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+     || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
 
   if (is_tmpl_type
       && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
@@ -4698,13 +4942,14 @@ convert_template_argument (tree parm,
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      pedwarn ("to refer to a type member of a template parameter, "
-              "use %<typename %E%>", arg);
-
-      arg = make_typename_type (TREE_OPERAND (arg, 0),
-                               TREE_OPERAND (arg, 1),
-                               typename_type,
-                               complain & tf_error);
+      permerror ("to refer to a type member of a template parameter, "
+                "use %<typename %E%>", orig_arg);
+
+      orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
+                                    TREE_OPERAND (arg, 1),
+                                    typename_type,
+                                    complain & tf_error);
+      arg = orig_arg;
       is_type = 1;
     }
   if (is_type != requires_type)
@@ -4719,11 +4964,11 @@ convert_template_argument (tree parm,
              if (is_type)
                error ("  expected a constant of type %qT, got %qT",
                       TREE_TYPE (parm),
-                      (is_tmpl_type ? DECL_NAME (arg) : arg));
+                      (DECL_P (arg) ? DECL_NAME (arg) : orig_arg));
              else if (requires_tmpl_type)
-               error ("  expected a class template, got %qE", arg);
+               error ("  expected a class template, got %qE", orig_arg);
              else
-               error ("  expected a type, got %qE", arg);
+               error ("  expected a type, got %qE", orig_arg);
            }
        }
       return error_mark_node;
@@ -4738,7 +4983,7 @@ convert_template_argument (tree parm,
          if (is_tmpl_type)
            error ("  expected a type, got %qT", DECL_NAME (arg));
          else
-           error ("  expected a class template, got %qT", arg);
+           error ("  expected a class template, got %qT", orig_arg);
        }
       return error_mark_node;
     }
@@ -4756,19 +5001,13 @@ convert_template_argument (tree parm,
              tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
              tree argparm;
 
-              check_arg = arg;
-              /* When determining whether a pack expansion is a template,
-                 look at the pattern.  */
-              if (TREE_CODE (check_arg) == TYPE_PACK_EXPANSION)
-                check_arg = PACK_EXPANSION_PATTERN (check_arg);
-
-              argparm = DECL_INNERMOST_TEMPLATE_PARMS (check_arg);
+              argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
 
              if (coerce_template_template_parms (parmparm, argparm,
                                                  complain, in_decl,
                                                  args))
                {
-                 val = arg;
+                 val = orig_arg;
 
                  /* TEMPLATE_TEMPLATE_PARM node is preferred over
                     TEMPLATE_DECL.  */
@@ -4777,9 +5016,9 @@ convert_template_argument (tree parm,
                       if (DECL_TEMPLATE_TEMPLATE_PARM_P (val))
                         val = TREE_TYPE (val);
                       else if (TREE_CODE (val) == TYPE_PACK_EXPANSION
-                               && DECL_TEMPLATE_TEMPLATE_PARM_P (check_arg))
+                               && DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
                         {
-                          val = TREE_TYPE (check_arg);
+                          val = TREE_TYPE (arg);
                           val = make_pack_expansion (val);
                         }
                     }
@@ -4792,7 +5031,7 @@ convert_template_argument (tree parm,
                             "template parameter list for %qD",
                             i + 1, in_decl);
                      error ("  expected a template of type %qD, got %qD",
-                            parm, arg);
+                            parm, orig_arg);
                    }
 
                  val = error_mark_node;
@@ -4800,7 +5039,7 @@ convert_template_argument (tree parm,
            }
        }
       else
-       val = arg;
+       val = orig_arg;
       /* We only form one instance of each template specialization.
         Therefore, if we use a non-canonical variant (i.e., a
         typedef), any future messages referring to the type will use
@@ -4816,7 +5055,7 @@ convert_template_argument (tree parm,
       if (invalid_nontype_parm_type_p (t, complain))
        return error_mark_node;
 
-      if (!uses_template_parms (arg) && !uses_template_parms (t))
+      if (!uses_template_parms (orig_arg) && !uses_template_parms (t))
        /* We used to call digest_init here.  However, digest_init
           will report errors, which we don't want when complain
           is zero.  More importantly, digest_init will try too
@@ -4827,14 +5066,14 @@ convert_template_argument (tree parm,
           conversions can occur is part of determining which
           function template to call, or whether a given explicit
           argument specification is valid.  */
-       val = convert_nontype_argument (t, arg);
+       val = convert_nontype_argument (t, orig_arg);
       else
-       val = arg;
+       val = orig_arg;
 
       if (val == NULL_TREE)
        val = error_mark_node;
       else if (val == error_mark_node && (complain & tf_error))
-       error ("could not convert template argument %qE to %qT",  arg, t);
+       error ("could not convert template argument %qE to %qT",  orig_arg, t);
     }
 
   return val;
@@ -4948,7 +5187,8 @@ coerce_template_parameter_pack (tree parms,
   else
     {
       argument_pack = make_node (NONTYPE_ARGUMENT_PACK);
-      TREE_TYPE (argument_pack) = TREE_TYPE (TREE_VALUE (parm));
+      TREE_TYPE (argument_pack) 
+        = tsubst (TREE_TYPE (TREE_VALUE (parm)), new_args, complain, in_decl);
       TREE_CONSTANT (argument_pack) = 1;
     }
 
@@ -5077,16 +5317,19 @@ coerce_template_parms (tree parms,
 
           if (arg && PACK_EXPANSION_P (arg))
             {
-              /* If ARG is a pack expansion, but PARM is not a
-                 template parameter pack (if it were, we would have
-                 handled it above), we're trying to expand into a
-                 fixed-length argument list.  */
-              if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
-                error ("cannot expand %<%E%> into a fixed-length "
-                       "argument list", arg);
-              else
-                error ("cannot expand %<%T%> into a fixed-length "
-                       "argument list", arg);
+             if (complain & tf_error)
+               {
+                 /* If ARG is a pack expansion, but PARM is not a
+                    template parameter pack (if it were, we would have
+                    handled it above), we're trying to expand into a
+                    fixed-length argument list.  */
+                 if (TREE_CODE (arg) == EXPR_PACK_EXPANSION)
+                   error ("cannot expand %<%E%> into a fixed-length "
+                          "argument list", arg);
+                 else
+                   error ("cannot expand %<%T%> into a fixed-length "
+                          "argument list", arg);
+               }
              return error_mark_node;
             }
         }
@@ -5293,7 +5536,7 @@ lookup_template_class (tree d1,
                       int entering_scope,
                       tsubst_flags_t complain)
 {
-  tree template = NULL_TREE, parmlist;
+  tree templ = NULL_TREE, parmlist;
   tree t;
 
   timevar_push (TV_NAME_LOOKUP);
@@ -5302,20 +5545,20 @@ lookup_template_class (tree d1,
     {
       tree value = innermost_non_namespace_value (d1);
       if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
-       template = value;
+       templ = value;
       else
        {
          if (context)
            push_decl_namespace (context);
-         template = lookup_name (d1);
-         template = maybe_get_template_decl_from_type_decl (template);
+         templ = lookup_name (d1);
+         templ = maybe_get_template_decl_from_type_decl (templ);
          if (context)
            pop_decl_namespace ();
        }
-      if (template)
-       context = DECL_CONTEXT (template);
+      if (templ)
+       context = DECL_CONTEXT (templ);
     }
-  else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
+  else if (TREE_CODE (d1) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (d1)))
     {
       tree type = TREE_TYPE (d1);
 
@@ -5326,37 +5569,37 @@ lookup_template_class (tree d1,
 
       if (CLASSTYPE_TEMPLATE_INFO (type))
        {
-         template = CLASSTYPE_TI_TEMPLATE (type);
-         d1 = DECL_NAME (template);
+         templ = CLASSTYPE_TI_TEMPLATE (type);
+         d1 = DECL_NAME (templ);
        }
     }
   else if (TREE_CODE (d1) == ENUMERAL_TYPE
-          || (TYPE_P (d1) && IS_AGGR_TYPE (d1)))
+          || (TYPE_P (d1) && MAYBE_CLASS_TYPE_P (d1)))
     {
-      template = TYPE_TI_TEMPLATE (d1);
-      d1 = DECL_NAME (template);
+      templ = TYPE_TI_TEMPLATE (d1);
+      d1 = DECL_NAME (templ);
     }
   else if (TREE_CODE (d1) == TEMPLATE_DECL
           && TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL)
     {
-      template = d1;
-      d1 = DECL_NAME (template);
-      context = DECL_CONTEXT (template);
+      templ = d1;
+      d1 = DECL_NAME (templ);
+      context = DECL_CONTEXT (templ);
     }
 
   /* Issue an error message if we didn't find a template.  */
-  if (! template)
+  if (! templ)
     {
       if (complain & tf_error)
        error ("%qT is not a template", d1);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
     }
 
-  if (TREE_CODE (template) != TEMPLATE_DECL
+  if (TREE_CODE (templ) != TEMPLATE_DECL
         /* Make sure it's a user visible template, if it was named by
            the user.  */
-      || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
-         && !PRIMARY_TEMPLATE_P (template)))
+      || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (templ)
+         && !PRIMARY_TEMPLATE_P (templ)))
     {
       if (complain & tf_error)
        {
@@ -5369,15 +5612,16 @@ lookup_template_class (tree d1,
 
   complain &= ~tf_user;
 
-  if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
+  if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
     {
       /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
         template arguments */
 
       tree parm;
       tree arglist2;
+      tree outer;
 
-      parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
+      parmlist = DECL_INNERMOST_TEMPLATE_PARMS (templ);
 
       /* Consider an example where a template template parameter declared as
 
@@ -5388,31 +5632,39 @@ lookup_template_class (tree d1,
         instantiation `TT<int>' is seen, we need to build the full
         arguments containing {int} as the innermost level.  Outer levels,
         available when not appearing as default template argument, can be
-        obtained from `current_template_args ()'.
+        obtained from the arguments of the enclosing template.
 
         Suppose that TT is later substituted with std::vector.  The above
         instantiation is `TT<int, std::allocator<T> >' with TT at
         level 1, and T at level 2, while the template arguments at level 1
         becomes {std::vector} and the inner level 2 is {int}.  */
 
-      if (current_template_parms)
-       arglist = add_to_template_args (current_template_args (), arglist);
+      outer = DECL_CONTEXT (templ);
+      if (outer)
+       outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
+      else if (current_template_parms)
+       /* This is an argument of the current template, so we haven't set
+          DECL_CONTEXT yet.  */
+       outer = current_template_args ();
+
+      if (outer)
+       arglist = add_to_template_args (outer, arglist);
 
-      arglist2 = coerce_template_parms (parmlist, arglist, template,
+      arglist2 = coerce_template_parms (parmlist, arglist, templ,
                                        complain,
                                        /*require_all_args=*/true,
                                        /*use_default_args=*/true);
       if (arglist2 == error_mark_node
          || (!uses_template_parms (arglist2)
-             && check_instantiated_args (template, arglist2, complain)))
+             && check_instantiated_args (templ, arglist2, complain)))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
-      parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
+      parm = bind_template_template_parm (TREE_TYPE (templ), arglist2);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
     }
   else
     {
-      tree template_type = TREE_TYPE (template);
+      tree template_type = TREE_TYPE (templ);
       tree gen_tmpl;
       tree type_decl;
       tree found = NULL_TREE;
@@ -5420,7 +5672,7 @@ lookup_template_class (tree d1,
       int parm_depth;
       int is_partial_instantiation;
 
-      gen_tmpl = most_general_template (template);
+      gen_tmpl = most_general_template (templ);
       parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
       parm_depth = TMPL_PARMS_DEPTH (parmlist);
       arg_depth = TMPL_ARGS_DEPTH (arglist);
@@ -5440,7 +5692,7 @@ lookup_template_class (tree d1,
             <class U> struct S1<T>::S2'.  We must fill in the missing
             arguments.  */
          arglist
-           = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (template)),
+           = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)),
                                           arglist);
          arg_depth = TMPL_ARGS_DEPTH (arglist);
        }
@@ -5450,7 +5702,7 @@ lookup_template_class (tree d1,
 
       /* From here on, we're only interested in the most general
         template.  */
-      template = gen_tmpl;
+      templ = gen_tmpl;
 
       /* Calculate the BOUND_ARGS.  These will be the args that are
         actually tsubst'd into the definition to create the
@@ -5464,12 +5716,12 @@ lookup_template_class (tree d1,
          tree bound_args = make_tree_vec (parm_depth);
 
          for (i = saved_depth,
-                t = DECL_TEMPLATE_PARMS (template);
+                t = DECL_TEMPLATE_PARMS (templ);
               i > 0 && t != NULL_TREE;
               --i, t = TREE_CHAIN (t))
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
-                                             arglist, template,
+                                             arglist, templ,
                                              complain,
                                              /*require_all_args=*/true,
                                              /*use_default_args=*/true);
@@ -5500,7 +5752,7 @@ lookup_template_class (tree d1,
        arglist
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
-                                  template,
+                                  templ,
                                   complain,
                                   /*require_all_args=*/true,
                                   /*use_default_args=*/true);
@@ -5522,7 +5774,7 @@ lookup_template_class (tree d1,
        {
          found = template_type;
 
-         if (!entering_scope && PRIMARY_TEMPLATE_P (template))
+         if (!entering_scope && PRIMARY_TEMPLATE_P (templ))
            {
              tree ctx;
 
@@ -5544,7 +5796,7 @@ lookup_template_class (tree d1,
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
 
       /* If we already have this specialization, return it.  */
-      found = retrieve_specialization (template, arglist,
+      found = retrieve_specialization (templ, arglist,
                                       /*class_specializations_p=*/false);
       if (found)
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
@@ -5558,22 +5810,22 @@ lookup_template_class (tree d1,
       /* If the deduced arguments are invalid, then the binding
         failed.  */
       if (!is_partial_instantiation
-         && check_instantiated_args (template,
+         && check_instantiated_args (templ,
                                      INNERMOST_TEMPLATE_ARGS (arglist),
                                      complain))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
       if (!is_partial_instantiation
-         && !PRIMARY_TEMPLATE_P (template)
-         && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
+         && !PRIMARY_TEMPLATE_P (templ)
+         && TREE_CODE (CP_DECL_CONTEXT (templ)) == NAMESPACE_DECL)
        {
-         found = xref_tag_from_type (TREE_TYPE (template),
-                                     DECL_NAME (template),
+         found = xref_tag_from_type (TREE_TYPE (templ),
+                                     DECL_NAME (templ),
                                      /*tag_scope=*/ts_global);
          POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
        }
 
-      context = tsubst (DECL_CONTEXT (template), arglist,
+      context = tsubst (DECL_CONTEXT (templ), arglist,
                        complain, in_decl);
       if (!context)
        context = global_namespace;
@@ -5595,7 +5847,7 @@ lookup_template_class (tree d1,
        }
       else
        {
-         t = make_aggr_type (TREE_CODE (template_type));
+         t = make_class_type (TREE_CODE (template_type));
          CLASSTYPE_DECLARED_CLASS (t)
            = CLASSTYPE_DECLARED_CLASS (template_type);
          SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
@@ -5603,7 +5855,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
@@ -5623,7 +5875,7 @@ lookup_template_class (tree d1,
        {
          TYPE_CONTEXT (t) = FROB_CONTEXT (context);
 
-         type_decl = create_implicit_typedef (DECL_NAME (template), t);
+         type_decl = create_implicit_typedef (DECL_NAME (templ), t);
          DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
          TYPE_STUB_DECL (t) = type_decl;
          DECL_SOURCE_LOCATION (type_decl)
@@ -5636,8 +5888,6 @@ lookup_template_class (tree d1,
        = TREE_PRIVATE (TYPE_STUB_DECL (template_type));
       TREE_PROTECTED (type_decl)
        = TREE_PROTECTED (TYPE_STUB_DECL (template_type));
-      DECL_IN_SYSTEM_HEADER (type_decl)
-       = DECL_IN_SYSTEM_HEADER (template);
       if (CLASSTYPE_VISIBILITY_SPECIFIED (template_type))
        {
          DECL_VISIBILITY_SPECIFIED (type_decl) = 1;
@@ -5648,15 +5898,15 @@ lookup_template_class (tree d1,
         template is the immediate parent if this is a full
         instantiation.  */
       if (parm_depth == 1 || is_partial_instantiation
-         || !PRIMARY_TEMPLATE_P (template))
+         || !PRIMARY_TEMPLATE_P (templ))
        /* This case is easy; there are no member templates involved.  */
-       found = template;
+       found = templ;
       else
        {
          /* This is a full instantiation of a member template.  Look
             for a partial instantiation of which this is an instance.  */
 
-         for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
+         for (found = DECL_TEMPLATE_INSTANTIATIONS (templ);
               found; found = TREE_CHAIN (found))
            {
              int success;
@@ -5701,15 +5951,15 @@ lookup_template_class (tree d1,
                 Create the partial instantiation.
               */
              TREE_VEC_LENGTH (arglist)--;
-             found = tsubst (template, arglist, complain, NULL_TREE);
+             found = tsubst (templ, arglist, complain, NULL_TREE);
              TREE_VEC_LENGTH (arglist)++;
            }
        }
 
       SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
-      DECL_TEMPLATE_INSTANTIATIONS (template)
+      DECL_TEMPLATE_INSTANTIATIONS (templ)
        = tree_cons (arglist, t,
-                    DECL_TEMPLATE_INSTANTIATIONS (template));
+                    DECL_TEMPLATE_INSTANTIATIONS (templ));
 
       if (TREE_CODE (t) == ENUMERAL_TYPE
          && !is_partial_instantiation)
@@ -5740,6 +5990,9 @@ struct pair_fn_data
 {
   tree_fn_t fn;
   void *data;
+  /* True when we should also visit template parameters that occur in
+     non-deduced contexts.  */
+  bool include_nondeduced_p;
   struct pointer_set_t *visited;
 };
 
@@ -5754,7 +6007,9 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
   void *data = pfd->data;
 
   if (TYPE_P (t)
-      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited))
+      && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE)
+      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited,
+                                pfd->include_nondeduced_p))
     return error_mark_node;
 
   switch (TREE_CODE (t))
@@ -5769,15 +6024,18 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       if (!TYPE_TEMPLATE_INFO (t))
        *walk_subtrees = 0;
       else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
-                                      fn, data, pfd->visited))
+                                      fn, data, pfd->visited, 
+                                      pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case INTEGER_TYPE:
       if (for_each_template_parm (TYPE_MIN_VALUE (t),
-                                 fn, data, pfd->visited)
+                                 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;
 
@@ -5785,13 +6043,14 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       /* Since we're not going to walk subtrees, we have to do this
         explicitly here.  */
       if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
-                                 pfd->visited))
+                                 pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
     case FUNCTION_TYPE:
       /* Check the return type.  */
-      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
+      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+                                 pfd->include_nondeduced_p))
        return error_mark_node;
 
       /* Check the parameter types.  Since default arguments are not
@@ -5805,7 +6064,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
 
        for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
          if (for_each_template_parm (TREE_VALUE (parm), fn, data,
-                                     pfd->visited))
+                                     pfd->visited, pfd->include_nondeduced_p))
            return error_mark_node;
 
        /* Since we've already handled the TYPE_ARG_TYPES, we don't
@@ -5815,8 +6074,10 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       break;
 
     case TYPEOF_TYPE:
-      if (for_each_template_parm (TYPE_FIELDS (t), fn, data,
-                                 pfd->visited))
+      if (pfd->include_nondeduced_p
+         && for_each_template_parm (TYPE_FIELDS (t), fn, data,
+                                    pfd->visited, 
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5824,7 +6085,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case VAR_DECL:
       if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
          && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
@@ -5832,17 +6093,19 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case CONST_DECL:
       if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
          && for_each_template_parm (DECL_INITIAL (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       if (DECL_CONTEXT (t)
+         && pfd->include_nondeduced_p
          && for_each_template_parm (DECL_CONTEXT (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Record template parameters such as `T' inside `TT<T>'.  */
-      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited))
+      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
+                                 pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
@@ -5858,7 +6121,8 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case TEMPLATE_DECL:
       /* A template template parameter is encountered.  */
       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
-         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
+         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
 
       /* Already substituted template template parameter */
@@ -5868,15 +6132,17 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case TYPENAME_TYPE:
       if (!fn
          || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
-                                    data, pfd->visited))
+                                    data, pfd->visited, 
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case CONSTRUCTOR:
       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
+         && pfd->include_nondeduced_p
          && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
                                     (TREE_TYPE (t)), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5917,11 +6183,16 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
    for_each_template_parm returns 1.  Otherwise, the iteration
    continues.  If FN never returns a nonzero value, the value
    returned by for_each_template_parm is 0.  If FN is NULL, it is
-   considered to be the function which always returns 1.  */
+   considered to be the function which always returns 1.
+
+   If INCLUDE_NONDEDUCED_P, then this routine will also visit template
+   parameters that occur in non-deduced contexts.  When false, only
+   visits those template parameters that can be deduced.  */
 
 static int
 for_each_template_parm (tree t, tree_fn_t fn, void* data,
-                       struct pointer_set_t *visited)
+                       struct pointer_set_t *visited,
+                       bool include_nondeduced_p)
 {
   struct pair_fn_data pfd;
   int result;
@@ -5929,6 +6200,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
   /* Set up.  */
   pfd.fn = fn;
   pfd.data = data;
+  pfd.include_nondeduced_p = include_nondeduced_p;
 
   /* Walk the tree.  (Conceptually, we would like to walk without
      duplicates, but for_each_template_parm_r recursively calls
@@ -6000,7 +6272,8 @@ uses_template_parms (tree t)
 int
 uses_template_parms_level (tree t, int level)
 {
-  return for_each_template_parm (t, template_parm_this_level_p, &level, NULL);
+  return for_each_template_parm (t, template_parm_this_level_p, &level, NULL,
+                                /*include_nondeduced_p=*/true);
 }
 
 static int tinst_depth;
@@ -6017,7 +6290,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)
     {
@@ -6037,12 +6310,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
@@ -6063,7 +6336,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;
@@ -6129,7 +6401,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,
@@ -6420,9 +6692,15 @@ tsubst_friend_class (tree friend_tmpl, tree args)
          > TMPL_ARGS_DEPTH (args))
        {
          tree parms;
+          location_t saved_input_location;
          parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
                                         args, tf_warning_or_error);
+
+          saved_input_location = input_location;
+          input_location = DECL_SOURCE_LOCATION (friend_tmpl);
          redeclare_class_template (TREE_TYPE (tmpl), parms);
+          input_location = saved_input_location;
+          
        }
 
       friend_type = TREE_TYPE (tmpl);
@@ -6488,29 +6766,77 @@ static void
 apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
                                tree args, tsubst_flags_t complain, tree in_decl)
 {
-  tree late_attrs = NULL_TREE;
+  tree last_dep = NULL_TREE;
   tree t;
+  tree *p;
+
+  for (t = attributes; t; t = TREE_CHAIN (t))
+    if (ATTR_IS_DEPENDENT (t))
+      {
+       last_dep = t;
+       attributes = copy_list (attributes);
+       break;
+      }
 
   if (DECL_P (*decl_p))
-    DECL_ATTRIBUTES (*decl_p) = attributes;
+    {
+      if (TREE_TYPE (*decl_p) == error_mark_node)
+       return;
+      p = &DECL_ATTRIBUTES (*decl_p);
+    }
   else
-    TYPE_ATTRIBUTES (*decl_p) = attributes;
+    p = &TYPE_ATTRIBUTES (*decl_p);
 
-  for (t = attributes; t; t = TREE_CHAIN (t))
-    if (ATTR_IS_DEPENDENT (t))
-      late_attrs = tree_cons
-       (TREE_PURPOSE (t),
-        tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
-                     /*integral_constant_expression_p=*/false),
-        late_attrs);
+  if (last_dep)
+    {
+      tree late_attrs = NULL_TREE;
+      tree *q = &late_attrs;
+
+      for (*p = attributes; *p; )
+       {
+         t = *p;
+         if (ATTR_IS_DEPENDENT (t))
+           {
+             *p = TREE_CHAIN (t);
+             TREE_CHAIN (t) = NULL_TREE;
+             /* If the first attribute argument is an identifier, don't
+                pass it through tsubst.  Attributes like mode, format,
+                cleanup and several target specific attributes expect it
+                unmodified.  */
+             if (TREE_VALUE (t)
+                 && TREE_CODE (TREE_VALUE (t)) == TREE_LIST
+                 && TREE_VALUE (TREE_VALUE (t))
+                 && (TREE_CODE (TREE_VALUE (TREE_VALUE (t)))
+                     == IDENTIFIER_NODE))
+               {
+                 tree chain
+                   = tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain,
+                                  in_decl,
+                                  /*integral_constant_expression_p=*/false);
+                 if (chain != TREE_CHAIN (TREE_VALUE (t)))
+                   TREE_VALUE (t)
+                     = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)),
+                                  chain);
+               }
+             else
+               TREE_VALUE (t)
+                 = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
+                                /*integral_constant_expression_p=*/false);
+             *q = t;
+             q = &TREE_CHAIN (t);
+           }
+         else
+           p = &TREE_CHAIN (t);
+       }
 
-  cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+      cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+    }
 }
 
 tree
 instantiate_class_template (tree type)
 {
-  tree template, args, pattern, t, member;
+  tree templ, args, pattern, t, member;
   tree typedecl;
   tree pbinfo;
   tree base_list;
@@ -6524,12 +6850,12 @@ instantiate_class_template (tree type)
     return type;
 
   /* Figure out which template is being instantiated.  */
-  template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
-  gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
+  templ = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
+  gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
 
   /* Determine what specialization of the original template to
      instantiate.  */
-  t = most_specialized_class (type, template);
+  t = most_specialized_class (type, templ);
   if (t == error_mark_node)
     {
       TYPE_BEING_DEFINED (type) = 1;
@@ -6552,7 +6878,7 @@ instantiate_class_template (tree type)
     }
   else
     {
-      pattern = TREE_TYPE (template);
+      pattern = TREE_TYPE (templ);
       args = CLASSTYPE_TI_ARGS (type);
     }
 
@@ -6581,9 +6907,8 @@ instantiate_class_template (tree type)
      if tsubsting causes an error.  */
   typedecl = TYPE_MAIN_DECL (type);
   input_location = DECL_SOURCE_LOCATION (typedecl);
-  in_system_header = DECL_IN_SYSTEM_HEADER (typedecl);
 
-  TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
+  TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
   TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
   TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
   TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
@@ -6779,7 +7104,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.  */
@@ -6938,7 +7263,7 @@ instantiate_class_template (tree type)
              /* Build new DECL_FRIENDLIST.  */
              tree r;
 
-             /* The the file and line for this declaration, to
+             /* The file and line for this declaration, to
                 assist in error message reporting.  Since we
                 called push_tinst_level above, we don't need to
                 restore these.  */
@@ -6974,7 +7299,7 @@ instantiate_class_template (tree type)
   /* Now that the class is complete, instantiate default arguments for
      any member functions.  We don't do this earlier because the
      default arguments may reference members of the class.  */
-  if (!PRIMARY_TEMPLATE_P (template))
+  if (!PRIMARY_TEMPLATE_P (templ))
     for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t))
       if (TREE_CODE (t) == FUNCTION_DECL
          /* Implicitly generated member functions will not have template
@@ -7046,10 +7371,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;
@@ -7073,6 +7395,22 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
          return result;
        }
 
+      if (arg_pack
+          && TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack)) == 1
+          && PACK_EXPANSION_P (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0)))
+        {
+          tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0);
+          tree pattern = PACK_EXPANSION_PATTERN (expansion);
+          if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack))
+              || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern)))
+            /* The argument pack that the parameter maps to is just an
+               expansion of the parameter itself, such as one would
+               find in the implicit typedef of a class inside the
+               class itself.  Consider this parameter "unsubstituted",
+               so that we will maintain the outer pack expansion.  */
+            arg_pack = NULL_TREE;
+        }
+          
       if (arg_pack)
         {
           int my_len = 
@@ -7398,7 +7736,7 @@ tsubst_aggr_type (tree t,
       /* Else fall through.  */
     case ENUMERAL_TYPE:
     case UNION_TYPE:
-      if (TYPE_TEMPLATE_INFO (t))
+      if (TYPE_TEMPLATE_INFO (t) && uses_template_parms (t))
        {
          tree argvec;
          tree context;
@@ -7413,8 +7751,14 @@ tsubst_aggr_type (tree t,
             up.  */
          context = TYPE_CONTEXT (t);
          if (context)
-           context = tsubst_aggr_type (context, args, complain,
-                                       in_decl, /*entering_scope=*/1);
+           {
+             context = tsubst_aggr_type (context, args, complain,
+                                         in_decl, /*entering_scope=*/1);
+             /* If context is a nested class inside a class template,
+                it may still need to be instantiated (c++/33959).  */
+             if (TYPE_P (context))
+               context = complete_type (context);
+           }
 
          /* Then, figure out what arguments are appropriate for the
             type we are trying to find.  For example, given:
@@ -7926,9 +8270,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)
@@ -8419,20 +8761,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_Wreturn_type,
-            "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]
 
@@ -8488,7 +8823,24 @@ tsubst_exception_specification (tree fntype,
                 expanded_specs = tsubst_pack_expansion (TREE_VALUE (specs),
                                                        args, complain,
                                                        in_decl);
-                len = TREE_VEC_LENGTH (expanded_specs);
+
+               if (expanded_specs == error_mark_node)
+                 return error_mark_node;
+               else if (TREE_CODE (expanded_specs) == TREE_VEC)
+                 len = TREE_VEC_LENGTH (expanded_specs);
+               else
+                 {
+                   /* We're substituting into a member template, so
+                      we got a TYPE_PACK_EXPANSION back.  Add that
+                      expansion and move on.  */
+                   gcc_assert (TREE_CODE (expanded_specs) 
+                               == TYPE_PACK_EXPANSION);
+                   new_specs = add_exception_specifier (new_specs,
+                                                        expanded_specs,
+                                                        complain);
+                   specs = TREE_CHAIN (specs);
+                   continue;
+                 }
               }
 
             for (i = 0; i < len; ++i)
@@ -8557,17 +8909,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);
@@ -8623,9 +8979,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");
@@ -8773,7 +9129,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                r = copy_type (t);
                TEMPLATE_TYPE_PARM_INDEX (r)
                  = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
-                                               r, levels);
+                                               r, levels, args, complain);
                TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
                TYPE_MAIN_VARIANT (r) = r;
                TYPE_POINTER_TO (r) = NULL_TREE;
@@ -8807,7 +9163,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            break;
 
          case TEMPLATE_PARM_INDEX:
-           r = reduce_template_parm_level (t, type, levels);
+           r = reduce_template_parm_level (t, type, levels, args, complain);
            break;
 
          default:
@@ -8894,13 +9250,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               message to avoid spewing a ton of messages during a
               single bad template instantiation.  */
            if (complain & tf_error
-#ifdef USE_MAPPED_LOCATION
-               && last_loc != input_location
-#else
-               && (last_loc.line != input_line
-                   || last_loc.file != input_filename)
-#endif
-                 )
+               && last_loc != input_location)
              {
                if (TREE_CODE (type) == VOID_TYPE)
                  error ("forming reference to void");
@@ -8946,7 +9296,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case OFFSET_TYPE:
       {
        r = tsubst (TYPE_OFFSET_BASETYPE (t), args, complain, in_decl);
-       if (r == error_mark_node || !IS_AGGR_TYPE (r))
+       if (r == error_mark_node || !MAYBE_CLASS_TYPE_P (r))
          {
            /* [temp.deduct]
 
@@ -9089,7 +9439,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (ctx == error_mark_node || f == error_mark_node)
          return error_mark_node;
 
-       if (!IS_AGGR_TYPE (ctx))
+       if (!MAYBE_CLASS_TYPE_P (ctx))
          {
            if (complain & tf_error)
              error ("%qT is not a class, struct, or union type", ctx);
@@ -9389,7 +9739,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
       if (complain & tf_error)
        qualified_name_lookup_error (scope,
                                     TREE_OPERAND (qualified_id, 1),
-                                    expr);
+                                    expr, input_location);
       return error_mark_node;
     }
 
@@ -9398,7 +9748,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
 
   if (expr == error_mark_node && complain & tf_error)
     qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
-                                expr);
+                                expr, input_location);
   else if (TYPE_P (scope))
     {
       expr = (adjust_result_of_qualified_name_lookup
@@ -9566,9 +9916,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 */
 
@@ -9836,16 +10207,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);
@@ -9853,6 +10234,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 ();
@@ -9896,6 +10278,137 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
 #undef RECUR
 }
 
+/* Substitute one OMP_FOR iterator.  */
+
+static void
+tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
+                        tree condv, tree incrv, tree *clauses,
+                        tree args, tsubst_flags_t complain, tree in_decl,
+                        bool integral_constant_expression_p)
+{
+#define RECUR(NODE)                            \
+  tsubst_expr ((NODE), args, complain, in_decl,        \
+              integral_constant_expression_p)
+  tree decl, init, cond, incr;
+
+  init = TREE_VEC_ELT (OMP_FOR_INIT (t), i);
+  gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+  decl = RECUR (TREE_OPERAND (init, 0));
+  init = TREE_OPERAND (init, 1);
+  gcc_assert (!type_dependent_expression_p (decl));
+
+  if (!CLASS_TYPE_P (TREE_TYPE (decl)))
+    {
+      cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
+      incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
+      if (TREE_CODE (incr) == MODIFY_EXPR)
+       incr = build_x_modify_expr (RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR,
+                                   RECUR (TREE_OPERAND (incr, 1)),
+                                   complain);
+      else
+       incr = RECUR (incr);
+      TREE_VEC_ELT (declv, i) = decl;
+      TREE_VEC_ELT (initv, i) = init;
+      TREE_VEC_ELT (condv, i) = cond;
+      TREE_VEC_ELT (incrv, i) = incr;
+      return;
+    }
+
+  if (init && TREE_CODE (init) != DECL_EXPR)
+    {
+      tree c;
+      for (c = *clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+       {
+         if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+              || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+             && OMP_CLAUSE_DECL (c) == decl)
+           break;
+         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+                  && OMP_CLAUSE_DECL (c) == decl)
+           error ("iteration variable %qD should not be firstprivate", decl);
+         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+                  && OMP_CLAUSE_DECL (c) == decl)
+           error ("iteration variable %qD should not be reduction", decl);
+       }
+      if (c == NULL)
+       {
+         c = build_omp_clause (OMP_CLAUSE_PRIVATE);
+         OMP_CLAUSE_DECL (c) = decl;
+         c = finish_omp_clauses (c);
+         if (c)
+           {
+             OMP_CLAUSE_CHAIN (c) = *clauses;
+             *clauses = c;
+           }
+       }
+    }
+  cond = TREE_VEC_ELT (OMP_FOR_COND (t), i);
+  if (COMPARISON_CLASS_P (cond))
+    cond = build2 (TREE_CODE (cond), boolean_type_node,
+                  RECUR (TREE_OPERAND (cond, 0)),
+                  RECUR (TREE_OPERAND (cond, 1)));
+  else
+    cond = RECUR (cond);
+  incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
+  switch (TREE_CODE (incr))
+    {
+    case PREINCREMENT_EXPR:
+    case PREDECREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+      incr = build2 (TREE_CODE (incr), TREE_TYPE (decl),
+                    RECUR (TREE_OPERAND (incr, 0)), NULL_TREE);
+      break;
+    case MODIFY_EXPR:
+      if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+         || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+       {
+         tree rhs = TREE_OPERAND (incr, 1);
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
+                        RECUR (TREE_OPERAND (incr, 0)),
+                        build2 (TREE_CODE (rhs), TREE_TYPE (decl),
+                                RECUR (TREE_OPERAND (rhs, 0)),
+                                RECUR (TREE_OPERAND (rhs, 1))));
+       }
+      else
+       incr = RECUR (incr);
+      break;
+    case MODOP_EXPR:
+      if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+         || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
+       {
+         tree lhs = RECUR (TREE_OPERAND (incr, 0));
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl), lhs,
+                        build2 (TREE_CODE (TREE_OPERAND (incr, 1)),
+                                TREE_TYPE (decl), lhs,
+                                RECUR (TREE_OPERAND (incr, 2))));
+       }
+      else if (TREE_CODE (TREE_OPERAND (incr, 1)) == NOP_EXPR
+              && (TREE_CODE (TREE_OPERAND (incr, 2)) == PLUS_EXPR
+                  || (TREE_CODE (TREE_OPERAND (incr, 2)) == MINUS_EXPR)))
+       {
+         tree rhs = TREE_OPERAND (incr, 2);
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
+                        RECUR (TREE_OPERAND (incr, 0)),
+                        build2 (TREE_CODE (rhs), TREE_TYPE (decl),
+                                RECUR (TREE_OPERAND (rhs, 0)),
+                                RECUR (TREE_OPERAND (rhs, 1))));
+       }
+      else
+       incr = RECUR (incr);
+      break;
+    default:
+      incr = RECUR (incr);
+      break;
+    }
+
+  TREE_VEC_ELT (declv, i) = decl;
+  TREE_VEC_ELT (initv, i) = init;
+  TREE_VEC_ELT (condv, i) = cond;
+  TREE_VEC_ELT (incrv, i) = incr;
+#undef RECUR
+}
+
 /* Like tsubst_copy for expressions, etc. but also does semantic
    processing.  */
 
@@ -9967,7 +10480,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);
          }
@@ -10219,21 +10732,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);
@@ -10242,10 +10789,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));
       }
@@ -10278,13 +10823,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case OMP_ATOMIC:
-      if (OMP_ATOMIC_DEPENDENT_P (t))
-        {
-         tree op1 = TREE_OPERAND (t, 1);
-         tree lhs = RECUR (TREE_OPERAND (op1, 0));
-         tree rhs = RECUR (TREE_OPERAND (op1, 1));
-         finish_omp_atomic (TREE_CODE (op1), lhs, rhs);
-        }
+      gcc_assert (OMP_ATOMIC_DEPENDENT_P (t));
+      {
+       tree op1 = TREE_OPERAND (t, 1);
+       tree lhs = RECUR (TREE_OPERAND (op1, 0));
+       tree rhs = RECUR (TREE_OPERAND (op1, 1));
+       finish_omp_atomic (TREE_CODE (op1), lhs, rhs);
+      }
       break;
 
     case EXPR_PACK_EXPANSION:
@@ -10382,7 +10927,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)
@@ -10393,26 +10939,26 @@ tsubst_copy_and_build (tree t,
     case TEMPLATE_ID_EXPR:
       {
        tree object;
-       tree template = RECUR (TREE_OPERAND (t, 0));
+       tree templ = RECUR (TREE_OPERAND (t, 0));
        tree targs = TREE_OPERAND (t, 1);
 
        if (targs)
          targs = tsubst_template_args (targs, args, complain, in_decl);
 
-       if (TREE_CODE (template) == COMPONENT_REF)
+       if (TREE_CODE (templ) == COMPONENT_REF)
          {
-           object = TREE_OPERAND (template, 0);
-           template = TREE_OPERAND (template, 1);
+           object = TREE_OPERAND (templ, 0);
+           templ = TREE_OPERAND (templ, 1);
          }
        else
          object = NULL_TREE;
-       template = lookup_template_function (template, targs);
+       templ = lookup_template_function (templ, targs);
 
        if (object)
-         return build3 (COMPONENT_REF, TREE_TYPE (template),
-                        object, template, NULL_TREE);
+         return build3 (COMPONENT_REF, TREE_TYPE (templ),
+                        object, templ, NULL_TREE);
        else
-         return baselink_for_fns (template);
+         return baselink_for_fns (templ);
       }
 
     case INDIRECT_REF:
@@ -10428,7 +10974,7 @@ tsubst_copy_and_build (tree t,
              r = convert_from_reference (r);
          }
        else
-         r = build_x_indirect_ref (r, "unary *");
+         r = build_x_indirect_ref (r, "unary *", complain);
        return r;
       }
 
@@ -10450,8 +10996,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; 
          }
 
@@ -10460,15 +11007,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 ();
          }
@@ -10478,7 +11025,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:
@@ -10489,7 +11036,8 @@ tsubst_copy_and_build (tree t,
     case UNARY_PLUS_EXPR:  /* Unary + */
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)));
+      return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)),
+                               complain);
 
     case ADDR_EXPR:
       op1 = TREE_OPERAND (t, 0);
@@ -10501,7 +11049,7 @@ tsubst_copy_and_build (tree t,
                                                  in_decl);
       if (TREE_CODE (op1) == LABEL_DECL)
        return finish_label_address_expr (DECL_NAME (op1));
-      return build_x_unary_op (ADDR_EXPR, op1);
+      return build_x_unary_op (ADDR_EXPR, op1, complain);
 
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -10544,7 +11092,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,
@@ -10560,18 +11109,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:
@@ -10593,16 +11136,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
@@ -10627,7 +11173,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
@@ -10640,7 +11186,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:
@@ -10652,7 +11199,8 @@ tsubst_copy_and_build (tree t,
 
     case COMPOUND_EXPR:
       return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)),
-                                   RECUR (TREE_OPERAND (t, 1)));
+                                   RECUR (TREE_OPERAND (t, 1)),
+                                    complain);
 
     case CALL_EXPR:
       {
@@ -10726,25 +11274,29 @@ tsubst_copy_and_build (tree t,
            if (!BASELINK_P (TREE_OPERAND (function, 1)))
              return finish_call_expr (function, call_args,
                                       /*disallow_virtual=*/false,
-                                      /*koenig_p=*/false);
+                                      /*koenig_p=*/false,
+                                      complain);
            else
              return (build_new_method_call
                      (TREE_OPERAND (function, 0),
                       TREE_OPERAND (function, 1),
                       call_args, NULL_TREE,
                       qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
-                      /*fn_p=*/NULL));
+                      /*fn_p=*/NULL,
+                      complain));
          }
        return finish_call_expr (function, call_args,
                                 /*disallow_virtual=*/qualified_p,
-                                koenig_p);
+                                koenig_p,
+                                complain);
       }
 
     case COND_EXPR:
       return build_x_conditional_expr
        (RECUR (TREE_OPERAND (t, 0)),
         RECUR (TREE_OPERAND (t, 1)),
-        RECUR (TREE_OPERAND (t, 2)));
+        RECUR (TREE_OPERAND (t, 2)),
+         complain);
 
     case PSEUDO_DTOR_EXPR:
       return finish_pseudo_destructor_expr
@@ -10863,15 +11415,23 @@ tsubst_copy_and_build (tree t,
 
        if (object_type && !CLASS_TYPE_P (object_type))
          {
-           if (TREE_CODE (member) == BIT_NOT_EXPR)
-             return finish_pseudo_destructor_expr (object,
-                                                   NULL_TREE,
-                                                   object_type);
-           else if (TREE_CODE (member) == SCOPE_REF
-                    && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
-             return finish_pseudo_destructor_expr (object,
-                                                   object,
-                                                   object_type);
+           if (SCALAR_TYPE_P (object_type))
+             {
+               tree s = NULL_TREE;
+               tree dtor = member;
+
+               if (TREE_CODE (dtor) == SCOPE_REF)
+                 {
+                   s = TREE_OPERAND (dtor, 0);
+                   dtor = TREE_OPERAND (dtor, 1);
+                 }
+               if (TREE_CODE (dtor) == BIT_NOT_EXPR)
+                 {
+                   dtor = TREE_OPERAND (dtor, 0);
+                   if (TYPE_P (dtor))
+                     return finish_pseudo_destructor_expr (object, s, dtor);
+                 }
+             }
          }
        else if (TREE_CODE (member) == SCOPE_REF
                 && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
@@ -10897,7 +11457,8 @@ tsubst_copy_and_build (tree t,
              }
            else
              {
-               qualified_name_lookup_error (object_type, tmpl, member);
+               qualified_name_lookup_error (object_type, tmpl, member,
+                                            input_location);
                return error_mark_node;
              }
          }
@@ -10920,7 +11481,8 @@ tsubst_copy_and_build (tree t,
          return finish_non_static_data_member (member, object, NULL_TREE);
 
        return finish_class_member_access_expr (object, member,
-                                               /*template_p=*/false);
+                                               /*template_p=*/false,
+                                               complain);
       }
 
     case THROW_EXPR:
@@ -10936,6 +11498,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;
@@ -10947,7 +11510,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);
@@ -11000,10 +11563,12 @@ tsubst_copy_and_build (tree t,
               }
           }
 
+       r = build_constructor (init_list_type_node, n);
+
        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:
@@ -11437,6 +12002,32 @@ fn_type_unification (tree fn,
         }
     }
 
+  /* Now that we have bindings for all of the template arguments,
+     ensure that the arguments deduced for the template template
+     parameters have compatible template parameter lists.  We cannot
+     check this property before we have deduced all template
+     arguments, because the template parameter types of a template
+     template parameter might depend on prior template parameters
+     deduced after the template template parameter.  The following
+     ill-formed example illustrates this issue:
+
+       template<typename T, template<T> class C> void f(C<5>, T);
+
+       template<int N> struct X {};
+
+       void g() {
+         f(X<5>(), 5l); // error: template argument deduction fails
+       }
+
+     The template parameter list of 'C' depends on the template type
+     parameter 'T', but 'C' is deduced to 'X' before 'T' is deduced to
+     'long'.  Thus, we can't check that 'C' cannot bind to 'X' at the
+     time that we deduce 'C'.  */
+  if (result == 0
+      && !template_template_parm_bindings_ok_p 
+           (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs))
+    return 1;
+
   if (result == 0)
     /* All is well so far.  Now, check:
 
@@ -11674,6 +12265,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;
       }
@@ -11844,6 +12437,7 @@ resolve_overloaded_unification (tree tparms,
          if (TREE_CODE (fn) != TEMPLATE_DECL)
            continue;
 
+         ++processing_template_decl;
          subargs = get_bindings (fn, DECL_TEMPLATE_RESULT (fn),
                                  expl_subargs, /*check_ret=*/false);
          if (subargs)
@@ -11852,6 +12446,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
@@ -12033,7 +12628,7 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
   tree rval = NULL_TREE;
   tree binfo;
 
-  gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
+  gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (arg)));
 
   binfo = TYPE_BINFO (complete_type (arg));
   if (!binfo)
@@ -12200,6 +12795,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
       /* Unify the pattern with the current argument.  */
       {
         tree arg = TREE_VEC_ELT (packed_args, i);
+       tree arg_expr = NULL_TREE;
         int arg_strict = strict;
         bool skip_arg_p = false;
 
@@ -12250,7 +12846,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
 
                 if (!skip_arg_p)
                   {
-                    arg = TREE_TYPE (arg);
+                   arg_expr = arg;
+                    arg = unlowered_expr_type (arg);
                     if (arg == error_mark_node)
                       return 1;
                   }
@@ -12260,7 +12857,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
 
             if (!subr)
               arg_strict |= 
-                maybe_adjust_types_for_deduction (strict, &parm, &arg, NULL);
+                maybe_adjust_types_for_deduction (strict, &parm, &arg, 
+                                                 arg_expr);
           }
 
         if (!skip_arg_p)
@@ -12288,6 +12886,16 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
     {
       tree old_pack = TREE_VALUE (pack);
       tree new_args = TREE_TYPE (pack);
+      int i, len = TREE_VEC_LENGTH (new_args);
+      bool nondeduced_p = false;
+
+      /* If NEW_ARGS contains any NULL_TREE entries, we didn't
+        actually deduce anything.  */
+      for (i = 0; i < len && !nondeduced_p; ++i)
+       if (TREE_VEC_ELT (new_args, i) == NULL_TREE)
+         nondeduced_p = true;
+      if (nondeduced_p)
+       continue;
 
       if (old_pack && ARGUMENT_PACK_INCOMPLETE_P (old_pack))
         {
@@ -12425,7 +13033,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
   if (arg == error_mark_node)
     return 1;
-  if (arg == unknown_type_node)
+  if (arg == unknown_type_node
+      || arg == init_list_type_node)
     /* We can't deduce anything from this, but we might get all the
        template args from other function args.  */
     return 0;
@@ -12437,6 +13046,31 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
   if (arg == parm && !uses_template_parms (parm))
     return 0;
 
+  /* Handle init lists early, so the rest of the function can assume
+     we're dealing with a type. */
+  if (BRACE_ENCLOSED_INITIALIZER_P (arg))
+    {
+      tree elt, elttype;
+      unsigned i;
+
+      if (!is_std_init_list (parm))
+       /* We can only deduce from an initializer list argument if the
+          parameter is std::initializer_list; otherwise this is a
+          non-deduced context. */
+       return 0;
+
+      elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+
+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+       {
+         if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+           elt = TREE_TYPE (elt);
+         if (unify (tparms, targs, elttype, elt, UNIFY_ALLOW_NONE))
+           return 1;
+       }
+      return 0;
+    }
+
   /* Immediately reject some pairs that won't unify because of
      cv-qualification mismatches.  */
   if (TREE_CODE (arg) == TREE_CODE (parm)
@@ -12506,9 +13140,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          {
            tree parmvec = TYPE_TI_ARGS (parm);
            tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
-           tree argtmplvec
-             = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
-           int i;
+           tree parm_parms 
+              = DECL_INNERMOST_TEMPLATE_PARMS
+                 (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm));
+           int i, len;
+            int parm_variadic_p = 0;
 
            /* The resolution to DR150 makes clear that default
               arguments for an N-argument may not be used to bind T
@@ -12537,7 +13173,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
              Here, if Lvalue_proxy is permitted to bind to View, then
              the global operator+ will be used; if they are not, the
              Lvalue_proxy will be converted to float.  */
-           if (coerce_template_parms (argtmplvec, parmvec,
+           if (coerce_template_parms (parm_parms,
+                                       argvec,
                                       TYPE_TI_TEMPLATE (parm),
                                       tf_none,
                                       /*require_all_args=*/true,
@@ -12550,7 +13187,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
               rather than the whole TREE_VEC since they can have
               different number of elements.  */
 
-           for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
+            parmvec = expand_template_argument_pack (parmvec);
+            argvec = expand_template_argument_pack (argvec);
+
+            len = TREE_VEC_LENGTH (parmvec);
+
+            /* Check if the parameters end in a pack, making them
+               variadic.  */
+            if (len > 0
+                && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1)))
+              parm_variadic_p = 1;
+            
+            if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
+              return 1;
+
+             for (i = 0; i < len - parm_variadic_p; ++i)
              {
                if (unify (tparms, targs,
                           TREE_VEC_ELT (parmvec, i),
@@ -12558,6 +13209,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
                           UNIFY_ALLOW_NONE))
                  return 1;
              }
+
+           if (parm_variadic_p
+               && unify_pack_expansion (tparms, targs,
+                                        parmvec, argvec,
+                                        UNIFY_ALLOW_NONE,
+                                        /*call_args_p=*/false,
+                                        /*subr=*/false))
+             return 1;
          }
          arg = TYPE_TI_TEMPLATE (arg);
 
@@ -12904,7 +13563,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       /* CV qualifications for methods can never be deduced, they must
         match exactly.  We need to check them explicitly here,
         because type_unification_real treats them as any other
-        cvqualified parameter.  */
+        cv-qualified parameter.  */
       if (TREE_CODE (parm) == METHOD_TYPE
          && (!check_cv_quals_for_unify
              (UNIFY_ALLOW_NONE,
@@ -12980,10 +13639,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
         int argslen = TREE_VEC_LENGTH (packed_args);
         int parm_variadic_p = 0;
 
-        /* Check if the parameters end in a pack, making them variadic.  */
-        if (len > 0 
-           && PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, len - 1)))
-          parm_variadic_p = 1;
+       for (i = 0; i < len; ++i)
+         {
+           if (PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, i)))
+             {
+               if (i == len - 1)
+                 /* We can unify against something with a trailing
+                    parameter pack.  */
+                 parm_variadic_p = 1;
+               else
+                 /* Since there is something following the pack
+                    expansion, we cannot unify this template argument
+                    list.  */
+                 return 0;
+             }
+         }
+         
 
         /* If we don't have enough arguments to satisfy the parameters
            (not counting the pack expression at the end), or we have
@@ -13018,6 +13689,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          nodes.  */
       return 0;
 
+    case ERROR_MARK:
+      /* Unification fails if we hit an error node.  */
+      return 1;
+
     default:
       gcc_assert (EXPR_P (parm));
 
@@ -13180,7 +13855,9 @@ more_specialized_fn (tree pat1, tree pat2, int len)
 
   processing_template_decl++;
 
-  while (len--)
+  while (len--
+        /* Stop when an ellipsis is seen.  */
+        && args1 != NULL_TREE && args2 != NULL_TREE)
     {
       tree arg1 = TREE_VALUE (args1);
       tree arg2 = TREE_VALUE (args2);
@@ -13560,6 +14237,14 @@ get_class_bindings (tree tparms, tree spec_args, tree args)
                              INNERMOST_TEMPLATE_ARGS (args)))
     return NULL_TREE;
 
+  /* Now that we have bindings for all of the template arguments,
+     ensure that the arguments deduced for the template template
+     parameters have compatible template parameter lists.  See the use
+     of template_template_parm_bindings_ok_p in fn_type_unification
+     for more information.  */
+  if (!template_template_parm_bindings_ok_p (tparms, deduced_args))
+    return NULL_TREE;
+
   return deduced_args;
 }
 
@@ -13847,6 +14532,11 @@ do_decl_instantiation (tree decl, tree storage)
         VAR_DECLs so we do the lookup here.  Probably, grokdeclarator
         should handle VAR_DECLs as it currently handles
         FUNCTION_DECLs.  */
+      if (!DECL_CLASS_SCOPE_P (decl))
+       {
+         error ("%qD is not a static data member of a class template", decl);
+         return;
+       }
       result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, false);
       if (!result || TREE_CODE (result) != VAR_DECL)
        {
@@ -13899,7 +14589,7 @@ do_decl_instantiation (tree decl, tree storage)
         the first instantiation was `extern' and the second is not,
         and EXTERN_P for the opposite case.  */
       if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
-       pedwarn ("duplicate explicit instantiation of %q#D", result);
+       permerror ("duplicate explicit instantiation of %q#D", result);
       /* If an "extern" explicit instantiation follows an ordinary
         explicit instantiation, the template is instantiated.  */
       if (extern_p)
@@ -13912,7 +14602,7 @@ do_decl_instantiation (tree decl, tree storage)
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      pedwarn ("explicit instantiation of non-template %q#D", result);
+      permerror ("explicit instantiation of non-template %q#D", result);
       return;
     }
 
@@ -13920,8 +14610,8 @@ do_decl_instantiation (tree decl, tree storage)
     ;
   else if (storage == ridpointers[(int) RID_EXTERN])
     {
-      if (pedantic && !in_system_header)
-       pedwarn ("ISO C++ forbids the use of %<extern%> on explicit "
+      if (pedantic && !in_system_header && (cxx_dialect == cxx98))
+       pedwarn ("ISO C++ 1998 forbids the use of %<extern%> on explicit "
                 "instantiations");
       extern_p = 1;
     }
@@ -13956,7 +14646,7 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
 {
   tree storage = *(tree *) data;
 
-  if (IS_AGGR_TYPE (entry->type)
+  if (MAYBE_CLASS_TYPE_P (entry->type)
       && !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
     do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
 }
@@ -14008,8 +14698,17 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
   if (storage != NULL_TREE)
     {
       if (pedantic && !in_system_header)
-       pedwarn("ISO C++ forbids the use of %qE on explicit instantiations",
-               storage);
+       {
+         if (storage == ridpointers[(int) RID_EXTERN])
+           {
+             if (cxx_dialect == cxx98)
+               pedwarn("ISO C++ 1998 forbids the use of %<extern%> on "
+                       "explicit instantiations");
+           }
+         else
+           pedwarn("ISO C++ forbids the use of %qE on explicit "
+                   "instantiations", storage);
+       }
 
       if (storage == ridpointers[(int) RID_INLINE])
        nomem_p = 1;
@@ -14053,7 +14752,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
 
       if (!previous_instantiation_extern_p && !extern_p
          && (complain & tf_error))
-       pedwarn ("duplicate explicit instantiation of %q#T", t);
+       permerror ("duplicate explicit instantiation of %q#T", t);
 
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
@@ -14313,7 +15012,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
@@ -14396,7 +15094,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
@@ -14500,7 +15197,7 @@ instantiate_decl (tree d, int defer_ok,
           member function or static data member of a class template
           shall be present in every translation unit in which it is
           explicitly instantiated.  */
-       pedwarn
+       permerror
          ("explicit instantiation of %qD but no definition available", d);
 
       /* ??? Historically, we have instantiated inline functions, even
@@ -14668,7 +15365,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 ();
 
@@ -14686,7 +15382,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
@@ -14770,7 +15465,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
@@ -14817,37 +15511,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);
-
-              /* Prepend each of the expanded expressions to the
-                 corresponding TREE_LIST in EXPANDED_ARGUMENTS.  */
-              for (i = 0; i < len; i++)
-                {
-                  TREE_VEC_ELT (expanded_arguments, i) = 
-                    tree_cons (NULL_TREE, TREE_VEC_ELT (expanded_exprs, i),
-                               TREE_VEC_ELT (expanded_arguments, i));
-                }
-            }
-          in_base_initializer = 0;
+         if (TREE_VALUE (t) == void_type_node)
+           /* VOID_TYPE_NODE is used to indicate
+              value-initialization.  */
+           {
+             for (i = 0; i < len; i++)
+               TREE_VEC_ELT (expanded_arguments, i) = void_type_node;
+           }
+         else
+           {
+             /* Substitute parameter packs into each argument in the
+                TREE_LIST.  */
+             in_base_initializer = 1;
+             for (arg = TREE_VALUE (t); arg; arg = TREE_CHAIN (arg))
+               {
+                 tree expanded_exprs;
+
+                 /* Expand the argument.  */
+                 SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
+                 expanded_exprs 
+                   = tsubst_pack_expansion (expr, argvec,
+                                            tf_warning_or_error,
+                                            NULL_TREE);
+                 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;
 
-          /* 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)
@@ -15095,13 +15803,18 @@ dependent_type_p_r (tree type)
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       if (TYPE_DOMAIN (type)
-         && ((value_dependent_expression_p
-              (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
-             || (type_dependent_expression_p
-                 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))))
+         && dependent_type_p (TYPE_DOMAIN (type)))
        return true;
       return dependent_type_p (TREE_TYPE (type));
     }
+  else if (TREE_CODE (type) == INTEGER_TYPE
+          && !TREE_CONSTANT (TYPE_MAX_VALUE (type)))
+    {
+      /* If this is the TYPE_DOMAIN of an array type, consider it
+        dependent.  */
+      return (value_dependent_expression_p (TYPE_MAX_VALUE (type))
+             || type_dependent_expression_p (TYPE_MAX_VALUE (type)));
+    }
 
   /* -- a template-id in which either the template name is a template
      parameter ...  */
@@ -15257,7 +15970,7 @@ value_dependent_expression_p (tree expression)
       /* A non-type template parm.  */
       if (DECL_TEMPLATE_PARM_P (expression))
        return true;
-      return false;
+      return value_dependent_expression_p (DECL_INITIAL (expression));
 
     case VAR_DECL:
        /* A constant with integral or enumeration type and is initialized
@@ -15686,6 +16399,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