OSDN Git Service

* pt.c (convert_nontype_argument): Fix a typo in an error
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index cae8da1..8066e08 100644 (file)
@@ -45,6 +45,7 @@ Boston, MA 02110-1301, USA.  */
 #include "rtl.h"
 #include "timevar.h"
 #include "tree-iterator.h"
+#include "vecprim.h"
 
 /* The type of functions taking a tree, and some additional data, and
    returning an int.  */
@@ -63,8 +64,7 @@ int processing_template_parmlist;
 static int template_header_count;
 
 static GTY(()) tree saved_trees;
-static GTY(()) varray_type inline_parm_levels;
-static size_t inline_parm_levels_used;
+static VEC(int,heap) *inline_parm_levels;
 
 static GTY(()) tree current_tinst_level;
 
@@ -97,12 +97,15 @@ static int try_one_overload (tree, tree, tree, tree, tree,
                             unification_kind_t, int, bool);
 static int unify (tree, tree, tree, tree, int);
 static void add_pending_template (tree);
+static int push_tinst_level (tree);
+static void pop_tinst_level (void);
 static void reopen_tinst_level (tree);
 static tree classtype_mangled_name (tree);
 static char* mangle_class_name_for_template (const char *, tree, tree);
 static tree tsubst_initializer_list (tree, tree);
 static tree get_class_bindings (tree, tree, tree);
-static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int);
+static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, 
+                                  bool, bool);
 static void tsubst_enum        (tree, tree, tree);
 static tree add_to_template_args (tree, tree);
 static tree add_outermost_template_args (tree, tree);
@@ -135,9 +138,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
 static void regenerate_decl_from_template (tree, tree);
-static tree most_specialized (tree, tree, tree);
 static tree most_specialized_class (tree, tree);
-static int template_class_depth_real (tree, int);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
 static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
@@ -145,13 +146,10 @@ static void check_specialization_scope (void);
 static tree process_partial_specialization (tree);
 static void set_current_access_from_decl (tree);
 static void check_default_tmpl_args (tree, tree, int, int);
-static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
 static tree get_template_base (tree, tree, tree, tree);
-static int verify_class_unification (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 tree determine_specialization (tree, tree, tree *, int, int);
 static int template_args_equal (tree, tree);
 static void tsubst_default_arguments (tree);
 static tree for_each_template_parm_r (tree *, int *, void *);
@@ -266,15 +264,14 @@ finish_member_template_decl (tree decl)
 
    A<T>::B<U> has depth two, while A<T> has depth one.
    Both A<T>::B<int> and A<int>::B<U> have depth one, if
-   COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not
-   specializations.
+   they are instantiations, not specializations.
 
    This function is guaranteed to return 0 if passed NULL_TREE so
    that, for example, `template_class_depth (current_class_type)' is
    always safe.  */
 
-static int
-template_class_depth_real (tree type, int count_specializations)
+int
+template_class_depth (tree type)
 {
   int depth;
 
@@ -287,18 +284,14 @@ template_class_depth_real (tree type, int count_specializations)
        {
          if (CLASSTYPE_TEMPLATE_INFO (type)
              && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
-             && ((count_specializations
-                  && CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
-                 || uses_template_parms (CLASSTYPE_TI_ARGS (type))))
+             && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
            ++depth;
        }
       else
        {
          if (DECL_TEMPLATE_INFO (type)
              && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type))
-             && ((count_specializations
-                  && DECL_TEMPLATE_SPECIALIZATION (type))
-                 || uses_template_parms (DECL_TI_ARGS (type))))
+             && uses_template_parms (DECL_TI_ARGS (type)))
            ++depth;
        }
     }
@@ -306,16 +299,6 @@ template_class_depth_real (tree type, int count_specializations)
   return depth;
 }
 
-/* Returns the template nesting level of the indicated class TYPE.
-   Like template_class_depth_real, but instantiations do not count in
-   the depth.  */
-
-int
-template_class_depth (tree type)
-{
-  return template_class_depth_real (type, /*count_specializations=*/0);
-}
-
 /* Returns 1 if processing DECL as part of do_pending_inlines
    needs us to push template parms.  */
 
@@ -412,12 +395,7 @@ maybe_begin_member_template_processing (tree decl)
 
   /* Remember how many levels of template parameters we pushed so that
      we can pop them later.  */
-  if (!inline_parm_levels)
-    VARRAY_INT_INIT (inline_parm_levels, 4, "inline_parm_levels");
-  if (inline_parm_levels_used == inline_parm_levels->num_elements)
-    VARRAY_GROW (inline_parm_levels, 2 * inline_parm_levels_used);
-  VARRAY_INT (inline_parm_levels, inline_parm_levels_used) = levels;
-  ++inline_parm_levels_used;
+  VEC_safe_push (int, heap, inline_parm_levels, levels);
 }
 
 /* Undo the effects of maybe_begin_member_template_processing.  */
@@ -426,14 +404,13 @@ void
 maybe_end_member_template_processing (void)
 {
   int i;
+  int last;
 
-  if (!inline_parm_levels_used)
+  if (VEC_length (int, inline_parm_levels) == 0)
     return;
 
-  --inline_parm_levels_used;
-  for (i = 0;
-       i < VARRAY_INT (inline_parm_levels, inline_parm_levels_used);
-       ++i)
+  last = VEC_pop (int, inline_parm_levels);
+  for (i = 0; i < last; ++i)
     {
       --processing_template_decl;
       current_template_parms = TREE_CHAIN (current_template_parms);
@@ -642,7 +619,7 @@ end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
-/* A explicit specialization or partial specialization TMPL is being
+/* An explicit specialization or partial specialization TMPL is being
    declared.  Check that the namespace in which the specialization is
    occurring is permissible.  Returns false iff it is invalid to
    specialize TMPL in the current namespace.  */
@@ -667,19 +644,40 @@ check_specialization_namespace (tree tmpl)
   else
     {
       pedwarn ("specialization of %qD in different namespace", tmpl);
-      cp_pedwarn_at ("  from definition of %q#D", tmpl);
+      pedwarn ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
 
+/* SPEC is an explicit instantiation.  Check that it is valid to
+   perform this explicit instantiation in the current namespace.  */
+
+static void
+check_explicit_instantiation_namespace (tree spec)
+{
+  tree ns;
+
+  /* DR 275: An explicit instantiation shall appear in an enclosing
+     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);
+}
+
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
 void
 maybe_process_partial_specialization (tree type)
 {
-  /* TYPE maybe an ERROR_MARK_NODE.  */
-  tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE;
+  tree context;
+
+  if (type == error_mark_node)
+    return;
+
+  context = TYPE_CONTEXT (type);
 
   if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
     {
@@ -736,8 +734,8 @@ maybe_process_partial_specialization (tree type)
              != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
            {
              pedwarn ("specializing %q#T in different namespace", type);
-             cp_pedwarn_at ("  from definition of %q#D",
-                            CLASSTYPE_TI_TEMPLATE (type));
+             pedwarn ("  from definition of %q+#D",
+                      CLASSTYPE_TI_TEMPLATE (type));
            }
 
          /* Check for invalid specialization after instantiation:
@@ -896,8 +894,8 @@ retrieve_specialization (tree tmpl, tree args,
 static tree
 retrieve_local_specialization (tree tmpl)
 {
-  tree spec = htab_find_with_hash (local_specializations, tmpl,
-                                  htab_hash_pointer (tmpl));
+  tree spec = (tree) htab_find_with_hash (local_specializations, tmpl,
+                                          htab_hash_pointer (tmpl));
   return spec ? TREE_PURPOSE (spec) : NULL_TREE;
 }
 
@@ -1114,11 +1112,12 @@ is_specialization_of_friend (tree decl, tree friend)
 }
 
 /* Register the specialization SPEC as a specialization of TMPL with
-   the indicated ARGS.  Returns SPEC, or an equivalent prior
-   declaration, if available.  */
+   the indicated ARGS.  IS_FRIEND indicates whether the specialization
+   is actually just a friend declaration.  Returns SPEC, or an
+   equivalent prior declaration, if available.  */
 
 static tree
-register_specialization (tree spec, tree tmpl, tree args)
+register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
 {
   tree fn;
 
@@ -1161,6 +1160,7 @@ register_specialization (tree spec, tree tmpl, tree args)
            }
          else
            {
+             tree clone;
              /* This situation should occur only if the first
                 specialization is an implicit instantiation, the
                 second is an explicit specialization, and the
@@ -1185,14 +1185,32 @@ register_specialization (tree spec, tree tmpl, tree args)
                 for the specialization, we want this to look as if
                 there were no definition, and vice versa.  */
              DECL_INITIAL (fn) = NULL_TREE;
-             duplicate_decls (spec, fn);
+             duplicate_decls (spec, fn, is_friend);
+             /* The call to duplicate_decls will have applied
+                [temp.expl.spec]: 
+
+                  An explicit specialization of a function template
+                  is inline only if it is explicitly declared to be,
+                  and independently of whether its function template
+                  is.
+
+               to the primary function; now copy the inline bits to
+               the various clones.  */   
+             FOR_EACH_CLONE (clone, fn)
+               {
+                 DECL_DECLARED_INLINE_P (clone)
+                   = DECL_DECLARED_INLINE_P (fn);
+                 DECL_INLINE (clone)
+                   = DECL_INLINE (fn);
+               }
+             check_specialization_namespace (fn);
 
              return fn;
            }
        }
       else if (DECL_TEMPLATE_SPECIALIZATION (fn))
        {
-         if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
+         if (!duplicate_decls (spec, fn, is_friend) && DECL_INITIAL (spec))
            /* Dup decl failed, but this is a new definition. Set the
               line number so any errors match this new
               definition.  */
@@ -1284,7 +1302,7 @@ print_candidates (tree fns)
       tree f;
 
       for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f))
-       cp_error_at ("%s %+#D", str, OVL_CURRENT (f));
+       error ("%s %+#D", str, OVL_CURRENT (f));
       str = "               ";
     }
 }
@@ -1302,6 +1320,11 @@ print_candidates (tree fns)
    template classes that appeared in the name of the function. See
    check_explicit_specialization for a more accurate description.
 
+   TSK indicates what kind of template declaration (if any) is being
+   declared.  TSK_TEMPLATE indicates that the declaration given by
+   DECL, though a FUNCTION_DECL, has template parameters, and is
+   therefore a template function.
+
    The template args (those explicitly specified and those deduced)
    are output in a newly created vector *TARGS_OUT.
 
@@ -1313,12 +1336,18 @@ determine_specialization (tree template_id,
                          tree decl,
                          tree* targs_out,
                          int need_member_template,
-                         int template_count)
+                         int template_count,
+                         tmpl_spec_kind tsk)
 {
   tree fns;
   tree targs;
   tree explicit_targs;
   tree candidates = NULL_TREE;
+  /* A TREE_LIST of templates of which DECL may be a specialization.
+     The TREE_VALUE of each node is a TEMPLATE_DECL.  The
+     corresponding TREE_PURPOSE is the set of template arguments that,
+     when used to instantiate the template, would produce a function
+     with the signature of DECL.  */
   tree templates = NULL_TREE;
   int header_count;
   struct cp_binding_level *b;
@@ -1422,9 +1451,22 @@ determine_specialization (tree template_id,
          if (current_binding_level->kind == sk_template_parms
              && !current_binding_level->explicit_spec_p
              && (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn))
-                 != TREE_VEC_LENGTH (TREE_VALUE (current_template_parms))))
+                 != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS 
+                                     (current_template_parms))))
            continue;
 
+         /* Function templates cannot be specializations; there are
+            no partial specializations of functions.  Therefore, if
+            the type of DECL does not match FN, there is no
+            match.  */
+         if (tsk == tsk_template)
+           {
+             if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+                            decl_arg_types))
+               candidates = tree_cons (NULL_TREE, fn, candidates);
+             continue;
+           }
+
          /* See whether this function might be a specialization of this
             template.  */
          targs = get_bindings (fn, decl, explicit_targs, /*check_ret=*/true);
@@ -1523,27 +1565,26 @@ determine_specialization (tree template_id,
         the EDG front-end has that behavior, and John Spicer claims
         that the committee simply forgot to delete the wording in
         [temp.expl.spec].  */
-     tree tmpl = most_specialized (templates, decl, explicit_targs);
-     if (tmpl && tmpl != error_mark_node)
-       {
-        targs = get_bindings (tmpl, decl, explicit_targs, /*check_ret=*/true);
-        templates = tree_cons (targs, tmpl, NULL_TREE);
-       }
+      tree tmpl = most_specialized_instantiation (templates);
+      if (tmpl != error_mark_node)
+       {
+         templates = tmpl;
+         TREE_CHAIN (templates) = NULL_TREE;
+       }
     }
 
   if (templates == NULL_TREE && candidates == NULL_TREE)
     {
-      cp_error_at ("template-id %qD for %q+D does not match any template "
-                  "declaration",
-                  template_id, decl);
+      error ("template-id %qD for %q+D does not match any template "
+            "declaration", template_id, decl);
       return error_mark_node;
     }
   else if ((templates && TREE_CHAIN (templates))
           || (candidates && TREE_CHAIN (candidates))
           || (templates && candidates))
     {
-      cp_error_at ("ambiguous template specialization %qD for %q+D",
-                  template_id, decl);
+      error ("ambiguous template specialization %qD for %q+D",
+            template_id, decl);
       chainon (candidates, templates);
       print_candidates (candidates);
       return error_mark_node;
@@ -1552,10 +1593,14 @@ determine_specialization (tree template_id,
   /* We have one, and exactly one, match.  */
   if (candidates)
     {
+      tree fn = TREE_VALUE (candidates);
+      /* DECL is a re-declaration of a template function.  */
+      if (TREE_CODE (fn) == TEMPLATE_DECL)
+       return fn;
       /* It was a specialization of an ordinary member function in a
         template class.  */
-      *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates)));
-      return DECL_TI_TEMPLATE (TREE_VALUE (candidates));
+      *targs_out = copy_node (DECL_TI_ARGS (fn));
+      return DECL_TI_TEMPLATE (fn);
     }
 
   /* It was a specialization of a template.  */
@@ -1859,8 +1904,6 @@ check_explicit_specialization (tree declarator,
              ("default argument specified in explicit specialization");
            break;
          }
-      if (current_lang_name == lang_name_c)
-       error ("template specialization with C linkage");
     }
 
   if (specialization || member_specialization || explicit_instantiation)
@@ -1884,12 +1927,21 @@ check_explicit_specialization (tree declarator,
 
              /* Find the namespace binding, using the declaration
                 context.  */
-             fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
+             fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
+                                          false, true);
              if (!fns || !is_overloaded_fn (fns))
                {
                  error ("%qD is not a template function", dname);
                  fns = error_mark_node;
                }
+             else
+               {
+                 tree fn = OVL_CURRENT (fns);
+                 if (!is_associated_namespace (CP_DECL_CONTEXT (decl),
+                                               CP_DECL_CONTEXT (fn)))
+                   error ("%qD is not declared in %qD",
+                          decl, current_namespace);
+               }
            }
 
          declarator = lookup_template_function (fns, NULL_TREE);
@@ -2011,7 +2063,8 @@ check_explicit_specialization (tree declarator,
       tmpl = determine_specialization (declarator, decl,
                                       &targs,
                                       member_specialization,
-                                      template_count);
+                                      template_count,
+                                      tsk);
 
       if (!tmpl || tmpl == error_mark_node)
        /* We couldn't figure out what this declaration was
@@ -2057,8 +2110,8 @@ check_explicit_specialization (tree declarator,
            revert_static_member_fn (decl);
 
          /* If this is a specialization of a member template of a
-            template class.  In we want to return the TEMPLATE_DECL,
-            not the specialization of it.  */
+            template class, we want to return the TEMPLATE_DECL, not
+            the specialization of it.  */
          if (tsk == tsk_template)
            {
              SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
@@ -2087,6 +2140,26 @@ check_explicit_specialization (tree declarator,
             template it specializes.  */
          TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
          TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
+         /* The specialization has the same visibility as the
+            template it specializes.  */
+         if (DECL_VISIBILITY_SPECIFIED (gen_tmpl))
+           {
+             DECL_VISIBILITY_SPECIFIED (decl) = 1;
+             DECL_VISIBILITY (decl) = DECL_VISIBILITY (gen_tmpl);
+           }
+         /* If DECL is a friend declaration, declared using an
+            unqualified name, the namespace associated with DECL may
+            have been set incorrectly.  For example, in:
+            
+              template <typename T> void f(T); 
+               namespace N {
+                struct S { friend void f<int>(int); }
+               }
+
+             we will have set the DECL_CONTEXT for the friend
+             declaration to N, rather than to the global namespace.  */
+         if (DECL_NAMESPACE_SCOPE_P (decl))
+           DECL_CONTEXT (decl) = DECL_CONTEXT (tmpl);
 
          if (is_friend && !have_def)
            /* This is not really a declaration of a specialization.
@@ -2101,7 +2174,7 @@ check_explicit_specialization (tree declarator,
 
          /* Register this specialization so that we can find it
             again.  */
-         decl = register_specialization (decl, gen_tmpl, targs);
+         decl = register_specialization (decl, gen_tmpl, targs, is_friend);
        }
     }
 
@@ -2197,8 +2270,8 @@ check_template_shadow (tree decl)
       || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
     return;
 
-  cp_error_at ("declaration of %q#D", decl);
-  cp_error_at (" shadows template parm %q#D", olddecl);
+  error ("declaration of %q+#D", decl);
+  error (" shadows template parm %q+#D", olddecl);
 }
 
 /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
@@ -2252,27 +2325,26 @@ reduce_template_parm_level (tree index, tree type, int levels)
                                     decl, type);
       TEMPLATE_PARM_DESCENDANTS (index) = t;
 
-      /* Template template parameters need this.  */
-      DECL_TEMPLATE_PARMS (decl)
-       = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
+       /* Template template parameters need this.  */
+      if (TREE_CODE (decl) != CONST_DECL)
+       DECL_TEMPLATE_PARMS (decl)
+         = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
     }
 
   return TEMPLATE_PARM_DESCENDANTS (index);
 }
 
-/* Process information from new template parameter NEXT and append it to the
+/* Process information from new template parameter PARM and append it to the
    LIST being built.  This new parameter is a non-type parameter iff
    IS_NON_TYPE is true.  */
 
 tree
-process_template_parm (tree list, tree next, bool is_non_type)
+process_template_parm (tree list, tree parm, bool is_non_type)
 {
-  tree parm;
   tree decl = 0;
   tree defval;
   int idx;
 
-  parm = next;
   gcc_assert (TREE_CODE (parm) == TREE_LIST);
   defval = TREE_PURPOSE (parm);
 
@@ -2295,18 +2367,23 @@ process_template_parm (tree list, tree next, bool is_non_type)
 
       SET_DECL_TEMPLATE_PARM_P (parm);
 
-      /* [temp.param]
+      if (TREE_TYPE (parm) == error_mark_node)
+       TREE_TYPE (parm) = void_type_node;
+      else
+      {
+       /* [temp.param]
 
-        The top-level cv-qualifiers on the template-parameter are
-        ignored when determining its type.  */
-      TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
+          The top-level cv-qualifiers on the template-parameter are
+          ignored when determining its type.  */
+       TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
+       if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
+         TREE_TYPE (parm) = void_type_node;
+      }
 
       /* A template parameter is not modifiable.  */
       TREE_CONSTANT (parm) = 1;
       TREE_INVARIANT (parm) = 1;
       TREE_READONLY (parm) = 1;
-      if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-       TREE_TYPE (parm) = void_type_node;
       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
       TREE_CONSTANT (decl) = 1;
       TREE_INVARIANT (decl) = 1;
@@ -2400,7 +2477,7 @@ end_template_decl (void)
 /* Given a template argument vector containing the template PARMS.
    The innermost PARMS are given first.  */
 
-tree
+static tree
 current_template_args (void)
 {
   tree header;
@@ -2580,10 +2657,10 @@ process_partial_specialization (tree decl)
 
      or some such would have been OK.  */
   tpd.level = TMPL_PARMS_DEPTH (current_template_parms);
-  tpd.parms = alloca (sizeof (int) * ntparms);
+  tpd.parms = (int *) alloca (sizeof (int) * ntparms);
   memset (tpd.parms, 0, sizeof (int) * ntparms);
 
-  tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs);
+  tpd.arg_uses_template_parms = (int *) alloca (sizeof (int) * nargs);
   memset (tpd.arg_uses_template_parms, 0, sizeof (int) * nargs);
   for (i = 0; i < nargs; ++i)
     {
@@ -2654,11 +2731,11 @@ process_partial_specialization (tree decl)
                {
                  /* We haven't yet initialized TPD2.  Do so now.  */
                  tpd2.arg_uses_template_parms
-                   = alloca (sizeof (int) * nargs);
+                   = (int *) alloca (sizeof (int) * nargs);
                  /* The number of parameters here is the number in the
                     main template, which, as checked in the assertion
                     above, is NARGS.  */
-                 tpd2.parms = alloca (sizeof (int) * nargs);
+                 tpd2.parms = (int *) alloca (sizeof (int) * nargs);
                  tpd2.level =
                    TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
                }
@@ -2701,7 +2778,7 @@ process_partial_specialization (tree decl)
     return decl;
 
   DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
-    = tree_cons (inner_args, inner_parms,
+    = tree_cons (specargs, inner_parms,
                 DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
   TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
   return decl;
@@ -2874,10 +2951,10 @@ template_parm_this_level_p (tree t, void* data)
    previously existing one, if appropriate.  Returns the DECL, or an
    equivalent one, if it is replaced via a call to duplicate_decls.
 
-   If IS_FRIEND is nonzero, DECL is a friend declaration.  */
+   If IS_FRIEND is true, DECL is a friend declaration.  */
 
 tree
-push_template_decl_real (tree decl, int is_friend)
+push_template_decl_real (tree decl, bool is_friend)
 {
   tree tmpl;
   tree args;
@@ -2898,7 +2975,8 @@ push_template_decl_real (tree decl, int is_friend)
                && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
                && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)));
 
-  is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl));
+  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl))
+    is_friend = true;
 
   if (is_friend)
     /* For a friend, we want the context of the friend function, not
@@ -2927,10 +3005,8 @@ push_template_decl_real (tree decl, int is_friend)
     {
       if (DECL_CLASS_SCOPE_P (decl))
        member_template_p = true;
-      if (current_lang_name == lang_name_c)
-       error ("template with C linkage");
-      else if (TREE_CODE (decl) == TYPE_DECL
-              && ANON_AGGRNAME_P (DECL_NAME (decl)))
+      if (TREE_CODE (decl) == TYPE_DECL
+         && ANON_AGGRNAME_P (DECL_NAME (decl)))
        error ("template class without a name");
       else if (TREE_CODE (decl) == FUNCTION_DECL)
        {
@@ -2955,12 +3031,11 @@ push_template_decl_real (tree decl, int is_friend)
                 template. ... Template allocation functions shall
                 have two or more parameters.  */
              error ("invalid template declaration of %qD", decl);
-             return decl;
+             return error_mark_node;
            }
        }
-      else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
-               && CLASS_TYPE_P (TREE_TYPE (decl)))
-              || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)))
+      else if (DECL_IMPLICIT_TYPEDEF_P (decl)
+              && CLASS_TYPE_P (TREE_TYPE (decl)))
        /* OK */;
       else
        {
@@ -3073,7 +3148,8 @@ push_template_decl_real (tree decl, int is_friend)
 
          register_specialization (new_tmpl,
                                   most_general_template (tmpl),
-                                  args);
+                                  args,
+                                  is_friend);
          return decl;
        }
 
@@ -3101,6 +3177,7 @@ push_template_decl_real (tree decl, int is_friend)
                  error ("got %d template parameters for %q#T",
                         TREE_VEC_LENGTH (a), current);
                error ("  but %d required", TREE_VEC_LENGTH (t));
+               return error_mark_node;
              }
 
            /* Perhaps we should also check that the parms are used in the
@@ -3123,7 +3200,7 @@ push_template_decl_real (tree decl, int is_friend)
   if (new_template_p && !ctx
       && !(is_friend && template_class_depth (current_class_type) > 0))
     {
-      tmpl = pushdecl_namespace_level (tmpl);
+      tmpl = pushdecl_namespace_level (tmpl, is_friend);
       if (tmpl == error_mark_node)
        return error_mark_node;
 
@@ -3178,7 +3255,7 @@ push_template_decl_real (tree decl, int is_friend)
 tree
 push_template_decl (tree decl)
 {
-  return push_template_decl_real (decl, 0);
+  return push_template_decl_real (decl, false);
 }
 
 /* Called when a class template TYPE is redeclared with the indicated
@@ -3219,7 +3296,7 @@ redeclare_class_template (tree type, tree parms)
 
   if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
     {
-      cp_error_at ("previous declaration %qD", tmpl);
+      error ("previous declaration %q+D", tmpl);
       error ("used %d template parameter(s) instead of %d",
             TREE_VEC_LENGTH (tmpl_parms),
             TREE_VEC_LENGTH (parms));
@@ -3239,7 +3316,7 @@ redeclare_class_template (tree type, tree parms)
          || (TREE_CODE (tmpl_parm) != TYPE_DECL
              && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
        {
-         cp_error_at ("template parameter %q#D", tmpl_parm);
+         error ("template parameter %q+#D", tmpl_parm);
          error ("redeclared here as %q#D", parm);
          return;
        }
@@ -3306,7 +3383,7 @@ fold_non_dependent_expr (tree expr)
    initializers can maintain a syntactic rather than semantic form
    (even if they are non-dependent, for access-checking purposes).  */
 
-tree
+static tree
 fold_decl_constant_value (tree expr)
 {
   tree const_expr = expr;
@@ -3402,6 +3479,8 @@ convert_nontype_argument (tree type, tree expr)
      instantiated -- but here we need the resolved form so that we can
      convert the argument.  */
   expr = fold_non_dependent_expr (expr);
+  if (error_operand_p (expr))
+    return error_mark_node;
   expr_type = TREE_TYPE (expr);
 
   /* HACK: Due to double coercion, we can get a
@@ -3541,7 +3620,7 @@ convert_nontype_argument (tree type, tree expr)
       if (!real_lvalue_p (expr))
        {
          error ("%qE is not a valid template argument for type %qT "
-                "because it is not a lvalue", expr, type);
+                "because it is not an lvalue", expr, type);
          return NULL_TREE;
        }
 
@@ -3571,9 +3650,7 @@ convert_nontype_argument (tree type, tree expr)
   else if (TYPE_PTRFN_P (type))
     {
       /* If the argument is a template-id, we might not have enough
-        context information to decay the pointer.
-        ??? Why static5.C requires decay and subst1.C works fine
-        even without it?  */
+        context information to decay the pointer.  */
       if (!type_unknown_p (expr_type))
        {
          expr = decay_conversion (expr);
@@ -3665,17 +3742,12 @@ convert_nontype_argument (tree type, tree expr)
    vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL
    or PARM_DECL.
 
-   ARG_PARMS may contain more parameters than PARM_PARMS.  If this is
-   the case, then extra parameters must have default arguments.
-
    Consider the example:
-     template <class T, class Allocator = allocator> class vector;
-     template<template <class U> class TT> class C;
+     template <class T> class A;
+     template<template <class U> class TT> class B;
 
-   C<vector> is a valid instantiation.  PARM_PARMS for the above code
-   contains a TYPE_DECL (for U),  ARG_PARMS contains two TYPE_DECLs (for
-   T and Allocator) and OUTER_ARGS contains the argument that is used to
-   substitute the TT parameter.  */
+   For B<A>, PARM_PARMS are the parameters to TT, while ARG_PARMS are
+   the parameters to A, and OUTER_ARGS contains A.  */
 
 static int
 coerce_template_template_parms (tree parm_parms,
@@ -3693,10 +3765,7 @@ coerce_template_template_parms (tree parm_parms,
   nparms = TREE_VEC_LENGTH (parm_parms);
   nargs = TREE_VEC_LENGTH (arg_parms);
 
-  /* The rule here is opposite of coerce_template_parms.  */
-  if (nargs < nparms
-      || (nargs > nparms
-         && TREE_PURPOSE (TREE_VEC_ELT (arg_parms, nparms)) == NULL_TREE))
+  if (nargs != nparms)
     return 0;
 
   for (i = 0; i < nparms; ++i)
@@ -3891,6 +3960,13 @@ convert_template_argument (tree parm,
        }
       else
        val = 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 
+        the typedef, which is confusing if those future uses do not
+        themselves also use the typedef.  */
+      if (TYPE_P (val))
+       val = canonical_type_variant (val);
     }
   else
     {
@@ -3928,17 +4004,20 @@ convert_template_argument (tree parm,
    arguments.  If any error occurs, return error_mark_node. Error and
    warning messages are issued under control of COMPLAIN.
 
-   If REQUIRE_ALL_ARGUMENTS is nonzero, all arguments must be
-   provided in ARGLIST, or else trailing parameters must have default
-   values.  If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument
-   deduction for any unspecified trailing arguments.  */
+   If REQUIRE_ALL_ARGS is false, argument deduction will be performed
+   for arguments not specified in ARGS.  Otherwise, if
+   USE_DEFAULT_ARGS is true, default arguments will be used to fill in
+   unspecified arguments.  If REQUIRE_ALL_ARGS is true, but
+   USE_DEFAULT_ARGS is false, then all arguments must be specified in
+   ARGS.  */
 
 static tree
 coerce_template_parms (tree parms,
                       tree args,
                       tree in_decl,
                       tsubst_flags_t complain,
-                      int require_all_arguments)
+                      bool require_all_args,
+                      bool use_default_args)
 {
   int nparms, nargs, i, lost = 0;
   tree inner_args;
@@ -3951,8 +4030,9 @@ coerce_template_parms (tree parms,
 
   if (nargs > nparms
       || (nargs < nparms
-         && require_all_arguments
-         && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE))
+         && require_all_args
+         && (!use_default_args
+             || !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))
     {
       if (complain & tf_error)
        {
@@ -3960,7 +4040,7 @@ coerce_template_parms (tree parms,
                 nargs, nparms);
 
          if (in_decl)
-           cp_error_at ("provided for %qD", in_decl);
+           error ("provided for %q+D", in_decl);
        }
 
       return error_mark_node;
@@ -3979,7 +4059,7 @@ coerce_template_parms (tree parms,
       /* Calculate the Ith argument.  */
       if (i < nargs)
        arg = TREE_VEC_ELT (inner_args, i);
-      else if (require_all_arguments)
+      else if (require_all_args)
        /* There must be a default arg in this case.  */
        arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
                                   complain, in_decl);
@@ -4063,7 +4143,7 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
     gcc_obstack_init (&scratch_obstack);
   else
     obstack_free (&scratch_obstack, scratch_firstobj);
-  scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
+  scratch_firstobj = (char *) obstack_alloc (&scratch_obstack, 1);
 
 #define ccat(C)        obstack_1grow (&scratch_obstack, (C));
 #define cat(S) obstack_grow (&scratch_obstack, (S), strlen (S))
@@ -4292,7 +4372,7 @@ lookup_template_class (tree d1,
        {
          if (context)
            push_decl_namespace (context);
-         template = lookup_name (d1, /*prefer_type=*/0);
+         template = lookup_name (d1);
          template = maybe_get_template_decl_from_type_decl (template);
          if (context)
            pop_decl_namespace ();
@@ -4347,7 +4427,7 @@ lookup_template_class (tree d1,
        {
          error ("non-template type %qT used as a template", d1);
          if (in_decl)
-           cp_error_at ("for template declaration %qD", in_decl);
+           error ("for template declaration %q+D", in_decl);
        }
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
     }
@@ -4384,7 +4464,9 @@ lookup_template_class (tree d1,
        arglist = add_to_template_args (current_template_args (), arglist);
 
       arglist2 = coerce_template_parms (parmlist, arglist, template,
-                                       complain, /*require_all_args=*/1);
+                                       complain, 
+                                       /*require_all_args=*/true,
+                                       /*use_default_args=*/true);
       if (arglist2 == error_mark_node
          || (!uses_template_parms (arglist2)
              && check_instantiated_args (template, arglist2, complain)))
@@ -4453,7 +4535,9 @@ lookup_template_class (tree d1,
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
                                              arglist, template,
-                                             complain, /*require_all_args=*/1);
+                                             complain, 
+                                             /*require_all_args=*/true,
+                                             /*use_default_args=*/true);
 
              /* Don't process further if one of the levels fails.  */
              if (a == error_mark_node)
@@ -4482,7 +4566,9 @@ lookup_template_class (tree d1,
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
                                   template,
-                                  complain, /*require_all_args=*/1);
+                                  complain, 
+                                  /*require_all_args=*/true,
+                                  /*use_default_args=*/true);
 
       if (arglist == error_mark_node)
        /* We were unable to bind the arguments.  */
@@ -4606,6 +4692,11 @@ lookup_template_class (tree d1,
        = 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;
+         DECL_VISIBILITY (type_decl) = CLASSTYPE_VISIBILITY (template_type);
+       }
 
       /* Set up the template information.  We have to figure out which
         template is the immediate parent if this is a full
@@ -4937,11 +5028,14 @@ uses_template_parms (tree t)
   else if (TREE_CODE (t) == TREE_LIST)
     dependent_p = (uses_template_parms (TREE_VALUE (t))
                   || uses_template_parms (TREE_CHAIN (t)));
+  else if (TREE_CODE (t) == TYPE_DECL)
+    dependent_p = dependent_type_p (TREE_TYPE (t));
   else if (DECL_P (t)
           || EXPR_P (t)
           || TREE_CODE (t) == TEMPLATE_PARM_INDEX
           || TREE_CODE (t) == OVERLOAD
           || TREE_CODE (t) == BASELINK
+          || TREE_CODE (t) == IDENTIFIER_NODE
           || CONSTANT_CLASS_P (t))
     dependent_p = (type_dependent_expression_p (t)
                   || value_dependent_expression_p (t));
@@ -4975,7 +5069,7 @@ static int last_template_error_tick;
 /* We're starting to instantiate D; record the template instantiation context
    for diagnostics and to restore it later.  */
 
-int
+static int
 push_tinst_level (tree d)
 {
   tree new;
@@ -5018,7 +5112,7 @@ push_tinst_level (tree d)
 /* We're done instantiating this template; return to the instantiation
    context.  */
 
-void
+static void
 pop_tinst_level (void)
 {
   tree old = current_tinst_level;
@@ -5081,21 +5175,22 @@ tsubst_friend_function (tree decl, tree args)
         current cless with same name.  */
       push_nested_namespace (ns);
       fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
-                        tf_error | tf_warning, NULL_TREE);
+                        tf_warning_or_error, NULL_TREE);
       pop_nested_namespace (ns);
       arglist = tsubst (DECL_TI_ARGS (decl), args,
-                       tf_error | tf_warning, NULL_TREE);
+                       tf_warning_or_error, NULL_TREE);
       template_id = lookup_template_function (fns, arglist);
 
-      new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
+      new_friend = tsubst (decl, args, tf_warning_or_error, NULL_TREE);
       tmpl = determine_specialization (template_id, new_friend,
                                       &new_args,
                                       /*need_member_template=*/0,
-                                      TREE_VEC_LENGTH (args));
+                                      TREE_VEC_LENGTH (args),
+                                      tsk_none);
       return instantiate_template (tmpl, new_args, tf_error);
     }
 
-  new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
+  new_friend = tsubst (decl, args, tf_warning_or_error, NULL_TREE);
 
   /* The NEW_FRIEND will look like an instantiation, to the
      compiler, but is not an instantiation from the point of view of
@@ -5160,9 +5255,12 @@ tsubst_friend_function (tree decl, tree args)
         into the namespace of the template.  */
       ns = decl_namespace_context (new_friend);
       push_nested_namespace (ns);
-      old_decl = pushdecl_namespace_level (new_friend);
+      old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
       pop_nested_namespace (ns);
 
+      if (old_decl == error_mark_node)
+       return error_mark_node;
+
       if (old_decl != new_friend)
        {
          /* This new friend declaration matched an existing
@@ -5316,7 +5414,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
     }
 
   /* First, we look for a class template.  */
-  tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
+  tmpl = lookup_name (DECL_NAME (friend_tmpl));
 
   /* But, if we don't find one, it might be because we're in a
      situation like this:
@@ -5331,7 +5429,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
      for `S<int>', not the TEMPLATE_DECL.  */
   if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
     {
-      tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
+      tmpl = lookup_name_prefer_type (DECL_NAME (friend_tmpl), 1);
       tmpl = maybe_get_template_decl_from_type_decl (tmpl);
     }
 
@@ -5348,7 +5446,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
        {
          tree parms;
          parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
-                                        args, tf_error | tf_warning);
+                                        args, tf_warning_or_error);
          redeclare_class_template (TREE_TYPE (tmpl), parms);
        }
 
@@ -5359,7 +5457,9 @@ tsubst_friend_class (tree friend_tmpl, tree args)
       /* The friend template has not already been declared.  In this
         case, the instantiation of the template class will cause the
         injection of this template into the global scope.  */
-      tmpl = tsubst (friend_tmpl, args, tf_error | tf_warning, NULL_TREE);
+      tmpl = tsubst (friend_tmpl, args, tf_warning_or_error, NULL_TREE);
+      if (tmpl == error_mark_node)
+       return error_mark_node;
 
       /* The new TMPL is not an instantiation of anything, so we
         forget its origins.  We don't reset CLASSTYPE_TI_TEMPLATE for
@@ -5372,7 +5472,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
        = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)));
 
       /* Inject this template into the global scope.  */
-      friend_type = TREE_TYPE (pushdecl_top_level (tmpl));
+      friend_type = TREE_TYPE (pushdecl_top_level_maybe_friend (tmpl, true));
     }
 
   if (context)
@@ -5425,34 +5525,34 @@ instantiate_class_template (tree type)
   template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
   gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
 
-  /* Figure out which arguments are being used to do the
-     instantiation.  */
-  args = CLASSTYPE_TI_ARGS (type);
-
   /* Determine what specialization of the original template to
      instantiate.  */
-  t = most_specialized_class (template, args);
+  t = most_specialized_class (type, template);
   if (t == error_mark_node)
     {
-      const char *str = "candidates are:";
-      error ("ambiguous class template instantiation for %q#T", type);
-      for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
-          t = TREE_CHAIN (t))
-       {
-         if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args))
-           {
-             cp_error_at ("%s %+#T", str, TREE_TYPE (t));
-             str = "               ";
-           }
-       }
       TYPE_BEING_DEFINED (type) = 1;
       return error_mark_node;
     }
+  else if (t)
+    {
+      /* This TYPE is actually an instantiation of a partial
+        specialization.  We replace the innermost set of ARGS with
+        the arguments appropriate for substitution.  For example,
+        given:
+       
+           template <class T> struct S {};
+          template <class T> struct S<T*> {};
 
-  if (t)
-    pattern = TREE_TYPE (t);
+        and supposing that we are instantiating S<int*>, ARGS will
+         presently be {int*} -- but we need {int}.  */
+      pattern = TREE_TYPE (t);
+      args = TREE_PURPOSE (t);
+    }
   else
-    pattern = TREE_TYPE (template);
+    {
+      pattern = TREE_TYPE (template);
+      args = CLASSTYPE_TI_ARGS (type);
+    }
 
   /* If the template we're instantiating is incomplete, then clearly
      there's nothing we can do.  */
@@ -5473,34 +5573,6 @@ instantiate_class_template (tree type)
 
   push_to_top_level ();
 
-  if (t)
-    {
-      /* This TYPE is actually an instantiation of a partial
-        specialization.  We replace the innermost set of ARGS with
-        the arguments appropriate for substitution.  For example,
-        given:
-
-          template <class T> struct S {};
-          template <class T> struct S<T*> {};
-
-        and supposing that we are instantiating S<int*>, ARGS will
-        present be {int*} but we need {int}.  */
-      tree inner_args
-       = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
-                             args);
-
-      /* If there were multiple levels in ARGS, replacing the
-        innermost level would alter CLASSTYPE_TI_ARGS, which we don't
-        want, so we make a copy first.  */
-      if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
-       {
-         args = copy_node (args);
-         SET_TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args), inner_args);
-       }
-      else
-       args = inner_args;
-    }
-
   SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
 
   /* Set the input location to the template definition. This is needed
@@ -5525,6 +5597,11 @@ instantiate_class_template (tree type)
   TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
   if (ANON_AGGR_TYPE_P (pattern))
     SET_ANON_AGGR_TYPE_P (type);
+  if (CLASSTYPE_VISIBILITY_SPECIFIED (pattern))
+    {
+      CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1;
+      CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern);
+    }
 
   pbinfo = TYPE_BINFO (pattern);
 
@@ -5596,14 +5673,12 @@ instantiate_class_template (tree type)
            {
              /* Build new CLASSTYPE_NESTED_UTDS.  */
 
-             tree tag = t;
-             tree name = TYPE_IDENTIFIER (tag);
              tree newtag;
              bool class_template_p;
 
-             class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE
-                                 && TYPE_LANG_SPECIFIC (tag)
-                                 && CLASSTYPE_IS_TEMPLATE (tag));
+             class_template_p = (TREE_CODE (t) != ENUMERAL_TYPE
+                                 && TYPE_LANG_SPECIFIC (t)
+                                 && CLASSTYPE_IS_TEMPLATE (t));
              /* If the member is a class template, then -- even after
                 substitution -- there may be dependent types in the
                 template argument list for the class.  We increment
@@ -5612,7 +5687,7 @@ instantiate_class_template (tree type)
                 when outside of a template.  */
              if (class_template_p)
                ++processing_template_decl;
-             newtag = tsubst (tag, args, tf_error, NULL_TREE);
+             newtag = tsubst (t, args, tf_error, NULL_TREE);
              if (class_template_p)
                --processing_template_decl;
              if (newtag == error_mark_node)
@@ -5620,6 +5695,8 @@ instantiate_class_template (tree type)
 
              if (TREE_CODE (newtag) != ENUMERAL_TYPE)
                {
+                 tree name = TYPE_IDENTIFIER (t);
+
                  if (class_template_p)
                    /* Unfortunately, lookup_template_class sets
                       CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
@@ -5655,7 +5732,6 @@ instantiate_class_template (tree type)
              if (TREE_CODE (t) == TEMPLATE_DECL)
                --processing_template_decl;
              set_current_access_from_decl (r);
-             grok_special_member_properties (r);
              finish_member_declaration (r);
            }
          else
@@ -5674,22 +5750,28 @@ instantiate_class_template (tree type)
 
                  if (TREE_CODE (t) == TEMPLATE_DECL)
                    ++processing_template_decl;
-                 r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
+                 r = tsubst (t, args, tf_warning_or_error, NULL_TREE);
                  if (TREE_CODE (t) == TEMPLATE_DECL)
                    --processing_template_decl;
                  if (TREE_CODE (r) == VAR_DECL)
                    {
-                     tree init;
-
-                     if (DECL_INITIALIZED_IN_CLASS_P (r))
-                       init = tsubst_expr (DECL_INITIAL (t), args,
-                                           tf_error | tf_warning, NULL_TREE);
-                     else
-                       init = NULL_TREE;
-
-                     finish_static_data_member_decl
-                       (r, init, /*asmspec_tree=*/NULL_TREE, /*flags=*/0);
-
+                     /* In [temp.inst]:
+
+                          [t]he initialization (and any associated
+                          side-effects) of a static data member does
+                          not occur unless the static data member is
+                          itself used in a way that requires the
+                          definition of the static data member to
+                          exist.  
+
+                        Therefore, we do not substitute into the
+                        initialized for the static data member here.  */
+                     finish_static_data_member_decl 
+                       (r, 
+                        /*init=*/NULL_TREE, 
+                        /*init_const_expr_p=*/false,
+                        /*asmspec_tree=*/NULL_TREE, 
+                        /*flags=*/0);
                      if (DECL_INITIALIZED_IN_CLASS_P (r))
                        check_static_variable_definition (r, TREE_TYPE (r));
                    }
@@ -5743,7 +5825,7 @@ instantiate_class_template (tree type)
                {
                  /* template <class T> friend class C::D;  */
                  friend_type = tsubst (friend_type, args,
-                                       tf_error | tf_warning, NULL_TREE);
+                                       tf_warning_or_error, NULL_TREE);
                  if (TREE_CODE (friend_type) == TEMPLATE_DECL)
                    friend_type = TREE_TYPE (friend_type);
                  adjust_processing_template_decl = true;
@@ -5760,7 +5842,7 @@ instantiate_class_template (tree type)
 
                     otherwise.  */
                  friend_type = tsubst (friend_type, args,
-                                       tf_error | tf_warning, NULL_TREE);
+                                       tf_warning_or_error, NULL_TREE);
                  /* Bump processing_template_decl for correct
                     dependent_type_p calculation.  */
                  ++processing_template_decl;
@@ -5789,7 +5871,7 @@ instantiate_class_template (tree type)
              else if (uses_template_parms (friend_type))
                /* friend class C<T>;  */
                friend_type = tsubst (friend_type, args,
-                                     tf_error | tf_warning, NULL_TREE);
+                                     tf_warning_or_error, NULL_TREE);
              /* Otherwise it's
 
                   friend class C;
@@ -5891,32 +5973,7 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   else
     {
       r = tsubst_expr (t, args, complain, in_decl);
-
-      if (!uses_template_parms (r))
-       {
-         /* Sometimes, one of the args was an expression involving a
-            template constant parameter, like N - 1.  Now that we've
-            tsubst'd, we might have something like 2 - 1.  This will
-            confuse lookup_template_class, so we do constant folding
-            here.  We have to unset processing_template_decl, to fool
-            tsubst_copy_and_build() into building an actual tree.  */
-
-        /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
-           as simple as it's going to get, and trying to reprocess
-           the trees will break.  Once tsubst_expr et al DTRT for
-           non-dependent exprs, this code can go away, as the type
-           will always be set.  */
-         if (!TREE_TYPE (r))
-           {
-             int saved_processing_template_decl = processing_template_decl;
-             processing_template_decl = 0;
-             r = tsubst_copy_and_build (r, /*args=*/NULL_TREE,
-                                        tf_error, /*in_decl=*/NULL_TREE,
-                                        /*function_p=*/false);
-             processing_template_decl = saved_processing_template_decl;
-           }
-         r = fold (r);
-       }
+      r = fold_non_dependent_expr (r);
     }
   return r;
 }
@@ -5928,7 +5985,7 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 {
   int len = TREE_VEC_LENGTH (t);
   int need_new = 0, i;
-  tree *elts = alloca (len * sizeof (tree));
+  tree *elts = (tree *) alloca (len * sizeof (tree));
 
   for (i = 0; i < len; i++)
     {
@@ -5971,6 +6028,12 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
   tree r = NULL_TREE;
   tree* new_parms;
 
+  /* When substituting into a template, we must set
+     PROCESSING_TEMPLATE_DECL as the template parameters may be
+     dependent if they are based on one-another, and the dependency
+     predicates are short-circuit outside of templates.  */
+  ++processing_template_decl;
+
   for (new_parms = &r;
        TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args);
        new_parms = &(TREE_CHAIN (*new_parms)),
@@ -5987,6 +6050,9 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
          tree parm_decl = TREE_VALUE (tuple);
 
          parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+         if (TREE_CODE (parm_decl) == PARM_DECL
+             && invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain))
+           parm_decl = error_mark_node;
          default_value = tsubst_template_arg (default_value, args,
                                               complain, NULL_TREE);
 
@@ -6000,6 +6066,8 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
                   new_vec, NULL_TREE);
     }
 
+  --processing_template_decl;
+
   return r;
 }
 
@@ -6033,6 +6101,11 @@ tsubst_aggr_type (tree t,
          tree argvec;
          tree context;
          tree r;
+         bool saved_skip_evaluation;
+
+         /* In "sizeof(X<I>)" we need to evaluate "I".  */
+         saved_skip_evaluation = skip_evaluation;
+         skip_evaluation = false;
 
          /* First, determine the context for the type we are looking
             up.  */
@@ -6053,12 +6126,17 @@ tsubst_aggr_type (tree t,
          argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
                                         complain, in_decl);
          if (argvec == error_mark_node)
-           return error_mark_node;
-
-         r = lookup_template_class (t, argvec, in_decl, context,
-                                    entering_scope, complain);
+           r = error_mark_node;
+         else
+           {
+             r = lookup_template_class (t, argvec, in_decl, context,
+                                        entering_scope, complain);
+             r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
+           }
+         
+         skip_evaluation = saved_skip_evaluation;
 
-         return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
+         return r;
        }
       else
        /* This is not a template type, so there's nothing to do.  */
@@ -6091,10 +6169,6 @@ tsubst_default_argument (tree fn, tree type, tree arg)
      we must be careful to do name lookup in the scope of S<T>,
      rather than in the current class.  */
   push_access_scope (fn);
-  /* The default argument expression should not be considered to be
-     within the scope of FN.  Since push_access_scope sets
-     current_function_decl, we must explicitly clear it here.  */
-  current_function_decl = NULL_TREE;
   /* The "this" pointer is not valid in a default argument.  */
   if (cfun)
     {
@@ -6105,8 +6179,15 @@ tsubst_default_argument (tree fn, tree type, tree arg)
     }
 
   push_deferring_access_checks(dk_no_deferred);
+  /* The default argument expression may cause implicitly defined
+     member functions to be synthesized, which will result in garbage
+     collection.  We must treat this situation as if we were within
+     the body of function so as to avoid collecting live data on the
+     stack.  */
+  ++function_depth;
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
-                    tf_error | tf_warning, NULL_TREE);
+                    tf_warning_or_error, NULL_TREE);
+  --function_depth;
   pop_deferring_access_checks();
 
   /* Restore the "this" pointer.  */
@@ -6201,8 +6282,16 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        tmpl_args = DECL_CLASS_TEMPLATE_P (t)
          ? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
          : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
+       /* Because this is a template, the arguments will still be
+          dependent, even after substitution.  If
+          PROCESSING_TEMPLATE_DECL is not set, the dependency
+          predicates will short-circuit.  */
+       ++processing_template_decl;
        full_args = tsubst_template_args (tmpl_args, args,
                                          complain, in_decl);
+       --processing_template_decl;
+       if (full_args == error_mark_node)
+         return error_mark_node;
 
        /* tsubst_template_args doesn't copy the vector if
           nothing changed.  But, *something* should have
@@ -6226,15 +6315,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
        TREE_CHAIN (r) = NULL_TREE;
 
-       DECL_CONTEXT (r)
-         = tsubst_aggr_type (DECL_CONTEXT (t), args,
-                             complain, in_decl,
-                             /*entering_scope=*/1);
        DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
 
        if (TREE_CODE (decl) == TYPE_DECL)
          {
-           tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+           tree new_type;
+           ++processing_template_decl;
+           new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+           --processing_template_decl; 
            if (new_type == error_mark_node)
              return error_mark_node;
 
@@ -6242,10 +6330,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            CLASSTYPE_TI_TEMPLATE (new_type) = r;
            DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
            DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type);
+           DECL_CONTEXT (r) = TYPE_CONTEXT (new_type);
          }
        else
          {
-           tree new_decl = tsubst (decl, args, complain, in_decl);
+           tree new_decl;
+           ++processing_template_decl;
+           new_decl = tsubst (decl, args, complain, in_decl);
+           --processing_template_decl;
            if (new_decl == error_mark_node)
              return error_mark_node;
 
@@ -6253,6 +6345,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_TI_TEMPLATE (new_decl) = r;
            TREE_TYPE (r) = TREE_TYPE (new_decl);
            DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl);
+           DECL_CONTEXT (r) = DECL_CONTEXT (new_decl); 
          }
 
        SET_DECL_IMPLICIT_INSTANTIATION (r);
@@ -6272,7 +6365,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (TREE_CODE (decl) != TYPE_DECL)
          /* Record this non-type partial instantiation.  */
          register_specialization (r, t,
-                                  DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
+                                  DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)),
+                                  false);
       }
       break;
 
@@ -6447,7 +6541,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_TEMPLATE_INFO (r)
              = tree_cons (gen_tmpl, argvec, NULL_TREE);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
-           register_specialization (r, gen_tmpl, argvec);
+           register_specialization (r, gen_tmpl, argvec, false);
 
            /* We're not supposed to instantiate default arguments
               until they are called, for a template.  But, for a
@@ -6465,6 +6559,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                && !uses_template_parms (argvec))
              tsubst_default_arguments (r);
          }
+       else
+         DECL_TEMPLATE_INFO (r) = NULL_TREE;
 
        /* Copy the list of befriending classes.  */
        for (friends = &DECL_BEFRIENDING_CLASSES (r);
@@ -6547,7 +6643,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                                        complain, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
        if (VOID_TYPE_P (type))
-         cp_error_at ("instantiation of %qD as type %qT", r, type);
+         error ("instantiation of %q+D as type %qT", r, type);
       }
       break;
 
@@ -6632,6 +6728,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        r = copy_decl (t);
        if (TREE_CODE (r) == VAR_DECL)
          {
+           /* Even if the original location is out of scope, the
+              newly substituted one is not.  */
+           DECL_DEAD_FOR_LOCAL (r) = 0;
+           DECL_INITIALIZED_P (r) = 0;
+           DECL_TEMPLATE_INSTANTIATED (r) = 0;
            type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            if (type == error_mark_node)
              return error_mark_node;
@@ -6639,6 +6740,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
              = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
            type = check_var_type (DECL_NAME (r), type);
+
+           if (DECL_HAS_VALUE_EXPR_P (t))
+             {
+               tree ve = DECL_VALUE_EXPR (t);
+               ve = tsubst_expr (ve, args, complain, in_decl);
+               SET_DECL_VALUE_EXPR (r, ve);
+             }
          }
        else if (DECL_SELF_REFERENCE_P (t))
          SET_DECL_SELF_REFERENCE_P (r);
@@ -6647,22 +6755,15 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        DECL_CONTEXT (r) = ctx;
        /* Clear out the mangled name and RTL for the instantiation.  */
        SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
-       SET_DECL_RTL (r, NULL_RTX);
-
-       /* Don't try to expand the initializer until someone tries to use
-          this variable; otherwise we run into circular dependencies.  */
+       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
+         SET_DECL_RTL (r, NULL_RTX);
+       /* The initializer must not be expanded until it is required;
+          see [temp.inst].  */
        DECL_INITIAL (r) = NULL_TREE;
-       SET_DECL_RTL (r, NULL_RTX);
+       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
+         SET_DECL_RTL (r, NULL_RTX);
        DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
 
-       /* Even if the original location is out of scope, the newly
-          substituted one is not.  */
-       if (TREE_CODE (r) == VAR_DECL)
-         {
-           DECL_DEAD_FOR_LOCAL (r) = 0;
-           DECL_INITIALIZED_P (r) = 0;
-         }
-
        if (!local_p)
          {
            /* A static data member declaration is always marked
@@ -6671,7 +6772,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               processing here.  */
            DECL_EXTERNAL (r) = 1;
 
-           register_specialization (r, gen_tmpl, argvec);
+           register_specialization (r, gen_tmpl, argvec, false);
            DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
          }
@@ -6723,7 +6824,7 @@ tsubst_arg_types (tree arg_types,
        {
          error ("invalid parameter type %qT", type);
          if (in_decl)
-           cp_error_at ("in declaration %qD", in_decl);
+           error ("in declaration %q+D", in_decl);
        }
       return error_mark_node;
     }
@@ -6872,39 +6973,6 @@ tsubst_exception_specification (tree fntype,
   return new_specs;
 }
 
-/* Substitute into the PARMS of a call-declarator.  */
-
-static tree
-tsubst_call_declarator_parms (tree parms,
-                             tree args,
-                             tsubst_flags_t complain,
-                             tree in_decl)
-{
-  tree new_parms;
-  tree type;
-  tree defarg;
-
-  if (!parms || parms == void_list_node)
-    return parms;
-
-  new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms),
-                                           args, complain, in_decl);
-
-  /* Figure out the type of this parameter.  */
-  type = tsubst (TREE_VALUE (parms), args, complain, in_decl);
-
-  /* Figure out the default argument as well.  Note that we use
-     tsubst_expr since the default argument is really an expression.  */
-  defarg = tsubst_expr (TREE_PURPOSE (parms), args, complain, in_decl);
-
-  /* Chain this parameter on to the front of those we have already
-     processed.  We don't use hash_tree_cons because that function
-     doesn't check TREE_PARMLIST.  */
-  new_parms = tree_cons (defarg, type, new_parms);
-
-  return new_parms;
-}
-
 /* Take the tree structure T and replace template parameters used
    therein with the argument vector ARGS.  IN_DECL is an associated
    decl for diagnostics.  If an error occurs, returns ERROR_MARK_NODE.
@@ -6989,25 +7057,24 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        max = tsubst_template_arg (omax, args, complain, in_decl);
        max = fold_decl_constant_value (max);
 
-       if (integer_zerop (omax))
-         {
-           /* Still allow an explicit array of size zero.  */
-           if (pedantic)
-             pedwarn ("creating array with size zero");
-         }
-       else if (integer_zerop (max)
-                || (TREE_CODE (max) == INTEGER_CST
-                    && INT_CST_LT (max, integer_zero_node)))
-         {
-           /* [temp.deduct]
+       /* [temp.deduct]
 
-              Type deduction may fail for any of the following
-              reasons:
+          Type deduction may fail for any of the following
+          reasons:
+
+            Attempting to create an array with a size that is
+            zero or negative.  */
+       if (integer_zerop (max) && !(complain & tf_error))
+         /* We must fail if performing argument deduction (as
+            indicated by the state of complain), so that
+            another substitution can be found.  */
+         return error_mark_node;
 
-                Attempting to create an array with a size that is
-                zero or negative.  */
+       else if (TREE_CODE (max) == INTEGER_CST
+                && INT_CST_LT (max, integer_zero_node))
+         {
            if (complain & tf_error)
-             error ("creating array with size zero (%qE)", max);
+             error ("creating array with negative size (%qE)", max);
 
            return error_mark_node;
          }
@@ -7311,6 +7378,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        /* Substitute the exception specification.  */
        specs = tsubst_exception_specification (t, args, complain,
                                                in_decl);
+       if (specs == error_mark_node)
+         return error_mark_node;
        if (specs)
          fntype = build_exception_variant (fntype, specs);
        return fntype;
@@ -7473,7 +7542,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return build_nt (TREE_CODE (t), e1, e2);
+       return build_qualified_name (/*type=*/NULL_TREE,
+                                    e1, e2, QUALIFIED_NAME_IS_TEMPLATE (t));
       }
 
     case TYPEOF_TYPE:
@@ -7604,11 +7674,18 @@ tsubst_qualified_id (tree qualified_id, tree args,
     expr = name;
 
   if (dependent_type_p (scope))
-    return build_nt (SCOPE_REF, scope, expr);
+    return build_qualified_name (/*type=*/NULL_TREE, 
+                                scope, expr, 
+                                QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
 
   if (!BASELINK_P (name) && !DECL_P (expr))
     {
-      expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+      if (TREE_CODE (expr) == BIT_NOT_EXPR)
+       /* If this were actually a destructor call, it would have been
+          parsed as such by the parser.  */
+       expr = error_mark_node;
+      else
+       expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
       if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
                     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)
        {
@@ -7649,10 +7726,14 @@ tsubst_qualified_id (tree qualified_id, tree args,
     {
       expr = (adjust_result_of_qualified_name_lookup
              (expr, scope, current_class_type));
-      expr = finish_qualified_id_expr (scope, expr, done, address_p);
+      expr = (finish_qualified_id_expr 
+             (scope, expr, done, address_p,
+              QUALIFIED_NAME_IS_TEMPLATE (qualified_id),
+              /*template_arg_p=*/false));
     }
 
-  expr = convert_from_reference (expr);
+  if (TREE_CODE (expr) != SCOPE_REF)
+    expr = convert_from_reference (expr);
 
   return expr;
 }
@@ -7835,7 +7916,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            name = tsubst_copy (TREE_OPERAND (name, 0), args,
                                complain, in_decl);
            name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
-           name = build_nt (SCOPE_REF, base, name);
+           name = build_qualified_name (/*type=*/NULL_TREE,
+                                        base, name, 
+                                        /*template_p=*/false);
          }
        else if (TREE_CODE (name) == BASELINK)
          name = tsubst_baselink (name,
@@ -7877,7 +7960,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case LT_EXPR:
     case GT_EXPR:
     case COMPOUND_EXPR:
-    case SCOPE_REF:
     case DOTSTAR_EXPR:
     case MEMBER_REF:
     case PREDECREMENT_EXPR:
@@ -7888,6 +7970,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
         tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
 
+    case SCOPE_REF:
+      return build_qualified_name (/*type=*/NULL_TREE,
+                                  tsubst_copy (TREE_OPERAND (t, 0),
+                                               args, complain, in_decl),
+                                  tsubst_copy (TREE_OPERAND (t, 1),
+                                               args, complain, in_decl),
+                                  QUALIFIED_NAME_IS_TEMPLATE (t));
+
     case ARRAY_REF:
       return build_nt
        (ARRAY_REF,
@@ -8001,13 +8091,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        return t;
 
     case CONSTRUCTOR:
-      {
-       r = build_constructor
-         (tsubst (TREE_TYPE (t), args, complain, in_decl),
-          tsubst_copy (CONSTRUCTOR_ELTS (t), args, complain, in_decl));
-       TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
-       return r;
-      }
+      /* This is handled by tsubst_copy_and_build.  */
+      gcc_unreachable ();
 
     case VA_ARG_EXPR:
       return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
@@ -8020,11 +8105,89 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
         in response to the saved STMT_IS_FULL_EXPR_P setting.  */
       gcc_unreachable ();
 
+    case OFFSET_REF:
+      mark_used (TREE_OPERAND (t, 1));
+      return t;
+
     default:
       return t;
     }
 }
 
+/* Like tsubst_copy, but specifically for OpenMP clauses.  */
+
+static tree
+tsubst_omp_clauses (tree clauses, tree args, tsubst_flags_t complain,
+                   tree in_decl)
+{
+  tree new_clauses = NULL, nc, oc;
+
+  for (oc = clauses; oc ; oc = OMP_CLAUSE_CHAIN (oc))
+    {
+      nc = copy_node (oc);
+      OMP_CLAUSE_CHAIN (nc) = new_clauses;
+      new_clauses = nc;
+
+      switch (OMP_CLAUSE_CODE (nc))
+       {
+       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:
+         OMP_CLAUSE_OPERAND (nc, 0)
+           = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
+         break;
+       case OMP_CLAUSE_NOWAIT:
+       case OMP_CLAUSE_ORDERED:
+       case OMP_CLAUSE_DEFAULT:
+         break;
+       default:
+         gcc_unreachable ();
+       }
+    }
+
+  return finish_omp_clauses (nreverse (new_clauses));
+}
+
+/* Like tsubst_copy_and_build, but unshare TREE_LIST nodes.  */
+
+static tree
+tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
+                         tree in_decl)
+{
+#define RECUR(t) tsubst_copy_asm_operands (t, args, complain, in_decl)
+
+  tree purpose, value, chain;
+
+  if (t == NULL)
+    return t;
+
+  if (TREE_CODE (t) != TREE_LIST)
+    return tsubst_copy_and_build (t, args, complain, in_decl,
+                                 /*function_p=*/false);
+
+  if (t == void_list_node)
+    return t;
+
+  purpose = TREE_PURPOSE (t);
+  if (purpose)
+    purpose = RECUR (purpose);
+  value = TREE_VALUE (t);
+  if (value)
+    value = RECUR (value);
+  chain = TREE_CHAIN (t);
+  if (chain && chain != void_type_node)
+    chain = RECUR (chain);
+  return tree_cons (purpose, value, chain);
+#undef RECUR
+}
+
 /* Like tsubst_copy for expressions, etc. but also does semantic
    processing.  */
 
@@ -8103,8 +8266,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            decl = tsubst (decl, args, complain, in_decl);
            if (decl != error_mark_node)
              {
-               if (init)
-                 DECL_INITIAL (decl) = error_mark_node;
                /* By marking the declaration as instantiated, we avoid
                   trying to instantiate it.  Since instantiate_decl can't
                   handle local variables, and since we've already done
@@ -8130,7 +8291,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                      }
                    else
                      init = tsubst_expr (init, args, complain, in_decl);
-                   cp_finish_decl (decl, init, NULL_TREE, 0);
+                   finish_decl (decl, init, NULL_TREE);
                  }
              }
          }
@@ -8242,9 +8403,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       tmp = finish_asm_stmt
        (ASM_VOLATILE_P (t),
         tsubst_expr (ASM_STRING (t), args, complain, in_decl),
-        tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
-        tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
-        tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl));
+        tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
+        tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
+        tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl));
       {
        tree asm_expr = tmp;
        if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
@@ -8265,8 +8426,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        }
       else
        {
+         tree compound_stmt = NULL_TREE;
+
          if (FN_TRY_BLOCK_P (t))
-           stmt = begin_function_try_block ();
+           stmt = begin_function_try_block (&compound_stmt);
          else
            stmt = begin_try_block ();
 
@@ -8279,7 +8442,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
          tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
          if (FN_TRY_BLOCK_P (t))
-           finish_function_handler_sequence (stmt);
+           finish_function_handler_sequence (stmt, compound_stmt);
          else
            finish_handler_sequence (stmt);
        }
@@ -8311,6 +8474,85 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
       break;
 
+    case OMP_PARALLEL:
+      tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t),
+                               args, complain, in_decl);
+      stmt = begin_omp_parallel ();
+      tsubst_expr (OMP_PARALLEL_BODY (t), args, complain, in_decl);
+      OMP_PARALLEL_COMBINED (finish_omp_parallel (tmp, stmt))
+       = OMP_PARALLEL_COMBINED (t);
+      break;
+
+    case OMP_FOR:
+      {
+       tree clauses, decl, init, cond, incr, body, pre_body;
+
+       clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t),
+                                     args, complain, in_decl);
+       init = OMP_FOR_INIT (t);
+       gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+       decl = tsubst_expr (TREE_OPERAND (init, 0), args, complain, in_decl);
+       init = tsubst_expr (TREE_OPERAND (init, 1), args, complain, in_decl);
+       cond = tsubst_expr (OMP_FOR_COND (t), args, complain, in_decl);
+       incr = tsubst_expr (OMP_FOR_INCR (t), args, complain, in_decl);
+
+       stmt = begin_omp_structured_block ();
+
+       pre_body = push_stmt_list ();
+       tsubst_expr (OMP_FOR_PRE_BODY (t), args, complain, in_decl);
+       pre_body = pop_stmt_list (pre_body);
+
+       body = push_stmt_list ();
+       tsubst_expr (OMP_FOR_BODY (t), args, complain, in_decl);
+       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;
+
+       add_stmt (finish_omp_structured_block (stmt));
+      }
+      break;
+
+    case OMP_SECTIONS:
+    case OMP_SINGLE:
+      tmp = tsubst_omp_clauses (OMP_CLAUSES (t), args, complain, in_decl);
+      stmt = push_stmt_list ();
+      tsubst_expr (OMP_BODY (t), args, complain, in_decl);
+      stmt = pop_stmt_list (stmt);
+
+      t = copy_node (t);
+      OMP_BODY (t) = stmt;
+      OMP_CLAUSES (t) = tmp;
+      add_stmt (t);
+      break;
+
+    case OMP_SECTION:
+    case OMP_CRITICAL:
+    case OMP_MASTER:
+    case OMP_ORDERED:
+      stmt = push_stmt_list ();
+      tsubst_expr (OMP_BODY (t), args, complain, in_decl);
+      stmt = pop_stmt_list (stmt);
+
+      t = copy_node (t);
+      OMP_BODY (t) = stmt;
+      add_stmt (t);
+      break;
+
+    case OMP_ATOMIC:
+      {
+       tree op0, op1;
+       op0 = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl);
+       op1 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl);
+       if (OMP_ATOMIC_DEPENDENT_P (t))
+         c_finish_omp_atomic (OMP_ATOMIC_CODE (t), op0, op1);
+       else
+         add_stmt (build2 (OMP_ATOMIC, void_type_node, op0, op1));
+      }
+      break;
+
     default:
       gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
 
@@ -8366,7 +8608,6 @@ tsubst_copy_and_build (tree t,
       {
        tree decl;
        cp_id_kind idk;
-       tree qualifying_class;
        bool non_integral_constant_expression_p;
        const char *error_msg;
 
@@ -8377,7 +8618,7 @@ tsubst_copy_and_build (tree t,
          }
 
        /* Look up the name.  */
-       decl = lookup_name (t, 0);
+       decl = lookup_name (t);
 
        /* By convention, expressions use ERROR_MARK_NODE to indicate
           failure, not NULL_TREE.  */
@@ -8386,10 +8627,13 @@ tsubst_copy_and_build (tree t,
 
        decl = finish_id_expression (t, decl, NULL_TREE,
                                     &idk,
-                                    &qualifying_class,
                                     /*integral_constant_expression_p=*/false,
                                     /*allow_non_integral_constant_expression_p=*/false,
                                     &non_integral_constant_expression_p,
+                                    /*template_p=*/false,
+                                    /*done=*/true,
+                                    /*address_p=*/false,
+                                    /*template_arg_p=*/false,
                                     &error_msg);
        if (error_msg)
          error (error_msg);
@@ -8631,9 +8875,17 @@ tsubst_copy_and_build (tree t,
          }
        else
          {
-           qualified_p = (TREE_CODE (function) == COMPONENT_REF
-                          && (TREE_CODE (TREE_OPERAND (function, 1))
-                              == SCOPE_REF));
+           if (TREE_CODE (function) == COMPONENT_REF)
+             {
+               tree op = TREE_OPERAND (function, 1);
+
+               qualified_p = (TREE_CODE (op) == SCOPE_REF
+                              || (BASELINK_P (op)
+                                  && BASELINK_QUALIFIED_P (op)));
+             }
+           else
+             qualified_p = false;
+           
            function = tsubst_copy_and_build (function, args, complain,
                                              in_decl,
                                              !qualified_p);
@@ -8678,7 +8930,8 @@ tsubst_copy_and_build (tree t,
                      (TREE_OPERAND (function, 0),
                       TREE_OPERAND (function, 1),
                       call_args, NULL_TREE,
-                      qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL));
+                      qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
+                      /*fn_p=*/NULL));
          }
        return finish_call_expr (function, call_args,
                                 /*disallow_virtual=*/qualified_p,
@@ -8723,6 +8976,7 @@ tsubst_copy_and_build (tree t,
     case COMPONENT_REF:
       {
        tree object;
+       tree object_type;
        tree member;
 
        object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
@@ -8730,6 +8984,7 @@ tsubst_copy_and_build (tree t,
        /* Remember that there was a reference to this entity.  */
        if (DECL_P (object))
          mark_used (object);
+       object_type = TREE_TYPE (object);
 
        member = TREE_OPERAND (t, 1);
        if (BASELINK_P (member))
@@ -8738,20 +8993,20 @@ tsubst_copy_and_build (tree t,
                                    args, complain, in_decl);
        else
          member = tsubst_copy (member, args, complain, in_decl);
-
        if (member == error_mark_node)
          return error_mark_node;
-       else if (!CLASS_TYPE_P (TREE_TYPE (object)))
+
+       if (object_type && !CLASS_TYPE_P (object_type))
          {
            if (TREE_CODE (member) == BIT_NOT_EXPR)
              return finish_pseudo_destructor_expr (object,
                                                    NULL_TREE,
-                                                   TREE_TYPE (object));
+                                                   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,
-                                                   TREE_TYPE (object));
+                                                   object_type);
          }
        else if (TREE_CODE (member) == SCOPE_REF
                 && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
@@ -8773,12 +9028,11 @@ tsubst_copy_and_build (tree t,
                              args);
                member = (adjust_result_of_qualified_name_lookup
                          (member, BINFO_TYPE (BASELINK_BINFO (member)),
-                          TREE_TYPE (object)));
+                          object_type));
              }
            else
              {
-               qualified_name_lookup_error (TREE_TYPE (object), tmpl,
-                                            member);
+               qualified_name_lookup_error (object_type, tmpl, member);
                return error_mark_node;
              }
          }
@@ -8800,7 +9054,8 @@ tsubst_copy_and_build (tree t,
        else if (TREE_CODE (member) == FIELD_DECL)
          return finish_non_static_data_member (member, object, NULL_TREE);
 
-       return finish_class_member_access_expr (object, member);
+       return finish_class_member_access_expr (object, member,
+                                               /*template_p=*/false);
       }
 
     case THROW_EXPR:
@@ -8809,38 +9064,35 @@ tsubst_copy_and_build (tree t,
 
     case CONSTRUCTOR:
       {
+       VEC(constructor_elt,gc) *n;
+       constructor_elt *ce;
+       unsigned HOST_WIDE_INT idx;
        tree r;
-       tree elts;
        tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-       bool purpose_p;
+       bool process_index_p;
 
        /* digest_init will do the wrong thing if we let it.  */
        if (type && TYPE_PTRMEMFUNC_P (type))
          return t;
 
-       r = NULL_TREE;
-       /* We do not want to process the purpose of aggregate
+       /* We do not want to process the index of aggregate
           initializers as they are identifier nodes which will be
           looked up by digest_init.  */
-       purpose_p = !(type && IS_AGGR_TYPE (type));
-       for (elts = CONSTRUCTOR_ELTS (t);
-            elts;
-            elts = TREE_CHAIN (elts))
-         {
-           tree purpose = TREE_PURPOSE (elts);
-           tree value = TREE_VALUE (elts);
+       process_index_p = !(type && IS_AGGR_TYPE (type));
 
-           if (purpose && purpose_p)
-             purpose = RECUR (purpose);
-           value = RECUR (value);
-           r = tree_cons (purpose, value, r);
+       n = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t));
+       for (idx = 0; VEC_iterate (constructor_elt, n, idx, ce); idx++)
+         {
+           if (ce->index && process_index_p)
+             ce->index = RECUR (ce->index);
+           ce->value = RECUR (ce->value);
          }
 
-       r = build_constructor (NULL_TREE, nreverse (r));
+       r = build_constructor (NULL_TREE, n);
        TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
 
        if (type)
-         return digest_init (type, r, 0);
+         return digest_init (type, r);
        return r;
       }
 
@@ -8922,7 +9174,6 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
 {
   int ix, len = DECL_NTPARMS (tmpl);
   bool result = false;
-  bool error_p = complain & tf_error;
 
   for (ix = 0; ix != len; ix++)
     {
@@ -8939,12 +9190,17 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
 
          if (nt)
            {
-             if (TYPE_ANONYMOUS_P (nt))
-               error ("%qT is/uses anonymous type", t);
-             else
-               error ("%qT uses local type %qT", t, nt);
+             /* DR 488 makes use of a type with no linkage cause
+                type deduction to fail.  */ 
+             if (complain & tf_error)
+               {
+                 if (TYPE_ANONYMOUS_P (nt))
+                   error ("%qT is/uses anonymous type", t);
+                 else
+                   error ("template argument for %qD uses local type %qT",
+                           tmpl, t);
+               }
              result = true;
-             error_p = true;
            }
          /* In order to avoid all sorts of complications, we do not
             allow variably-modified types as template arguments.  */
@@ -8966,7 +9222,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
          result = true;
        }
     }
-  if (result && error_p)
+  if (result && (complain & tf_error))
     error ("  trying to instantiate %qD", tmpl);
   return result;
 }
@@ -9042,6 +9298,8 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
   /* Substitute template parameters.  */
   fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
                   targ_ptr, complain, gen_tmpl);
+  if (fndecl == error_mark_node)
+    return error_mark_node;
 
   /* Now we know the specialization, compute access previously
      deferred.  */
@@ -9100,7 +9358,8 @@ fn_type_unification (tree fn,
                     tree targs,
                     tree args,
                     tree return_type,
-                    unification_kind_t strict)
+                    unification_kind_t strict,
+                    int flags)
 {
   tree parms;
   tree fntype;
@@ -9138,7 +9397,8 @@ fn_type_unification (tree fn,
       converted_args
        = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
                                  explicit_targs, NULL_TREE, tf_none,
-                                 /*require_all_arguments=*/0));
+                                 /*require_all_args=*/false,
+                                 /*use_default_args=*/false));
       if (converted_args == error_mark_node)
        return 1;
 
@@ -9168,7 +9428,6 @@ fn_type_unification (tree fn,
 
   if (return_type)
     {
-      /* We've been given a return type to match, prepend it.  */
       parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
       args = tree_cons (NULL_TREE, return_type, args);
     }
@@ -9179,7 +9438,7 @@ fn_type_unification (tree fn,
      event.  */
   result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
                                  targs, parms, args, /*subr=*/0,
-                                 strict, /*allow_incomplete*/1);
+                                 strict, flags);
 
   if (result == 0)
     /* All is well so far.  Now, check:
@@ -9287,7 +9546,7 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
 
    If SUBR is 1, we're being called recursively (to unify the
    arguments of a function or method parameter of a function
-   template).  */
+   template). */
 
 static int
 type_unification_real (tree tparms,
@@ -9296,7 +9555,7 @@ type_unification_real (tree tparms,
                       tree xargs,
                       int subr,
                       unification_kind_t strict,
-                      int allow_incomplete)
+                      int flags)
 {
   tree parm, arg;
   int i;
@@ -9364,7 +9623,8 @@ type_unification_real (tree tparms,
          if (same_type_p (parm, type))
            continue;
          if (strict != DEDUCE_EXACT
-             && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg))
+             && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg, 
+                                 flags))
            continue;
          
          return 1;
@@ -9427,8 +9687,6 @@ type_unification_real (tree tparms,
              && !saw_undeduced++)
            goto again;
 
-         if (!allow_incomplete)
-           error ("incomplete type unification");
          return 2;
        }
 
@@ -9609,34 +9867,6 @@ try_one_overload (tree tparms,
   return 1;
 }
 
-/* Verify that nondeduce template argument agrees with the type
-   obtained from argument deduction.  Return nonzero if the
-   verification fails.
-
-   For example:
-
-     struct A { typedef int X; };
-     template <class T, class U> struct C {};
-     template <class T> struct C<T, typename T::X> {};
-
-   Then with the instantiation `C<A, int>', we can deduce that
-   `T' is `A' but unify () does not check whether `typename T::X'
-   is `int'.  This function ensure that they agree.
-
-   TARGS, PARMS are the same as the arguments of unify.
-   ARGS contains template arguments from all levels.  */
-
-static int
-verify_class_unification (tree targs, tree parms, tree args)
-{
-  parms = tsubst (parms, add_outermost_template_args (args, targs),
-                 tf_none, NULL_TREE);
-  if (parms == error_mark_node)
-    return 1;
-
-  return !comp_template_args (parms, INNERMOST_TEMPLATE_ARGS (args));
-}
-
 /* PARM is a template class (perhaps with unbound template
    parameters).  ARG is a fully instantiated type.  If ARG can be
    bound to PARM, return ARG, otherwise return NULL_TREE.  TPARMS and
@@ -9799,9 +10029,18 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
   return 1;
 }
 
-/* Takes parameters as for type_unification.  Returns 0 if the
-   type deduction succeeds, 1 otherwise.  The parameter STRICT is a
-   bitwise or of the following flags:
+/* Deduce the value of template parameters.  TPARMS is the (innermost)
+   set of template parameters to a template.  TARGS is the bindings
+   for those template parameters, as determined thus far; TARGS may
+   include template arguments for outer levels of template parameters
+   as well.  PARM is a parameter to a template function, or a
+   subcomponent of that parameter; ARG is the corresponding argument.
+   This function attempts to match PARM with ARG in a manner
+   consistent with the existing assignments in TARGS.  If more values
+   are deduced, then TARGS is updated.
+
+   Returns 0 if the type deduction succeeds, 1 otherwise.  The
+   parameter STRICT is a bitwise or of the following flags:
 
      UNIFY_ALLOW_NONE:
        Require an exact match between PARM and ARG.
@@ -9906,7 +10145,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
        return (TREE_CODE (arg) == TREE_CODE (parm)
                && same_type_p (parm, arg)) ? 0 : 1;
       idx = TEMPLATE_TYPE_IDX (parm);
-      targ = TREE_VEC_ELT (targs, idx);
+      targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
       tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
 
       /* Check for mixed types and values.  */
@@ -9925,21 +10164,44 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            return 1;
 
          {
-           tree parmtmpl = TYPE_TI_TEMPLATE (parm);
            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;
 
-           /* The parameter and argument roles have to be switched here
-              in order to handle default arguments properly.  For example,
-              template<template <class> class TT> void f(TT<int>)
-              should be able to accept vector<int> which comes from
-              template <class T, class Allocator = allocator>
-              class vector.  */
+           /* The resolution to DR150 makes clear that default
+              arguments for an N-argument may not be used to bind T
+              to a template template parameter with fewer than N
+              parameters.  It is not safe to permit the binding of
+              default arguments as an extension, as that may change
+              the meaning of a conforming program.  Consider:
+
+                 struct Dense { static const unsigned int dim = 1; };
+
+                 template <template <typename> class View,
+                           typename Block>
+                 void operator+(float, View<Block> const&);
 
-           if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
+                 template <typename Block, 
+                           unsigned int Dim = Block::dim>
+                 struct Lvalue_proxy { operator float() const; };
+
+                 void
+                 test_1d (void) {
+                   Lvalue_proxy<Dense> p;
+                   float b;
+                   b + p;
+                 }
+
+             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, 
+                                      TYPE_TI_TEMPLATE (parm),
+                                      tf_none,
+                                      /*require_all_args=*/true,
+                                      /*use_default_args=*/false)
                == error_mark_node)
              return 1;
 
@@ -10007,7 +10269,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            return 1;
        }
 
-      TREE_VEC_ELT (targs, idx) = arg;
+      TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return 0;
 
     case TEMPLATE_PARM_INDEX:
@@ -10021,7 +10283,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
                 && cp_tree_equal (parm, arg));
 
       idx = TEMPLATE_PARM_IDX (parm);
-      targ = TREE_VEC_ELT (targs, idx);
+      targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
 
       if (targ)
        return !cp_tree_equal (targ, arg);
@@ -10055,7 +10317,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       else
        return 1;
 
-      TREE_VEC_ELT (targs, idx) = arg;
+      TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return 0;
 
     case PTRMEM_CST:
@@ -10250,12 +10512,23 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       if (TREE_CODE (arg) != TREE_CODE (parm))
        return 1;
 
+      /* 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.  */
+      if (TREE_CODE (parm) == METHOD_TYPE
+         && (!check_cv_quals_for_unify
+             (UNIFY_ALLOW_NONE,
+              TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
+              TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
+       return 1;
+
       if (unify (tparms, targs, TREE_TYPE (parm),
                 TREE_TYPE (arg), UNIFY_ALLOW_NONE))
        return 1;
       return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
-                                   TYPE_ARG_TYPES (arg), 1,
-                                   DEDUCE_EXACT, 0);
+                                   TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
+                                   LOOKUP_NORMAL);
 
     case OFFSET_TYPE:
       /* Unify a pointer to member with a pointer to member function, which
@@ -10433,17 +10706,30 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2));
   int better1 = 0;
   int better2 = 0;
-
-  /* If only one is a member function, they are unordered.  */
-  if (DECL_FUNCTION_MEMBER_P (decl1) != DECL_FUNCTION_MEMBER_P (decl2))
-    return 0;
-
-  /* Don't consider 'this' parameter.  */
+  
+  /* Remove the this parameter from non-static member functions.  If
+     one is a non-static member function and the other is not a static
+     member function, remove the first parameter from that function
+     also.  This situation occurs for operator functions where we
+     locate both a member function (with this pointer) and non-member
+     operator (with explicit first operand).  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1))
-    args1 = TREE_CHAIN (args1);
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2))
-    args2 = TREE_CHAIN (args2);
-
+    {
+      len--; /* LEN is the number of significant arguments for DECL1 */
+      args1 = TREE_CHAIN (args1);
+      if (!DECL_STATIC_FUNCTION_P (decl2))
+       args2 = TREE_CHAIN (args2);
+    }
+  else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2))
+    {
+      args2 = TREE_CHAIN (args2);
+      if (!DECL_STATIC_FUNCTION_P (decl1))
+       {
+         len--;
+         args1 = TREE_CHAIN (args1);
+       }
+    }
+    
   /* If only one is a conversion operator, they are unordered.  */
   if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2))
     return 0;
@@ -10556,33 +10842,44 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   return (better1 > 0) - (better2 > 0);
 }
 
-/* Given two class template specialization list nodes PAT1 and PAT2, return:
+/* Determine which of two partial specializations is more specialized.
 
-   1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-   -1 if PAT2 is more specialized than PAT1.
-   0 if neither is more specialized.
+   PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding
+   to the first partial specialization.  The TREE_VALUE is the
+   innermost set of template parameters for the partial
+   specialization.  PAT2 is similar, but for the second template.
 
-   FULL_ARGS is the full set of template arguments that triggers this
-   partial ordering.  */
+   Return 1 if the first partial specialization is more specialized;
+   -1 if the second is more specialized; 0 if neither is more
+   specialized.
 
-int
-more_specialized_class (tree pat1, tree pat2, tree full_args)
+   See [temp.class.order] for information about determining which of
+   two templates is more specialized.  */ 
+
+static int
+more_specialized_class (tree pat1, tree pat2)
 {
   tree targs;
+  tree tmpl1, tmpl2;
   int winner = 0;
 
+  tmpl1 = TREE_TYPE (pat1);
+  tmpl2 = TREE_TYPE (pat2);
+
   /* Just like what happens for functions, if we are ordering between
      different class template specializations, we may encounter dependent
      types in the arguments, and we need our dependency check functions
      to behave correctly.  */
   ++processing_template_decl;
-  targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
-                             add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
+  targs = get_class_bindings (TREE_VALUE (pat1), 
+                             CLASSTYPE_TI_ARGS (tmpl1),
+                             CLASSTYPE_TI_ARGS (tmpl2));
   if (targs)
     --winner;
 
-  targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
-                             add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
+  targs = get_class_bindings (TREE_VALUE (pat2), 
+                             CLASSTYPE_TI_ARGS (tmpl2),
+                             CLASSTYPE_TI_ARGS (tmpl1));
   if (targs)
     ++winner;
   --processing_template_decl;
@@ -10620,9 +10917,11 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
        return NULL_TREE;
 
       converted_args
-       = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
-                                 explicit_args, NULL_TREE,
-                                 tf_none, /*require_all_arguments=*/0));
+       = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
+                                explicit_args, NULL_TREE,
+                                tf_none, 
+                                /*require_all_args=*/false,
+                                /*use_default_args=*/false);
       if (converted_args == error_mark_node)
        return NULL_TREE;
 
@@ -10640,7 +10939,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
                           decl_arg_types,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT))
+                          DEDUCE_EXACT, LOOKUP_NORMAL))
     return NULL_TREE;
 
   return targs;
@@ -10657,49 +10956,81 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
      template <class T> struct S<T*, int> {};
 
    Then, suppose we want to get `S<double*, int>'.  The TPARMS will be
-   {T}, the PARMS will be {T*, int} and the ARGS will be {double*,
+   {T}, the SPEC_ARGS will be {T*, int} and the ARGS will be {double*,
    int}.  The resulting vector will be {double}, indicating that `T'
    is bound to `double'.  */
 
 static tree
-get_class_bindings (tree tparms, tree parms, tree args)
+get_class_bindings (tree tparms, tree spec_args, tree args)
 {
   int i, ntparms = TREE_VEC_LENGTH (tparms);
-  tree vec = make_tree_vec (ntparms);
+  tree deduced_args;
+  tree innermost_deduced_args;
+
+  innermost_deduced_args = make_tree_vec (ntparms);
+  if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+    {
+      deduced_args = copy_node (args);
+      SET_TMPL_ARGS_LEVEL (deduced_args,
+                          TMPL_ARGS_DEPTH (deduced_args),
+                          innermost_deduced_args);
+    }
+  else
+    deduced_args = innermost_deduced_args; 
 
-  if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args),
+  if (unify (tparms, deduced_args, 
+            INNERMOST_TEMPLATE_ARGS (spec_args), 
+            INNERMOST_TEMPLATE_ARGS (args), 
             UNIFY_ALLOW_NONE))
     return NULL_TREE;
 
   for (i =  0; i < ntparms; ++i)
-    if (! TREE_VEC_ELT (vec, i))
+    if (! TREE_VEC_ELT (innermost_deduced_args, i))
       return NULL_TREE;
 
-  if (verify_class_unification (vec, parms, args))
+  /* Verify that nondeduced template arguments agree with the type
+     obtained from argument deduction.
+     
+     For example:
+
+       struct A { typedef int X; };
+       template <class T, class U> struct C {};
+       template <class T> struct C<T, typename T::X> {};
+
+     Then with the instantiation `C<A, int>', we can deduce that
+     `T' is `A' but unify () does not check whether `typename T::X'
+     is `int'.  */
+  spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
+  if (spec_args == error_mark_node
+      /* We only need to check the innermost arguments; the other
+        arguments will always agree.  */
+      || !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args),
+                             INNERMOST_TEMPLATE_ARGS (args)))
     return NULL_TREE;
 
-  return vec;
+  return deduced_args;
 }
 
-/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
-   Pick the most specialized template, and return the corresponding
-   instantiation, or if there is no corresponding instantiation, the
-   template itself.  If there is no most specialized template,
-   error_mark_node is returned.  If there are no templates at all,
-   NULL_TREE is returned.  */
+/* TEMPLATES is a TREE_LIST.  Each TREE_VALUE is a TEMPLATE_DECL.
+   Return the TREE_LIST node with the most specialized template, if
+   any.  If there is no most specialized template, the error_mark_node
+   is returned.
+
+   Note that this function does not look at, or modify, the
+   TREE_PURPOSE or TREE_TYPE of any of the nodes.  Since the node
+   returned is one of the elements of INSTANTIATIONS, callers may
+   store information in the TREE_PURPOSE or TREE_TYPE of the nodes,
+   and retrieve it from the value returned.  */
 
 tree
-most_specialized_instantiation (tree instantiations)
+most_specialized_instantiation (tree templates)
 {
   tree fn, champ;
 
-  if (!instantiations)
-    return NULL_TREE;
-
   ++processing_template_decl;
 
-  champ = instantiations;
-  for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
+  champ = templates;
+  for (fn = TREE_CHAIN (templates); fn; fn = TREE_CHAIN (fn))
     {
       int fate = 0;
 
@@ -10713,20 +11044,23 @@ most_specialized_instantiation (tree instantiations)
                        NULL_TREE, /*check_ret=*/false))
        fate++;
 
-      if (fate != 1)
+      if (fate == -1)
+       champ = fn;
+      else if (!fate)
        {
-         if (!fate)
-           /* Equally specialized, move to next function.  If there
-              is no next function, nothing's most specialized.  */
-           fn = TREE_CHAIN (fn);
+         /* Equally specialized, move to next function.  If there
+            is no next function, nothing's most specialized.  */
+         fn = TREE_CHAIN (fn);
          champ = fn;
+         if (!fn)
+           break;
        }
     }
 
   if (champ)
     /* Now verify that champ is better than everything earlier in the
        instantiation list.  */
-    for (fn = instantiations; fn != champ; fn = TREE_CHAIN (fn))
+    for (fn = templates; fn != champ; fn = TREE_CHAIN (fn))
       if (get_bindings (TREE_VALUE (champ),
                        DECL_TEMPLATE_RESULT (TREE_VALUE (fn)),
                        NULL_TREE, /*check_ret=*/false)
@@ -10743,29 +11077,7 @@ most_specialized_instantiation (tree instantiations)
   if (!champ)
     return error_mark_node;
 
-  return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ);
-}
-
-/* Return the most specialized of the list of templates in FNS that can
-   produce an instantiation matching DECL, given the explicit template
-   arguments EXPLICIT_ARGS.  */
-
-static tree
-most_specialized (tree fns, tree decl, tree explicit_args)
-{
-  tree candidates = NULL_TREE;
-  tree fn, args;
-
-  for (fn = fns; fn; fn = TREE_CHAIN (fn))
-    {
-      tree candidate = TREE_VALUE (fn);
-
-      args = get_bindings (candidate, decl, explicit_args, /*check_ret=*/true);
-      if (args)
-       candidates = tree_cons (NULL_TREE, candidate, candidates);
-    }
-
-  return most_specialized_instantiation (candidates);
+  return champ;
 }
 
 /* If DECL is a specialization of some template, return the most
@@ -10826,26 +11138,42 @@ most_general_template (tree decl)
   return decl;
 }
 
-/* Return the most specialized of the class template specializations
-   of TMPL which can produce an instantiation matching ARGS, or
-   error_mark_node if the choice is ambiguous.  */
+/* Return the most specialized of the class template partial
+   specializations of TMPL which can produce TYPE, a specialization of
+   TMPL.  The value returned is actually a TREE_LIST; the TREE_TYPE is
+   a _TYPE node corresponding to the partial specialization, while the
+   TREE_PURPOSE is the set of template arguments that must be
+   substituted into the TREE_TYPE in order to generate TYPE.
+
+   If the choice of partial specialization is ambiguous, a diagnostic
+   is issued, and the error_mark_node is returned.  If there are no
+   partial specializations of TMPL matching TYPE, then NULL_TREE is
+   returned.  */
 
 static tree
-most_specialized_class (tree tmpl, tree args)
+most_specialized_class (tree type, tree tmpl)
 {
   tree list = NULL_TREE;
   tree t;
   tree champ;
   int fate;
+  bool ambiguous_p;
+  tree args;
 
   tmpl = most_general_template (tmpl);
+  args = CLASSTYPE_TI_ARGS (type);
   for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t))
     {
-      tree spec_args
-       = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args);
+      tree partial_spec_args;
+      tree spec_args;
+
+      partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
+      spec_args = get_class_bindings (TREE_VALUE (t), 
+                                     partial_spec_args, 
+                                     args);
       if (spec_args)
        {
-         list = tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list);
+         list = tree_cons (spec_args, TREE_VALUE (t), list);
          TREE_TYPE (list) = TREE_TYPE (t);
        }
     }
@@ -10853,12 +11181,13 @@ most_specialized_class (tree tmpl, tree args)
   if (! list)
     return NULL_TREE;
 
+  ambiguous_p = false;
   t = list;
   champ = t;
   t = TREE_CHAIN (t);
   for (; t; t = TREE_CHAIN (t))
     {
-      fate = more_specialized_class (champ, t, args);
+      fate = more_specialized_class (champ, t);
       if (fate == 1)
        ;
       else
@@ -10867,17 +11196,36 @@ most_specialized_class (tree tmpl, tree args)
            {
              t = TREE_CHAIN (t);
              if (! t)
-               return error_mark_node;
+               {
+                 ambiguous_p = true;
+                 break;
+               }
            }
          champ = t;
        }
     }
 
-  for (t = list; t && t != champ; t = TREE_CHAIN (t))
+  if (!ambiguous_p)
+    for (t = list; t && t != champ; t = TREE_CHAIN (t))
+      {
+       fate = more_specialized_class (champ, t);
+       if (fate != 1)
+         {
+           ambiguous_p = true;
+           break;
+         }
+      }
+
+  if (ambiguous_p)
     {
-      fate = more_specialized_class (champ, t, args);
-      if (fate != 1)
-       return error_mark_node;
+      const char *str = "candidates are:";
+      error ("ambiguous class template instantiation for %q#T", type);
+      for (t = list; t; t = TREE_CHAIN (t))
+       {
+         error ("%s %+#T", str, TREE_TYPE (t));
+         str = "               ";
+       }
+      return error_mark_node;
     }
 
   return champ;
@@ -10891,7 +11239,7 @@ do_decl_instantiation (tree decl, tree storage)
   tree result = NULL_TREE;
   int extern_p = 0;
 
-  if (!decl)
+  if (!decl || decl == error_mark_node)
     /* An error occurred, for which grokdeclarator has already issued
        an appropriate message.  */
     return;
@@ -10983,13 +11331,15 @@ do_decl_instantiation (tree decl, tree storage)
     }
   else
     error ("storage class %qD applied to template instantiation", storage);
-
+  
+  check_explicit_instantiation_namespace (result);
   mark_decl_instantiated (result, extern_p);
   if (! extern_p)
-    instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0);
+    instantiate_decl (result, /*defer_ok=*/1, 
+                     /*expl_inst_class_mem_p=*/false);
 }
 
-void
+static void
 mark_class_instantiated (tree t, int extern_p)
 {
   SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
@@ -11023,7 +11373,8 @@ instantiate_class_member (tree decl, int extern_p)
 {
   mark_decl_instantiated (decl, extern_p);
   if (! extern_p)
-    instantiate_decl (decl, /*defer_ok=*/1, /* undefined_ok=*/1);
+    instantiate_decl (decl, /*defer_ok=*/1, 
+                     /*expl_inst_class_mem_p=*/true);
 }
 
 /* Perform an explicit instantiation of template class T.  STORAGE, if
@@ -11113,6 +11464,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
        return;
     }
 
+  check_explicit_instantiation_namespace (TYPE_NAME (t));
   mark_class_instantiated (t, extern_p);
 
   if (nomem_p)
@@ -11244,13 +11596,9 @@ regenerate_decl_from_template (tree decl, tree tmpl)
        DECL_INLINE (decl) = 1;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
-    {
-      if (!DECL_INITIALIZED_IN_CLASS_P (decl)
-         && DECL_INITIAL (code_pattern))
-       DECL_INITIAL (decl) =
-         tsubst_expr (DECL_INITIAL (code_pattern), args,
-                      tf_error, DECL_TI_TEMPLATE (decl));
-    }
+    DECL_INITIAL (decl) =
+      tsubst_expr (DECL_INITIAL (code_pattern), args,
+                  tf_error, DECL_TI_TEMPLATE (decl));
   else
     gcc_unreachable ();
 
@@ -11319,14 +11667,12 @@ template_for_substitution (tree decl)
    DEFER_OK is nonzero, then we don't have to actually do the
    instantiation now; we just have to do it sometime.  Normally it is
    an error if this is an explicit instantiation but D is undefined.
-   If UNDEFINED_OK is nonzero, then instead we treat it as an implicit
-   instantiation.  UNDEFINED_OK is nonzero only if we are being used
-   to instantiate the members of an explicitly instantiated class
-   template.  */
-
+   EXPL_INST_CLASS_MEM_P is true iff D is a member of an
+   explicitly instantiated class template.  */
 
 tree
-instantiate_decl (tree d, int defer_ok, int undefined_ok)
+instantiate_decl (tree d, int defer_ok, 
+                 bool expl_inst_class_mem_p)
 {
   tree tmpl = DECL_TI_TEMPLATE (d);
   tree gen_args;
@@ -11335,9 +11681,10 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
   tree code_pattern;
   tree spec;
   tree gen_tmpl;
-  int pattern_defined;
+  bool pattern_defined;
   int need_push;
   location_t saved_loc = input_location;
+  bool external_p;
 
   /* This function should only be used to instantiate templates for
      functions and static member variables.  */
@@ -11383,14 +11730,15 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
   timevar_push (TV_PARSE);
 
-  /* We may be in the middle of deferred access check.  Disable it now.  */
-  push_deferring_access_checks (dk_no_deferred);
-
   /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
      for the instantiation.  */
   td = template_for_substitution (d);
   code_pattern = DECL_TEMPLATE_RESULT (td);
 
+  /* We should never be trying to instantiate a member of a class
+     template or partial specialization.  */ 
+  gcc_assert (d != code_pattern);
   if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
       || DECL_TEMPLATE_SPECIALIZATION (td))
     /* In the case of a friend template whose definition is provided
@@ -11405,6 +11753,10 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
     pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE);
   else
     pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
+
+  /* We may be in the middle of deferred access check.  Disable it now.  */
+  push_deferring_access_checks (dk_no_deferred);
+
   /* Unless an explicit instantiation directive has already determined
      the linkage of D, remember that a definition is available for
      this entity.  */
@@ -11415,9 +11767,14 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
   input_location = DECL_SOURCE_LOCATION (d);
 
-  if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
+  /* If D is a member of an explicitly instantiated class template,
+     and no definition is available, treat it like an implicit
+     instantiation.  */ 
+  if (!pattern_defined && expl_inst_class_mem_p 
+      && DECL_EXPLICIT_INSTANTIATION (d)) 
     {
       DECL_NOT_REALLY_EXTERN (d) = 0;
+      DECL_INTERFACE_KNOWN (d) = 0;
       SET_DECL_IMPLICIT_INSTANTIATION (d);
     }
 
@@ -11435,38 +11792,71 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
       if (TREE_CODE (gen) == FUNCTION_DECL)
        {
-         tsubst (DECL_ARGUMENTS (gen), gen_args, tf_error | tf_warning, d);
+         tsubst (DECL_ARGUMENTS (gen), gen_args, tf_warning_or_error, d);
          tsubst (TYPE_RAISES_EXCEPTIONS (type), gen_args,
-                 tf_error | tf_warning, d);
+                 tf_warning_or_error, d);
          /* Don't simply tsubst the function type, as that will give
             duplicate warnings about poor parameter qualifications.
             The function arguments are the same as the decl_arguments
             without the top level cv qualifiers.  */
          type = TREE_TYPE (type);
        }
-      tsubst (type, gen_args, tf_error | tf_warning, d);
+      tsubst (type, gen_args, tf_warning_or_error, d);
 
       pop_access_scope (d);
     }
 
-  /* We should have set up DECL_INITIAL in instantiate_class_template
-     for in-class definitions of static data members.  */
-  gcc_assert (!(TREE_CODE (d) == VAR_DECL
-               && DECL_INITIALIZED_IN_CLASS_P (d)
-               && DECL_INITIAL (d) == NULL_TREE));
-
-  /* Do not instantiate templates that we know will be defined
-     elsewhere.  */
-  if (DECL_INTERFACE_KNOWN (d)
-      && DECL_REALLY_EXTERN (d)
-      && ! (TREE_CODE (d) == FUNCTION_DECL
-           && DECL_INLINE (d)))
+  /* Check to see whether we know that this template will be
+     instantiated in some other file, as with "extern template"
+     extension.  */
+  external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
+  /* In general, we do not instantiate such templates...  */
+  if (external_p
+      /* ... but we instantiate inline functions so that we can inline
+        them and ... */
+      && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+      /* ... we instantiate static data members whose values are
+        needed in integral constant expressions.  */
+      && ! (TREE_CODE (d) == VAR_DECL 
+           && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d)))
     goto out;
   /* Defer all other templates, unless we have been explicitly
-     forbidden from doing so.  We restore the source position here
-     because it's used by add_pending_template.  */
-  else if (! pattern_defined || defer_ok)
-    {
+     forbidden from doing so.  */
+  if (/* If there is no definition, we cannot instantiate the
+        template.  */
+      ! pattern_defined 
+      /* If it's OK to postpone instantiation, do so.  */
+      || defer_ok
+      /* If this is a static data member that will be defined
+        elsewhere, we don't want to instantiate the entire data
+        member, but we do want to instantiate the initializer so that
+        we can substitute that elsewhere.  */
+      || (external_p && TREE_CODE (d) == VAR_DECL))
+    {
+      /* The definition of the static data member is now required so
+        we must substitute the initializer.  */
+      if (TREE_CODE (d) == VAR_DECL
+         && !DECL_INITIAL (d) 
+         && DECL_INITIAL (code_pattern))
+       {
+         tree ns;
+         tree init;
+
+         ns = decl_namespace_context (d);
+         push_nested_namespace (ns);
+         push_nested_class (DECL_CONTEXT (d));
+         init = tsubst_expr (DECL_INITIAL (code_pattern), 
+                             args,
+                             tf_warning_or_error, NULL_TREE);
+         cp_finish_decl (d, init, /*init_const_expr_p=*/false,
+                         /*asmspec_tree=*/NULL_TREE,
+                         LOOKUP_ONLYCONVERTING);
+         pop_nested_class ();
+         pop_nested_namespace (ns);
+       }
+
+      /* We restore the source position here because it's used by
+        add_pending_template.  */
       input_location = saved_loc;
 
       if (at_eof && !pattern_defined
@@ -11481,7 +11871,10 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
        pedwarn
          ("explicit instantiation of %qD but no definition available", d);
 
-      add_pending_template (d);
+      /* ??? Historically, we have instantiated inline functions, even
+        when marked as "extern template".  */
+      if (!(external_p && TREE_CODE (d) == VAR_DECL))
+       add_pending_template (d);
       goto out;
     }
   /* Tell the repository that D is available in this translation unit
@@ -11521,11 +11914,20 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
   if (TREE_CODE (d) == VAR_DECL)
     {
+      tree init;
+
       /* Clear out DECL_RTL; whatever was there before may not be right
         since we've reset the type of the declaration.  */
       SET_DECL_RTL (d, NULL_RTX);
       DECL_IN_AGGR_P (d) = 0;
 
+      /* The initializer is placed in DECL_INITIAL by
+        regenerate_decl_from_template.  Pull it out so that
+        finish_decl can process it.  */
+      init = DECL_INITIAL (d);
+      DECL_INITIAL (d) = NULL_TREE;
+      DECL_INITIALIZED_P (d) = 0;
+
       /* Clear DECL_EXTERNAL so that cp_finish_decl will process the
         initializer.  That function will defer actual emission until
         we have a chance to determine linkage.  */
@@ -11533,10 +11935,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
       /* Enter the scope of D so that access-checking works correctly.  */
       push_nested_class (DECL_CONTEXT (d));
-      cp_finish_decl (d,
-                     (!DECL_INITIALIZED_IN_CLASS_P (d)
-                      ? DECL_INITIAL (d) : NULL_TREE),
-                     NULL_TREE, 0);
+      finish_decl (d, init, NULL_TREE);
       pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
@@ -11579,7 +11978,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
-                  tf_error | tf_warning, tmpl);
+                  tf_warning_or_error, tmpl);
 
       /* We don't need the local specializations any more.  */
       htab_delete (local_specializations);
@@ -11624,11 +12023,15 @@ instantiate_pending_templates (int retries)
      to avoid infinite loop.  */
   if (pending_templates && retries >= max_tinst_depth)
     {
-      cp_error_at ("template instantiation depth exceeds maximum of %d"
-                  " (use -ftemplate-depth-NN to increase the maximum)"
-                  " instantiating %q+D, possibly from virtual table"
-                  " generation",
-                  max_tinst_depth, TREE_VALUE (pending_templates));
+      tree decl = TREE_VALUE (pending_templates);
+
+      error ("template instantiation depth exceeds maximum of %d"
+            " instantiating %q+D, possibly from virtual table generation"
+            " (use -ftemplate-depth-NN to increase the maximum)",
+            max_tinst_depth, decl);
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+       /* Pretend that we defined it.  */
+       DECL_INITIAL (decl) = error_mark_node;
       return;
     }
 
@@ -11655,8 +12058,9 @@ instantiate_pending_templates (int retries)
                         fn;
                         fn = TREE_CHAIN (fn))
                      if (! DECL_ARTIFICIAL (fn))
-                       instantiate_decl (fn, /*defer_ok=*/0,
-                                         /*undefined_ok=*/0);
+                       instantiate_decl (fn, 
+                                         /*defer_ok=*/0,
+                                         /*expl_inst_class_mem_p=*/false);
                  if (COMPLETE_TYPE_P (instantiation))
                    reconsider = 1;
                }
@@ -11676,9 +12080,10 @@ instantiate_pending_templates (int retries)
              if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
                  && !DECL_TEMPLATE_INSTANTIATED (instantiation))
                {
-                 instantiation = instantiate_decl (instantiation,
-                                                   /*defer_ok=*/0,
-                                                   /*undefined_ok=*/0);
+                 instantiation 
+                   = instantiate_decl (instantiation,
+                                       /*defer_ok=*/0,
+                                       /*expl_inst_class_mem_p=*/false);
                  if (DECL_TEMPLATE_INSTANTIATED (instantiation))
                    reconsider = 1;
                }
@@ -11720,13 +12125,13 @@ tsubst_initializer_list (tree t, tree argvec)
       tree decl;
       tree init;
 
-      decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_error | tf_warning,
+      decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_warning_or_error,
                          NULL_TREE);
       decl = expand_member_init (decl);
       if (decl && !DECL_P (decl))
        in_base_initializer = 1;
 
-      init = tsubst_expr (TREE_VALUE (t), argvec, tf_error | tf_warning,
+      init = tsubst_expr (TREE_VALUE (t), argvec, tf_warning_or_error,
                          NULL_TREE);
       in_base_initializer = 0;
 
@@ -11771,8 +12176,7 @@ tsubst_enum (tree tag, tree newtag, tree args)
       /* Note that in a template enum, the TREE_VALUE is the
         CONST_DECL, not the corresponding INTEGER_CST.  */
       value = tsubst_expr (DECL_INITIAL (decl),
-                          args, tf_error | tf_warning,
-                          NULL_TREE);
+                          args, tf_warning_or_error, NULL_TREE);
 
       /* Give this enumeration constant the correct access.  */
       set_current_access_from_decl (decl);
@@ -12006,7 +12410,13 @@ dependent_type_p (tree type)
   /* If there are no template parameters in scope, then there can't be
      any dependent types.  */
   if (!processing_template_decl)
-    return false;
+    {
+      /* If we are not processing a template, then nobody should be
+        providing us with a dependent type.  */
+      gcc_assert (type);
+      gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM);
+      return false;
+    }
 
   /* If the type is NULL, we have not computed a type for the entity
      in question; in that case, the type is dependent.  */
@@ -12319,7 +12729,8 @@ type_dependent_expression_p (tree expression)
            return true;
          expression = TREE_OPERAND (expression, 0);
        }
-      gcc_assert (TREE_CODE (expression) == OVERLOAD);
+      gcc_assert (TREE_CODE (expression) == OVERLOAD
+                 || TREE_CODE (expression) == FUNCTION_DECL);
 
       while (expression)
        {
@@ -12330,6 +12741,8 @@ type_dependent_expression_p (tree expression)
       return false;
     }
 
+  gcc_assert (TREE_CODE (expression) != TYPE_DECL);
+  
   return (dependent_type_p (TREE_TYPE (expression)));
 }
 
@@ -12379,6 +12792,8 @@ any_dependent_template_arguments_p (tree args)
 
   if (!args)
     return false;
+  if (args == error_mark_node)
+    return true;
 
   for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
     {
@@ -12524,8 +12939,11 @@ build_non_dependent_expr (tree expr)
     return expr;
   /* Preserve OVERLOADs; the functions must be available to resolve
      types.  */
-  inner_expr = (TREE_CODE (expr) == ADDR_EXPR ?
-               TREE_OPERAND (expr, 0) : expr);
+  inner_expr = expr;
+  if (TREE_CODE (inner_expr) == ADDR_EXPR)
+    inner_expr = TREE_OPERAND (inner_expr, 0);
+  if (TREE_CODE (inner_expr) == COMPONENT_REF)
+    inner_expr = TREE_OPERAND (inner_expr, 1);
   if (is_overloaded_fn (inner_expr)
       || TREE_CODE (inner_expr) == OFFSET_REF)
     return expr;
@@ -12564,6 +12982,9 @@ build_non_dependent_expr (tree expr)
                   TREE_OPERAND (expr, 0),
                   build_non_dependent_expr (TREE_OPERAND (expr, 1)));
 
+  /* If the type is unknown, it can't really be non-dependent */
+  gcc_assert (TREE_TYPE (expr) != unknown_type_node);
+  
   /* Otherwise, build a NON_DEPENDENT_EXPR.
 
      REFERENCE_TYPEs are not stripped for expressions in templates