error.c (dump_function_name): Don't let the user see __comp_ctor.
[gcc.git] / gcc / cp / pt.c
index b64fc72a72edcf1680c99cf30131db7a26c2c6f4..87d4195b3175da953e435beca08f0cfdad497a58 100644 (file)
@@ -43,7 +43,7 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "defaults.h"
 #include "ggc.h"
-#include "hashtab.h"
+#include "timevar.h"
 
 /* The type of functions taking a tree, and some additional data, and
    returning an int.  */
@@ -71,6 +71,8 @@ static tree saved_trees;
 static varray_type inline_parm_levels;
 static size_t inline_parm_levels_used;
 
+static tree current_tinst_level;
+
 /* A map from local variable declarations in the body of the template
    presently being instantiated to the corresponding instantiated
    local variables.  */
@@ -98,9 +100,10 @@ static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
 static int unify PARAMS ((tree, tree, tree, tree, int));
 static void add_pending_template PARAMS ((tree));
 static int push_tinst_level PARAMS ((tree));
+static void reopen_tinst_level PARAMS ((tree));
 static tree classtype_mangled_name PARAMS ((tree));
-static char *mangle_class_name_for_template PARAMS ((char *, tree, tree));
-static tree tsubst_expr_values PARAMS ((tree, tree));
+static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree));
+static tree tsubst_initializer_list PARAMS ((tree, tree));
 static int list_eq PARAMS ((tree, tree));
 static tree get_class_bindings PARAMS ((tree, tree, tree));
 static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int));
@@ -154,12 +157,12 @@ static tree tsubst_call_declarator_parms PARAMS ((tree, tree, int, tree));
 static tree get_template_base_recursive PARAMS ((tree, tree,
                                               tree, tree, tree, int)); 
 static tree get_template_base PARAMS ((tree, tree, tree, tree));
+static int verify_class_unification PARAMS ((tree, tree, tree));
 static tree try_class_unification PARAMS ((tree, tree, tree, tree));
 static int coerce_template_template_parms PARAMS ((tree, tree, int,
                                                 tree, tree));
 static tree determine_specialization PARAMS ((tree, tree, tree *, int));
 static int template_args_equal PARAMS ((tree, tree));
-static void print_template_context PARAMS ((int));
 static void tsubst_default_arguments PARAMS ((tree));
 static tree for_each_template_parm_r PARAMS ((tree *, int *, void *));
 static tree instantiate_clone PARAMS ((tree, tree));
@@ -172,6 +175,7 @@ init_pt ()
   ggc_add_tree_root (&pending_templates, 1);
   ggc_add_tree_root (&maybe_templates, 1);
   ggc_add_tree_root (&saved_trees, 1);
+  ggc_add_tree_root (&current_tinst_level, 1);
 }
 
 /* Do any processing required when DECL (a member template declaration
@@ -342,7 +346,7 @@ push_inline_template_parms_recursive (parmlist, levels)
               available.  */
            tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
                                    TREE_TYPE (parm));
-           SET_DECL_ARTIFICIAL (decl);
+           DECL_ARTIFICIAL (decl) = 1;
            DECL_INITIAL (decl) = DECL_INITIAL (parm);
            SET_DECL_TEMPLATE_PARM_P (decl);
            pushdecl (decl);
@@ -474,9 +478,7 @@ is_member_template_class (t)
 #endif
 
 /* Return a new template argument vector which contains all of ARGS,
-   but has as its innermost set of arguments the EXTRA_ARGS.  The
-   resulting vector will be built on a temporary obstack, and so must
-   be explicitly copied to the permanent obstack, if required.  */
+   but has as its innermost set of arguments the EXTRA_ARGS.  */
 
 static tree
 add_to_template_args (args, extra_args)
@@ -535,6 +537,39 @@ add_outermost_template_args (args, extra_args)
   return new_args;
 }
 
+/* Return the N levels of innermost template arguments from the ARGS.  */
+
+tree
+get_innermost_template_args (args, n)
+     tree args;
+     int n;
+{
+  tree new_args;
+  int extra_levels;
+  int i;
+
+  my_friendly_assert (n >= 0, 20000603);
+
+  /* If N is 1, just return the innermost set of template arguments.  */
+  if (n == 1)
+    return TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args));
+  
+  /* If we're not removing anything, just return the arguments we were
+     given.  */
+  extra_levels = TMPL_ARGS_DEPTH (args) - n;
+  my_friendly_assert (extra_levels >= 0, 20000603);
+  if (extra_levels == 0)
+    return args;
+
+  /* Make a new set of arguments, not containing the outer arguments.  */
+  new_args = make_tree_vec (n);
+  for (i = 1; i <= n; ++i)
+    SET_TMPL_ARGS_LEVEL (new_args, i, 
+                        TMPL_ARGS_LEVEL (args, i + extra_levels));
+
+  return new_args;
+}
+
 /* We've got a template header coming up; push to a new level for storing
    the parms.  */
 
@@ -604,7 +639,7 @@ begin_specialization ()
   check_specialization_scope ();
 }
 
-/* Called at then end of processing a declaration preceeded by
+/* Called at then end of processing a declaration preceded by
    template<>.  */
 
 void 
@@ -712,7 +747,7 @@ retrieve_specialization (tmpl, args)
   return NULL_TREE;
 }
 
-/* Like retrieve_speciailization, but for local declarations.  */
+/* Like retrieve_specialization, but for local declarations.  */
 
 static tree
 retrieve_local_specialization (tmpl)
@@ -1264,8 +1299,12 @@ check_explicit_specialization (declarator, decl, template_count, flags)
          /* This case handles bogus declarations like template <>
             template <class T> void f<int>(); */
 
-         cp_error ("template-id `%D' in declaration of primary template",
-                   declarator);
+         if (uses_template_parms (declarator))
+           cp_error ("partial specialization `%D' of function template",
+                     declarator);
+         else
+           cp_error ("template-id `%D' in declaration of primary template",
+                     declarator);
          return decl;
        }
 
@@ -1469,7 +1508,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
                  /* If TMPL is not the most general template (for
                     example, if TMPL is a friend template that is
                     injected into namespace scope), then there will
-                    be too many levels fo TARGS.  Remove some of them
+                    be too many levels of TARGS.  Remove some of them
                     here.  */
                  int i;
                  tree new_targs;
@@ -1484,13 +1523,13 @@ check_explicit_specialization (declarator, decl, template_count, flags)
              return instantiate_template (tmpl, targs);
            }
 
-         /* If this is both a template specialization, then it's a
-            specialization of a member template of a template class.
-            In that case we want to return the TEMPLATE_DECL, not the
-            specialization of it.  */
+         /* 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.  */
          if (tsk == tsk_template)
            {
              SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
+             DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE;
              return tmpl;
            }
 
@@ -1757,10 +1796,8 @@ process_template_parm (list, next)
     {
       tree p = TREE_VALUE (tree_last (list));
 
-      if (TREE_CODE (p) == TYPE_DECL)
+      if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
        idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
-      else if (TREE_CODE (p) == TEMPLATE_DECL)
-       idx = TEMPLATE_TYPE_IDX (TREE_TYPE (DECL_TEMPLATE_RESULT (p)));
       else
        idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p));
       ++idx;
@@ -1833,7 +1870,7 @@ process_template_parm (list, next)
                                     processing_template_decl,
                                     decl, TREE_TYPE (parm));
     }
-  SET_DECL_ARTIFICIAL (decl);
+  DECL_ARTIFICIAL (decl) = 1;
   SET_DECL_TEMPLATE_PARM_P (decl);
   pushdecl (decl);
   parm = build_tree_list (defval, parm);
@@ -1949,10 +1986,15 @@ build_template_decl (decl, parms)
   DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
   if (DECL_LANG_SPECIFIC (decl))
     {
-      DECL_VIRTUAL_CONTEXT (tmpl) = DECL_VIRTUAL_CONTEXT (decl);
+      if (CAN_HAVE_FULL_LANG_DECL_P (decl))
+       DECL_VIRTUAL_CONTEXT (tmpl) = DECL_VIRTUAL_CONTEXT (decl);
       DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
       DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);
       DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);
+      DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);
+      if (DECL_OVERLOADED_OPERATOR_P (decl))
+       SET_OVERLOADED_OPERATOR_CODE (tmpl, 
+                                     DECL_OVERLOADED_OPERATOR_P (decl));
     }
 
   return tmpl;
@@ -2025,7 +2067,7 @@ process_partial_specialization (decl)
   tree type = TREE_TYPE (decl);
   tree maintmpl = CLASSTYPE_TI_TEMPLATE (type);
   tree specargs = CLASSTYPE_TI_ARGS (type);
-  tree inner_args = innermost_args (specargs);
+  tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs);
   tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
   tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl);
   int nargs = TREE_VEC_LENGTH (inner_args);
@@ -2067,10 +2109,10 @@ process_partial_specialization (decl)
      or some such would have been OK.  */
   tpd.level = TMPL_PARMS_DEPTH (current_template_parms);
   tpd.parms = alloca (sizeof (int) * ntparms);
-  bzero ((PTR) tpd.parms, sizeof (int) * ntparms);
+  memset ((PTR) tpd.parms, 0, sizeof (int) * ntparms);
 
   tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs);
-  bzero ((PTR) tpd.arg_uses_template_parms, sizeof (int) * nargs);
+  memset ((PTR) tpd.arg_uses_template_parms, 0, sizeof (int) * nargs);
   for (i = 0; i < nargs; ++i)
     {
       tpd.current_arg = i;
@@ -2082,7 +2124,7 @@ process_partial_specialization (decl)
     if (tpd.parms[i] == 0)
       {
        /* One of the template parms was not used in the
-           specialization.  */
+          specialization.  */
        if (!did_error_intro)
          {
            cp_error ("template parameters not used in partial specialization:");
@@ -2097,9 +2139,10 @@ process_partial_specialization (decl)
 
      The argument list of the specialization shall not be identical to
      the implicit argument list of the primary template.  */
-  if (comp_template_args (inner_args, 
-                         innermost_args (CLASSTYPE_TI_ARGS (TREE_TYPE
-                                                            (maintmpl)))))
+  if (comp_template_args 
+      (inner_args, 
+       INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE
+                                                  (maintmpl)))))
     cp_error ("partial specialization `%T' does not specialize any template arguments", type);
 
   /* [temp.class.spec]
@@ -2153,7 +2196,7 @@ process_partial_specialization (decl)
                 template, not in the specialization.  */
              tpd2.current_arg = i;
              tpd2.arg_uses_template_parms[i] = 0;
-             bzero ((PTR) tpd2.parms, sizeof (int) * nargs);
+             memset ((PTR) tpd2.parms, 0, sizeof (int) * nargs);
              for_each_template_parm (type,
                                      &mark_template_parm,
                                      &tpd2);
@@ -2373,7 +2416,7 @@ push_template_decl_real (decl, is_friend)
        it is defined.  */
     ctx = CP_DECL_CONTEXT (decl);
   else
-    /* Otherwise, if we're currently definining some class, the DECL
+    /* Otherwise, if we're currently defining some class, the DECL
        is assumed to be a member of the class.  */
     ctx = current_scope ();
 
@@ -2502,7 +2545,9 @@ push_template_decl_real (decl, is_friend)
          DECL_TEMPLATE_INFO (new_tmpl) 
            = tree_cons (tmpl, args, NULL_TREE);
 
-         register_specialization (new_tmpl, tmpl, args);
+         register_specialization (new_tmpl, 
+                                  most_general_template (tmpl), 
+                                  args);
          return decl;
        }
 
@@ -2657,7 +2702,7 @@ redeclare_class_template (type, parms)
 
 /* Attempt to convert the non-type template parameter EXPR to the
    indicated TYPE.  If the conversion is successful, return the
-   converted value.  If the conversion is unsuccesful, return
+   converted value.  If the conversion is unsuccessful, return
    NULL_TREE if we issued an error message, or error_mark_node if we
    did not.  We issue error messages for out-and-out bad template
    parameters, but not simply because the conversion failed, since we
@@ -2724,8 +2769,9 @@ convert_nontype_argument (type, expr)
       tree e = expr;
       STRIP_NOPS (e);
 
-      if (TREE_CODE (type) == REFERENCE_TYPE
-         || TREE_CODE (expr_type) == ARRAY_TYPE)
+      if (TREE_CODE (expr_type) == ARRAY_TYPE
+         || (TREE_CODE (type) == REFERENCE_TYPE
+             && TREE_CODE (e) != ADDR_EXPR))
        referent = e;
       else
        {
@@ -2763,7 +2809,7 @@ convert_nontype_argument (type, expr)
        ;
       else if (TREE_CODE (referent) != VAR_DECL)
        goto bad_argument;
-      else if (!TREE_PUBLIC (referent))
+      else if (!DECL_EXTERNAL_LINKAGE_P (referent))
        {
          cp_error ("address of non-extern `%E' cannot be used as template argument", referent); 
          return error_mark_node;
@@ -2865,12 +2911,12 @@ convert_nontype_argument (type, expr)
            else
              fns = expr;
 
-           fn = instantiate_type (type_pointed_to, fns, 0);
+           fn = instantiate_type (type_pointed_to, fns, itf_none);
 
            if (fn == error_mark_node)
              return error_mark_node;
 
-           if (!TREE_PUBLIC (fn))
+           if (!DECL_EXTERNAL_LINKAGE_P (fn))
              {
                if (really_overloaded_fn (fns))
                  return error_mark_node;
@@ -2912,6 +2958,15 @@ convert_nontype_argument (type, expr)
       {
        tree type_referred_to = TREE_TYPE (type);
 
+       /* If this expression already has reference type, get the
+          underling object.  */
+       if (TREE_CODE (expr_type) == REFERENCE_TYPE) 
+         {
+           my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
+           expr = TREE_OPERAND (expr, 0);
+           expr_type = TREE_TYPE (expr);
+         }
+
        if (TREE_CODE (type_referred_to) == FUNCTION_TYPE)
          {
            /* For a non-type template-parameter of type reference to
@@ -2919,17 +2974,16 @@ convert_nontype_argument (type, expr)
               template-argument represents a set of overloaded
               functions, the matching function is selected from the
               set (_over.over_).  */
-           tree fns = expr;
            tree fn;
 
-           fn = instantiate_type (type_referred_to, fns, 0);
+           fn = instantiate_type (type_referred_to, expr, itf_none);
 
            if (fn == error_mark_node)
              return error_mark_node;
 
-           if (!TREE_PUBLIC (fn))
+           if (!DECL_EXTERNAL_LINKAGE_P (fn))
              {
-               if (really_overloaded_fn (fns))
+               if (really_overloaded_fn (expr))
                  /* Don't issue an error here; we might get a different
                     function if the overloading had worked out
                     differently.  */
@@ -2942,7 +2996,7 @@ convert_nontype_argument (type, expr)
                                             TREE_TYPE (fn)),
                                0);
 
-           return fn;
+           expr = fn;
          }
        else
          {
@@ -2952,15 +3006,16 @@ convert_nontype_argument (type, expr)
               identical) type of the template-argument.  The
               template-parameter is bound directly to the
               template-argument, which must be an lvalue.  */
-           if ((TYPE_MAIN_VARIANT (expr_type)
-                != TYPE_MAIN_VARIANT (type_referred_to))
+           if (!same_type_p (TYPE_MAIN_VARIANT (expr_type),
+                             TYPE_MAIN_VARIANT (type_referred_to))
                || !at_least_as_qualified_p (type_referred_to,
                                             expr_type)
                || !real_lvalue_p (expr))
              return error_mark_node;
-           else
-             return expr;
          }
+
+       mark_addressable (expr);
+       return build1 (ADDR_EXPR, type, expr);
       }
       break;
 
@@ -2996,7 +3051,7 @@ convert_nontype_argument (type, expr)
        if (TREE_CODE (expr) != ADDR_EXPR)
          return error_mark_node;
 
-       expr = instantiate_type (type, expr, 0);
+       expr = instantiate_type (type, expr, itf_none);
        
        if (expr == error_mark_node)
          return error_mark_node;
@@ -3124,7 +3179,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
   tree inner_args;
   int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
   
-  inner_args = innermost_args (args);
+  inner_args = INNERMOST_TEMPLATE_ARGS (args);
 
   if (TREE_CODE (arg) == TREE_LIST 
       && TREE_TYPE (arg) != NULL_TREE
@@ -3152,8 +3207,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
   is_tmpl_type 
     = ((TREE_CODE (arg) == TEMPLATE_DECL
        && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
-       || (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
-          && !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg))
+       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
        || (TREE_CODE (arg) == RECORD_TYPE
           && CLASSTYPE_TEMPLATE_INFO (arg)
           && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
@@ -3280,7 +3334,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
           the standard.  Accepting this is not merely an
           extension, since deciding whether or not these
           conversions can occur is part of determining which
-          function template to call, or whether a given epxlicit
+          function template to call, or whether a given explicit
           argument specification is legal.  */
        val = convert_nontype_argument (t, arg);
       else
@@ -3322,7 +3376,7 @@ coerce_template_parms (parms, args, in_decl,
   tree new_args;
   tree new_inner_args;
 
-  inner_args = innermost_args (args);
+  inner_args = INNERMOST_TEMPLATE_ARGS (args);
   nargs = NUM_TMPL_ARGS (inner_args);
   nparms = TREE_VEC_LENGTH (parms);
 
@@ -3411,13 +3465,14 @@ template_args_equal (ot, nt)
 {
   if (nt == ot)
     return 1;
-  if (TREE_CODE (nt) != TREE_CODE (ot))
-    return 0;
+
   if (TREE_CODE (nt) == TREE_VEC)
     /* For member templates */
-    return comp_template_args (ot, nt);
-  else if (TYPE_P (ot))
-    return same_type_p (ot, nt);
+    return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt);
+  else if (TYPE_P (nt))
+    return TYPE_P (ot) && same_type_p (ot, nt);
+  else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
+    return 0;
   else
     return (cp_tree_equal (ot, nt) > 0);
 }
@@ -3450,7 +3505,7 @@ comp_template_args (oldargs, newargs)
 
 static char *
 mangle_class_name_for_template (name, parms, arglist)
-     char *name;
+     const char *name;
      tree parms, arglist;
 {
   static struct obstack scratch_obstack;
@@ -3469,7 +3524,7 @@ mangle_class_name_for_template (name, parms, arglist)
   cat (name);
   ccat ('<');
   nparms = TREE_VEC_LENGTH (parms);
-  arglist = innermost_args (arglist);
+  arglist = INNERMOST_TEMPLATE_ARGS (arglist);
   my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
   for (i = 0; i < nparms; i++)
     {
@@ -3481,7 +3536,7 @@ mangle_class_name_for_template (name, parms, arglist)
 
       if (TREE_CODE (parm) == TYPE_DECL)
        {
-         cat (type_as_string (arg, TS_CHASE_TYPEDEFS));
+         cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
          continue;
        }
       else if (TREE_CODE (parm) == TEMPLATE_DECL)
@@ -3498,14 +3553,14 @@ mangle_class_name_for_template (name, parms, arglist)
                   my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL
                                       || CLASS_TYPE_P (context), 
                                       980422);
-                 cat(decl_as_string (DECL_CONTEXT (arg), 0));
+                 cat(decl_as_string (DECL_CONTEXT (arg), TFF_PLAIN_IDENTIFIER));
                  cat("::");
                }
              cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
            }
          else
            /* Output the parameter declaration */
-           cat (type_as_string (arg, TS_CHASE_TYPEDEFS));
+           cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
          continue;
        }
       else
@@ -3520,7 +3575,7 @@ mangle_class_name_for_template (name, parms, arglist)
        }
       /* No need to check arglist against parmlist here; we did that
         in coerce_template_parms, called from lookup_template_class.  */
-      cat (expr_as_string (arg, 0));
+      cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER));
     }
   {
     char *bufp = obstack_next_free (&scratch_obstack);
@@ -3571,14 +3626,28 @@ static void
 add_pending_template (d)
      tree d;
 {
-  tree ti = (TYPE_P (d)) ? CLASSTYPE_TEMPLATE_INFO (d) : DECL_TEMPLATE_INFO (d);
+  tree ti = (TYPE_P (d)
+            ? CLASSTYPE_TEMPLATE_INFO (d)
+            : DECL_TEMPLATE_INFO (d));
+  int level;
 
   if (TI_PENDING_TEMPLATE_FLAG (ti))
     return;
 
-  *template_tail = tree_cons (build_srcloc_here (), d, NULL_TREE);
+  /* We are called both from instantiate_decl, where we've already had a
+     tinst_level pushed, and instantiate_template, where we haven't.
+     Compensate.  */
+  level = !(current_tinst_level && TINST_DECL (current_tinst_level) == d);
+
+  if (level)
+    push_tinst_level (d);
+
+  *template_tail = tree_cons (current_tinst_level, d, NULL_TREE);
   template_tail = &TREE_CHAIN (*template_tail);
   TI_PENDING_TEMPLATE_FLAG (ti) = 1;
+
+  if (level)
+    pop_tinst_level ();
 }
 
 
@@ -3633,9 +3702,7 @@ maybe_get_template_decl_from_type_decl (decl)
    D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
    (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC.  It will
    be a TREE_LIST if called directly from the parser, and a TREE_VEC
-   otherwise.)  Since ARGLIST is build on the temp_decl_obstack, we must
-   copy it here to keep it from being reclaimed when the decl storage
-   is reclaimed.
+   otherwise.)
 
    IN_DECL, if non-NULL, is the template declaration we are trying to
    instantiate.  
@@ -3702,23 +3769,18 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
       d1 = DECL_NAME (template);
       context = DECL_CONTEXT (template);
     }
-  else
-    my_friendly_abort (272);
 
   /* With something like `template <class T> class X class X { ... };'
      we could end up with D1 having nothing but an IDENTIFIER_VALUE.
      We don't want to do that, but we have to deal with the situation,
      so let's give them some syntax errors to chew on instead of a
-     crash.  */
+     crash. Alternatively D1 might not be a template type at all.  */
   if (! template)
     {
       cp_error ("`%T' is not a template", d1);
       return error_mark_node;
     }
 
-  if (context == NULL_TREE)
-    context = global_namespace;
-
   if (TREE_CODE (template) != TEMPLATE_DECL)
     {
       cp_error ("non-template type `%T' used as a template", d1);
@@ -3732,8 +3794,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
       /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
          template arguments */
 
-      tree parm = copy_template_template_parm (TREE_TYPE (template));
-      tree template2 = TYPE_STUB_DECL (parm);
+      tree parm;
       tree arglist2;
 
       parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
@@ -3742,8 +3803,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
       if (arglist2 == error_mark_node)
        return error_mark_node;
 
-      TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)
-       = tree_cons (template2, arglist2, NULL_TREE);
+      parm = copy_template_template_parm (TREE_TYPE (template), arglist2);
       TYPE_SIZE (parm) = 0;
       return parm;
     }
@@ -3824,7 +3884,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
       else
        arglist
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
-                                  innermost_args (arglist),
+                                  INNERMOST_TEMPLATE_ARGS (arglist),
                                   template, 1, 1);
 
       if (arglist == error_mark_node)
@@ -3850,7 +3910,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
              
              /* Note that we use DECL_CONTEXT, rather than
                 CP_DECL_CONTEXT, so that the termination test is
-                always just `ctx'.  We're not interested in namepace
+                always just `ctx'.  We're not interested in namespace
                 scopes.  */
              for (ctx = current_class_type; 
                   ctx; 
@@ -3865,23 +3925,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
                found = NULL_TREE;
            }
        }
-      
-      if (!found)
-       {
-         for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
-              found; found = TREE_CHAIN (found))
-           if (comp_template_args (TREE_PURPOSE (found), arglist))
-             break;
-
-         if (found)
-           found = TREE_VALUE (found);
-       }
-
       if (found)
-       return found;
+        return found;
+      
+      for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
+          found; found = TREE_CHAIN (found))
+       if (comp_template_args (TREE_PURPOSE (found), arglist))
+          return TREE_VALUE (found);
 
       /* This type is a "partial instantiation" if any of the template
-        arguments still inolve template parameters.  Note that we set
+        arguments still involve template parameters.  Note that we set
         IS_PARTIAL_INSTANTIATION for partial specializations as
         well.  */
       is_partial_instantiation = uses_template_parms (arglist);
@@ -3896,11 +3949,19 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
          return found;
        }
       
+      context = tsubst (DECL_CONTEXT (template), arglist,
+                       /*complain=*/0, in_decl);
+      if (!context)
+       context = global_namespace;
+
       /* Create the type.  */
       if (TREE_CODE (template_type) == ENUMERAL_TYPE)
        {
          if (!is_partial_instantiation)
-           t = start_enum (TYPE_IDENTIFIER (template_type));
+           {
+             set_current_access_from_decl (TYPE_NAME (template_type));
+             t = start_enum (TYPE_IDENTIFIER (template_type));
+           }
          else
            /* We don't want to call start_enum for this type, since
               the values for the enumeration constants may involve
@@ -3948,9 +4009,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
        found = template;
       else
        {
-         /* This is a full instantiation of a member template.  There
-            should be some partial instantiation of which this is an
-            instance.  */
+         /* This is a full instantiation of a member template.  Look
+            for a partial instantiation of which this is an instance.  */
 
          for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
               found; found = TREE_CHAIN (found))
@@ -3986,11 +4046,24 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
            }
 
          if (!found)
-           my_friendly_abort (0);
+           {
+             /* There was no partial instantiation. This happens
+                 where C<T> is a member template of A<T> and it's used
+                 in something like
+                
+                  template <typename T> struct B { A<T>::C<int> m; };
+                  B<float>;
+                
+                 Create the partial instantiation.
+               */
+              TREE_VEC_LENGTH (arglist)--;
+              template = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
+              TREE_VEC_LENGTH (arglist)++;
+              found = template;
+            }
        }
 
-      SET_TYPE_TEMPLATE_INFO (t,
-                             tree_cons (found, arglist, NULL_TREE));  
+      SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));  
       DECL_TEMPLATE_INSTANTIATIONS (template) 
        = tree_cons (arglist, t, 
                     DECL_TEMPLATE_INSTANTIATIONS (template));
@@ -4013,8 +4086,11 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
       DECL_ASSEMBLER_NAME (type_decl) = DECL_NAME (type_decl);
       if (!is_partial_instantiation)
        {
-         DECL_ASSEMBLER_NAME (type_decl)
-           = get_identifier (build_overload_name (t, 1, 1));
+         if (flag_new_abi)
+           DECL_ASSEMBLER_NAME (type_decl) = mangle_decl (type_decl);
+         else
+           DECL_ASSEMBLER_NAME (type_decl)
+             = get_identifier (build_overload_name (t, 1, 1));
 
          /* For backwards compatibility; code that uses
             -fexternal-templates expects looking up a template to
@@ -4061,7 +4137,7 @@ for_each_template_parm_r (tp, walk_subtrees, d)
   switch (TREE_CODE (t))
     {
     case RECORD_TYPE:
-      if (TYPE_PTRMEMFUNC_FLAG (t))
+      if (TYPE_PTRMEMFUNC_P (t))
        break;
       /* Fall through.  */
 
@@ -4118,13 +4194,13 @@ for_each_template_parm_r (tp, walk_subtrees, d)
        return error_mark_node;
       break;
 
-    case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Record template parameters such as `T' inside `TT<T>'.  */
-      if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
-         && for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
+      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
        return error_mark_node;
       /* Fall through.  */
 
+    case TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_PARM_INDEX:
       if (fn && (*fn)(t, data))
@@ -4186,8 +4262,9 @@ for_each_template_parm_r (tp, walk_subtrees, d)
   return NULL_TREE;
 }
 
-/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, or
-   TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA.
+/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, 
+   BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T, 
+   call FN with the parameter and the DATA.
    If FN returns non-zero, the iteration is terminated, and
    for_each_template_parm returns 1.  Otherwise, the iteration
    continues.  If FN never returns a non-zero value, the value
@@ -4207,7 +4284,9 @@ for_each_template_parm (t, fn, data)
   pfd.data = data;
 
   /* Walk the tree.  */
-  return walk_tree (&t, for_each_template_parm_r, &pfd) != NULL_TREE;
+  return walk_tree_without_duplicates (&t, 
+                                      for_each_template_parm_r, 
+                                      &pfd) != NULL_TREE;
 }
 
 int
@@ -4217,8 +4296,6 @@ uses_template_parms (t)
   return for_each_template_parm (t, 0, 0);
 }
 
-static struct tinst_level *current_tinst_level;
-static struct tinst_level *free_tinst_level;
 static int tinst_depth;
 extern int max_tinst_depth;
 #ifdef GATHER_STATISTICS
@@ -4227,68 +4304,14 @@ int depth_reached;
 static int tinst_level_tick;
 static int last_template_error_tick;
 
-/* Print out all the template instantiations that we are currently
-   working on.  If ERR, we are being called from cp_thing, so do
-   the right thing for an error message.  */
-
-static void
-print_template_context (err)
-     int err;
-{
-  struct tinst_level *p = current_tinst_level;
-  int line = lineno;
-  const char *file = input_filename;
-
-  if (err && p)
-    {
-      if (current_function_decl != p->decl
-         && current_function_decl != NULL_TREE)
-       /* We can get here during the processing of some synthesized
-          method.  Then, p->decl will be the function that's causing
-          the synthesis.  */
-       ;
-      else
-       {
-         if (current_function_decl == p->decl)
-           /* Avoid redundancy with the the "In function" line.  */;
-         else 
-           fprintf (stderr, "%s: In instantiation of `%s':\n",
-                    file, decl_as_string (p->decl, TS_DECL_TYPE | TS_FUNC_NORETURN));
-         
-         line = p->line;
-         file = p->file;
-         p = p->next;
-       }
-    }
-
-  for (; p; p = p->next)
-    {
-      fprintf (stderr, "%s:%d:   instantiated from `%s'\n", file, line,
-              decl_as_string (p->decl, TS_DECL_TYPE | TS_FUNC_NORETURN));
-      line = p->line;
-      file = p->file;
-    }
-  fprintf (stderr, "%s:%d:   instantiated from here\n", file, line);
-}
-
-/* Called from cp_thing to print the template context for an error.  */
-
-void
-maybe_print_template_context ()
-{
-  if (last_template_error_tick == tinst_level_tick
-      || current_tinst_level == 0)
-    return;
-
-  last_template_error_tick = tinst_level_tick;
-  print_template_context (1);
-}
+/* We're starting to instantiate D; record the template instantiation context
+   for diagnostics and to restore it later.  */
 
 static int
 push_tinst_level (d)
      tree d;
 {
-  struct tinst_level *new;
+  tree new;
 
   if (tinst_depth >= max_tinst_depth)
     {
@@ -4302,23 +4325,13 @@ push_tinst_level (d)
       cp_error ("template instantiation depth exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum) instantiating `%D'",
             max_tinst_depth, d);
 
-      print_template_context (0);
+      print_instantiation_context ();
 
       return 0;
     }
 
-  if (free_tinst_level)
-    {
-      new = free_tinst_level;
-      free_tinst_level = new->next;
-    }
-  else
-    new = (struct tinst_level *) xmalloc (sizeof (struct tinst_level));
-
-  new->decl = d;
-  new->line = lineno;
-  new->file = input_filename;
-  new->next = current_tinst_level;
+  new = build_expr_wfl (d, input_filename, lineno, 0);
+  TREE_CHAIN (new) = current_tinst_level;
   current_tinst_level = new;
 
   ++tinst_depth;
@@ -4331,31 +4344,53 @@ push_tinst_level (d)
   return 1;
 }
 
+/* We're done instantiating this template; return to the instantiation
+   context.  */
+
 void
 pop_tinst_level ()
 {
-  struct tinst_level *old = current_tinst_level;
+  tree old = current_tinst_level;
 
   /* Restore the filename and line number stashed away when we started
      this instantiation.  */
-  lineno = old->line;
-  input_filename = old->file;
+  lineno = TINST_LINE (old);
+  input_filename = TINST_FILE (old);
   extract_interface_info ();
   
-  current_tinst_level = old->next;
-  old->next = free_tinst_level;
-  free_tinst_level = old;
+  current_tinst_level = TREE_CHAIN (old);
   --tinst_depth;
   ++tinst_level_tick;
 }
 
-struct tinst_level *
+/* We're instantiating a deferred template; restore the template
+   instantiation context in which the instantiation was requested, which
+   is one step out from LEVEL.  */
+
+static void
+reopen_tinst_level (level)
+     tree level;
+{
+  tree t;
+
+  tinst_depth = 0;
+  for (t = level; t; t = TREE_CHAIN (t))
+    ++tinst_depth;
+
+  current_tinst_level = level;
+  pop_tinst_level ();
+}
+
+/* Return the outermost template instantiation context, for use with
+   -falt-external-templates.  */
+
+tree
 tinst_for_decl ()
 {
-  struct tinst_level *p = current_tinst_level;
+  tree p = current_tinst_level;
 
   if (p)
-    for (; p->next ; p = p->next )
+    for (; TREE_CHAIN (p) ; p = TREE_CHAIN (p))
       ;
   return p;
 }
@@ -4363,7 +4398,7 @@ tinst_for_decl ()
 /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL.  ARGS is the
    vector of template arguments, as for tsubst.
 
-   Returns an appropriate tsbust'd friend declaration.  */
+   Returns an appropriate tsubst'd friend declaration.  */
 
 static tree
 tsubst_friend_function (decl, args)
@@ -4389,17 +4424,22 @@ tsubst_friend_function (decl, args)
        function declaration.  Now, we have to figure out what
        instantiation of what template.  */
     {
-      tree template_id;
+      tree template_id, arglist, fns;
       tree new_args;
       tree tmpl;
-
-      template_id
-       = lookup_template_function (tsubst_expr (DECL_TI_TEMPLATE (decl),
-                                                args, /*complain=*/1, 
-                                                NULL_TREE),
-                                   tsubst (DECL_TI_ARGS (decl),
-                                           args, /*complain=*/1, 
-                                           NULL_TREE));
+      tree ns = CP_DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
+      
+      /* Friend functions are looked up in the containing namespace scope.
+         We must enter that scope, to avoid finding member functions of the
+         current cless with same name.  */
+      push_nested_namespace (ns);
+      fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
+                         /*complain=*/1, NULL_TREE);
+      pop_nested_namespace (ns);
+      arglist = tsubst (DECL_TI_ARGS (decl), args,
+                        /*complain=*/1, NULL_TREE);
+      template_id = lookup_template_function (fns, arglist);
+      
       new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
       tmpl = determine_specialization (template_id, new_friend,
                                       &new_args, 
@@ -4422,7 +4462,11 @@ tsubst_friend_function (decl, args)
      instantiation of anything.  */
   DECL_USE_TEMPLATE (new_friend) = 0;
   if (TREE_CODE (decl) == TEMPLATE_DECL)
-    DECL_USE_TEMPLATE (DECL_TEMPLATE_RESULT (new_friend)) = 0;
+    {
+      DECL_USE_TEMPLATE (DECL_TEMPLATE_RESULT (new_friend)) = 0;
+      DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (new_friend))
+       = DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (decl));
+    }
 
   /* The mangled name for the NEW_FRIEND is incorrect.  The call to
      tsubst will have resulted in a call to
@@ -4586,7 +4630,8 @@ tsubst_friend_function (decl, args)
 /* FRIEND_TMPL is a friend TEMPLATE_DECL.  ARGS is the vector of
    template arguments, as for tsubst.
 
-   Returns an appropriate tsbust'd friend type.  */
+   Returns an appropriate tsubst'd friend type or error_mark_node on
+   failure.  */
 
 static tree
 tsubst_friend_class (friend_tmpl, args)
@@ -4627,6 +4672,8 @@ tsubst_friend_class (friend_tmpl, args)
       tree parms 
        = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl),
                                 args, /*complain=*/1);
+      if (!parms)
+        return error_mark_node;
       redeclare_class_template (TREE_TYPE (tmpl), parms);
       friend_type = TREE_TYPE (tmpl);
     }
@@ -4752,6 +4799,8 @@ instantiate_class_template (type)
       TYPE_FIELDS (type) = TYPE_FIELDS (pattern);
       TYPE_METHODS (type) = TYPE_METHODS (pattern);
       CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
+      CLASSTYPE_VBASECLASSES (type) = CLASSTYPE_VBASECLASSES (pattern);
+      
       /* Pretend that the type is complete, so that we will look
         inside it during name lookup and such.  */
       TYPE_SIZE (type) = bitsize_zero_node;
@@ -4846,6 +4895,7 @@ instantiate_class_template (type)
     = TYPE_USES_VIRTUAL_BASECLASSES (pattern);
   TYPE_PACKED (type) = TYPE_PACKED (pattern);
   TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
+  TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern);
   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);
@@ -4866,7 +4916,7 @@ instantiate_class_template (type)
 
          pbase = TREE_VEC_ELT (pbases, i);
 
-         /* Substitue to figure out the base class.  */
+         /* Substitute to figure out the base class.  */
          base = tsubst (BINFO_TYPE (pbase), args, 
                         /*complain=*/1, NULL_TREE);
          if (base == error_mark_node)
@@ -4911,7 +4961,7 @@ instantiate_class_template (type)
 
   /* Now that our base classes are set up, enter the scope of the
      class, so that name lookups into base classes, etc. will work
-     corectly.  This is precisely analagous to what we do in
+     correctly.  This is precisely analogous to what we do in
      begin_class_definition when defining an ordinary non-template
      class.  */
   pushclass (type, 1);
@@ -5050,7 +5100,8 @@ instantiate_class_template (type)
           information.  */
        ++processing_template_decl;
 
-      make_friend_class (type, new_friend_type);
+      if (new_friend_type != error_mark_node)
+        make_friend_class (type, new_friend_type);
 
       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
        --processing_template_decl;
@@ -5084,7 +5135,7 @@ instantiate_class_template (type)
   if (!PRIMARY_TEMPLATE_P (template))
     for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t))
       if (TREE_CODE (t) == FUNCTION_DECL 
-         /* Implicitly generated member functions will not have tmplate
+         /* Implicitly generated member functions will not have template
             information; they are not instantiations, but instead are
             created "fresh" for each instantiation.  */
          && DECL_TEMPLATE_INFO (t))
@@ -5143,17 +5194,6 @@ maybe_fold_nontype_arg (arg)
   return arg;
 }
 
-/* Return the TREE_VEC with the arguments for the innermost template header,
-   where ARGS is either that or the VEC of VECs for all the
-   arguments.  */
-
-tree
-innermost_args (args)
-     tree args;
-{
-  return TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args));
-}
-
 /* Substitute ARGS into the vector of template arguments T.  */
 
 static tree
@@ -5165,7 +5205,7 @@ tsubst_template_arg_vector (t, args, complain)
   int len = TREE_VEC_LENGTH (t), need_new = 0, i;
   tree *elts = (tree *) alloca (len * sizeof (tree));
   
-  bzero ((char *) elts, len * sizeof (tree));
+  memset ((char *) elts, 0, len * sizeof (tree));
   
   for (i = 0; i < len; i++)
     {
@@ -5178,6 +5218,9 @@ tsubst_template_arg_vector (t, args, complain)
          (tsubst_expr (TREE_VEC_ELT (t, i), args, complain,
                        NULL_TREE));
       
+      if (elts[i] == error_mark_node)
+       return error_mark_node;
+
       if (elts[i] != TREE_VEC_ELT (t, i))
        need_new = 1;
     }
@@ -5244,7 +5287,7 @@ tsubst_template_parms (parms, args, complain)
    type T.  If T is not an aggregate or enumeration type, it is
    handled as if by tsubst.  IN_DECL is as for tsubst.  If
    ENTERING_SCOPE is non-zero, T is the context for a template which
-   we are presently tsubst'ing.  Return the subsituted value.  */
+   we are presently tsubst'ing.  Return the substituted value.  */
 
 static tree
 tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
@@ -5297,6 +5340,8 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
             S we only want {double}.  */
          argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args,
                                               complain);
+         if (argvec == error_mark_node)
+           return error_mark_node;
 
          r = lookup_template_class (t, argvec, in_decl, context,
                                     entering_scope);
@@ -5496,61 +5541,6 @@ tsubst_decl (t, args, type, in_decl)
        if (TREE_CODE (decl) == TYPE_DECL)
          break;
 
-       for (spec = DECL_TEMPLATE_SPECIALIZATIONS (t);
-            spec != NULL_TREE;
-            spec = TREE_CHAIN (spec))
-         {
-           /* It helps to consider example here.  Consider:
-
-              template <class T>
-              struct S {
-                template <class U>
-                void f(U u);
-
-                template <>
-                void f(T* t) {}
-              };
-              
-              Now, for example, we are instantiating S<int>::f(U u).  
-              We want to make a template:
-
-              template <class U>
-              void S<int>::f(U);
-
-              It will have a specialization, for the case U = int*, of
-              the form:
-
-              template <>
-              void S<int>::f<int*>(int*);
-
-              This specialization will be an instantiation of
-              the specialization given in the declaration of S, with
-              argument list int*.  */
-
-           tree fn = TREE_VALUE (spec);
-           tree spec_args;
-           tree new_fn;
-
-           if (!DECL_TEMPLATE_SPECIALIZATION (fn))
-             /* Instantiations are on the same list, but they're of
-                no concern to us.  */
-             continue;
-
-           if (TREE_CODE (fn) != TEMPLATE_DECL)
-             /* A full specialization.  There's no need to record
-                that here.  */
-             continue;
-
-           spec_args = tsubst (DECL_TI_ARGS (fn), args,
-                               /*complain=*/1, in_decl); 
-           new_fn
-             = tsubst (DECL_TEMPLATE_RESULT (most_general_template (fn)), 
-                       spec_args, /*complain=*/1, in_decl); 
-           DECL_TI_TEMPLATE (new_fn) = fn;
-           register_specialization (new_fn, r, 
-                                    innermost_args (spec_args));
-         }
-
        /* Record this partial instantiation.  */
        register_specialization (r, t, 
                                 DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
@@ -5593,7 +5583,19 @@ tsubst_decl (t, args, type, in_decl)
                break;
              }
 
-           /* Here, we deal with the peculiar case:
+           /* We can see more levels of arguments than parameters if
+              there was a specialization of a member template, like
+              this:
+
+                template <class T> struct S { template <class U> void f(); }
+                template <> template <class U> void S<int>::f(U); 
+
+              Here, we'll be substituting into the specialization,
+              because that's where we can find the code we actually
+              want to generate, but we'll have enough arguments for
+              the most general template.              
+
+              We also deal with the peculiar case:
 
                 template <class T> struct S { 
                   template <class U> friend void f();
@@ -5618,21 +5620,7 @@ tsubst_decl (t, args, type, in_decl)
              TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t))); 
            if (args_depth > parms_depth
                && !DECL_TEMPLATE_SPECIALIZATION (t))
-             {
-               my_friendly_assert (DECL_FRIEND_P (t), 0);
-
-               if (parms_depth > 1)
-                 {
-                   int i;
-
-                   args = make_tree_vec (parms_depth);
-                   for (i = 0; i < parms_depth; ++i)
-                     TREE_VEC_ELT (args, i) = 
-                       TREE_VEC_ELT (args, i + (args_depth - parms_depth));
-                 }
-               else
-                 args = TREE_VEC_ELT (args, args_depth - parms_depth);
-             }
+             args = get_innermost_template_args (args, parms_depth);
          }
        else
          {
@@ -5676,7 +5664,7 @@ tsubst_decl (t, args, type, in_decl)
        /* We do NOT check for matching decls pushed separately at this
            point, as they may not represent instantiations of this
            template, and in any case are considered separate under the
-           discrete model.  Instead, see add_maybe_template.  */
+           discrete model.  */
        r = copy_decl (t);
        DECL_USE_TEMPLATE (r) = 0;
        TREE_TYPE (r) = type;
@@ -5687,10 +5675,15 @@ tsubst_decl (t, args, type, in_decl)
                              /*complain=*/1, t,
                              /*entering_scope=*/1);
 
-       if (member && DECL_CONV_FN_P (r))
-         /* Type-conversion operator.  Reconstruct the name, in
-            case it's the name of one of the template's parameters.  */
-         DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
+       if (member && DECL_CONV_FN_P (r)) 
+         {
+           /* Type-conversion operator.  Reconstruct the name, in
+              case it's the name of one of the template's parameters.  */
+           if (flag_new_abi)
+             DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type));
+           else
+             DECL_NAME (r) = build_typename_overload (TREE_TYPE (type));
+         }
 
        DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
                                     /*complain=*/1, t);
@@ -5704,6 +5697,7 @@ tsubst_decl (t, args, type, in_decl)
        TREE_CHAIN (r) = NULL_TREE;
        DECL_PENDING_INLINE_INFO (r) = 0;
        DECL_PENDING_INLINE_P (r) = 0;
+       DECL_SAVED_TREE (r) = NULL_TREE;
        TREE_USED (r) = 0;
        if (DECL_CLONED_FUNCTION (r))
          {
@@ -5724,8 +5718,13 @@ tsubst_decl (t, args, type, in_decl)
            register_specialization (r, gen_tmpl, argvec);
 
            /* Set the mangled name for R.  */
-           if (DECL_DESTRUCTOR_P (t))
-             DECL_ASSEMBLER_NAME (r) = build_destructor_name (ctx);
+           if (DECL_DESTRUCTOR_P (t)) 
+             {
+               if (flag_new_abi)
+                 set_mangled_name_for_decl (r);
+               else
+                 DECL_ASSEMBLER_NAME (r) = build_destructor_name (ctx);
+             }
            else 
              {
                /* Instantiations of template functions must be mangled
@@ -5789,6 +5788,8 @@ tsubst_decl (t, args, type, in_decl)
            maybe_retrofit_in_chrg (r);
            if (DECL_CONSTRUCTOR_P (r))
              grok_ctor_properties (ctx, r);
+           if (PRIMARY_TEMPLATE_P (gen_tmpl))
+             clone_function_decl(r, /*update_method_vec_p=*/0);
          }
        else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
          grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
@@ -5845,20 +5846,13 @@ tsubst_decl (t, args, type, in_decl)
       break;
 
     case TYPE_DECL:
-      if (DECL_IMPLICIT_TYPEDEF_P (t))
+      if (TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
+         || t == TYPE_MAIN_DECL (TREE_TYPE (t)))
        {
-         /* For an implicit typedef, we just want the implicit
-            typedef for the tsubst'd type.  We've already got the
-            tsubst'd type, as TYPE, so we just need it's associated
-            declaration.  */
-         r = TYPE_NAME (type);
-         break;
-       }
-      else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
-              || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
-       {
-         /* For a template type parameter, we don't have to do
-            anything special.  */
+         /* If this is the canonical decl, we don't have to mess with
+             instantiations, and often we can't (for typename, template
+            type parms and such).  Note that TYPE_NAME is not correct for
+            the above test if we've copied the type for a typedef.  */
          r = TYPE_NAME (type);
          break;
        }
@@ -6174,6 +6168,7 @@ tsubst (t, args, complain, in_decl)
     case VOID_TYPE:
     case REAL_TYPE:
     case COMPLEX_TYPE:
+    case VECTOR_TYPE:
     case BOOLEAN_TYPE:
     case INTEGER_CST:
     case REAL_CST:
@@ -6245,6 +6240,7 @@ tsubst (t, args, complain, in_decl)
 
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_PARM_INDEX:
       {
        int idx;
@@ -6254,7 +6250,8 @@ tsubst (t, args, complain, in_decl)
        r = NULL_TREE;
 
        if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
-           || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+           || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
+           || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
          {
            idx = TEMPLATE_TYPE_IDX (t);
            level = TEMPLATE_TYPE_LEVEL (t);
@@ -6284,38 +6281,33 @@ tsubst (t, args, complain, in_decl)
                      (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t),
                       complain);
                  }
-               else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+               else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
                  {
-                   if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
-                     {
-                       /* We are processing a type constructed from
-                          a template template parameter */
-                       tree argvec = tsubst (TYPE_TI_ARGS (t),
-                                             args, complain, in_decl);
-                       if (argvec == error_mark_node)
-                         return error_mark_node;
+                   /* We are processing a type constructed from
+                      a template template parameter */
+                   tree argvec = tsubst (TYPE_TI_ARGS (t),
+                                         args, complain, in_decl);
+                   if (argvec == error_mark_node)
+                     return error_mark_node;
                        
-                       /* We can get a TEMPLATE_TEMPLATE_PARM here when 
-                          we are resolving nested-types in the signature of 
-                          a member function templates.
-                          Otherwise ARG is a TEMPLATE_DECL and is the real 
-                          template to be instantiated.  */
-                       if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
-                         arg = TYPE_NAME (arg);
-
-                       r = lookup_template_class (DECL_NAME (arg), 
-                                                  argvec, in_decl, 
-                                                  DECL_CONTEXT (arg),
-                                                  /*entering_scope=*/0);
-                       return cp_build_qualified_type_real (r, 
-                                                            TYPE_QUALS (t),
-                                                            complain);
-                     }
-                   else
-                     /* We are processing a template argument list.  */ 
-                     return arg;
+                   /* We can get a TEMPLATE_TEMPLATE_PARM here when 
+                      we are resolving nested-types in the signature of 
+                      a member function templates.
+                      Otherwise ARG is a TEMPLATE_DECL and is the real 
+                      template to be instantiated.  */
+                   if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+                     arg = TYPE_NAME (arg);
+
+                   r = lookup_template_class (arg, 
+                                              argvec, in_decl, 
+                                              DECL_CONTEXT (arg),
+                                              /*entering_scope=*/0);
+                   return cp_build_qualified_type_real (r, 
+                                                        TYPE_QUALS (t),
+                                                        complain);
                  }
                else
+                 /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
                  return arg;
              }
          }
@@ -6335,25 +6327,34 @@ tsubst (t, args, complain, in_decl)
          {
          case TEMPLATE_TYPE_PARM:
          case TEMPLATE_TEMPLATE_PARM:
-           r = copy_node (t);
-           TEMPLATE_TYPE_PARM_INDEX (r)
-             = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
-                                           r, levels);
-           TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
-           TYPE_MAIN_VARIANT (r) = r;
-           TYPE_POINTER_TO (r) = NULL_TREE;
-           TYPE_REFERENCE_TO (r) = NULL_TREE;
-
-           if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
-               && TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
+         case BOUND_TEMPLATE_TEMPLATE_PARM:
+           if (CP_TYPE_QUALS (t))
              {
-               tree argvec = tsubst (TYPE_TI_ARGS (t), args,
-                                     complain, in_decl); 
-               if (argvec == error_mark_node)
-                 return error_mark_node;
+               r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
+               r = cp_build_qualified_type_real (r, CP_TYPE_QUALS (t),
+                                                 complain);
+             }
+           else
+             {
+               r = copy_node (t);
+               TEMPLATE_TYPE_PARM_INDEX (r)
+                 = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
+                                               r, levels);
+               TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
+               TYPE_MAIN_VARIANT (r) = r;
+               TYPE_POINTER_TO (r) = NULL_TREE;
+               TYPE_REFERENCE_TO (r) = NULL_TREE;
+
+               if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
+                 {
+                   tree argvec = tsubst (TYPE_TI_ARGS (t), args,
+                                         complain, in_decl); 
+                   if (argvec == error_mark_node)
+                     return error_mark_node;
 
-               TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
-                 = tree_cons (TYPE_NAME (t), argvec, NULL_TREE);
+                   TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
+                     = tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
+                 }
              }
            break;
 
@@ -6478,8 +6479,10 @@ tsubst (t, args, complain, in_decl)
          r = build_reference_type (type);
        r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
 
-       /* Will this ever be needed for TYPE_..._TO values?  */
-       layout_type (r);
+       if (r != error_mark_node)
+         /* Will this ever be needed for TYPE_..._TO values?  */
+         layout_type (r);
+       
        return r;
       }
     case OFFSET_TYPE:
@@ -7044,6 +7047,7 @@ tsubst_copy (t, args, complain, in_decl)
     case INTEGER_TYPE:
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_PARM_INDEX:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
@@ -7057,8 +7061,13 @@ tsubst_copy (t, args, complain, in_decl)
 
     case IDENTIFIER_NODE:
       if (IDENTIFIER_TYPENAME_P (t))
-       return (build_typename_overload
-               (tsubst (TREE_TYPE (t), args, complain, in_decl)));
+       {
+         tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+         if (flag_new_abi)
+           return mangle_conv_op_name_for_type (new_type);
+         else
+           return (build_typename_overload (new_type));
+       }
       else
        return t;
 
@@ -7073,7 +7082,7 @@ tsubst_copy (t, args, complain, in_decl)
       }
 
     case VA_ARG_EXPR:
-      return build_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
+      return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
                                        in_decl),
                           tsubst (TREE_TYPE (t), args, complain, in_decl));
 
@@ -7112,14 +7121,19 @@ tsubst_expr (t, args, complain, in_decl)
       break;
 
     case CTOR_INITIALIZER:
-      prep_stmt (t);
-      current_member_init_list
-       = tsubst_expr_values (TREE_OPERAND (t, 0), args);
-      current_base_init_list
-       = tsubst_expr_values (TREE_OPERAND (t, 1), args);
-      setup_vtbl_ptr ();
-      tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
-      break;
+      {
+       tree member_init_list;
+       tree base_init_list;
+
+       prep_stmt (t);
+       member_init_list
+         = tsubst_initializer_list (TREE_OPERAND (t, 0), args);
+       base_init_list
+         = tsubst_initializer_list (TREE_OPERAND (t, 1), args);
+       setup_vtbl_ptr (member_init_list, base_init_list);
+       tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
+       break;
+      }
 
     case RETURN_STMT:
       prep_stmt (t);
@@ -7147,17 +7161,23 @@ tsubst_expr (t, args, complain, in_decl)
            init = DECL_INITIAL (decl);
            decl = tsubst (decl, args, complain, in_decl);
            init = tsubst_expr (init, args, complain, in_decl);
-           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
-              all that needs to be done, that's the right thing to
-              do.  */
-           if (TREE_CODE (decl) == VAR_DECL)
-             DECL_TEMPLATE_INSTANTIATED (decl) = 1;
-           maybe_push_decl (decl);
-           cp_finish_decl (decl, init, NULL_TREE, 0);
+           if (decl != error_mark_node)
+             {
+                if (TREE_CODE (decl) != TYPE_DECL)
+                  /* Make sure the type is instantiated now. */
+                  complete_type (TREE_TYPE (decl));
+               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
+                  all that needs to be done, that's the right thing to
+                  do.  */
+               if (TREE_CODE (decl) == VAR_DECL)
+                 DECL_TEMPLATE_INSTANTIATED (decl) = 1;
+               maybe_push_decl (decl);
+               cp_finish_decl (decl, init, NULL_TREE, 0);
+             }
          }
        return decl;
       }
@@ -7177,7 +7197,7 @@ tsubst_expr (t, args, complain, in_decl)
        tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
        finish_for_expr (tmp, stmt);
        tsubst_expr (FOR_BODY (t), args, complain, in_decl);
-       finish_for_stmt (tmp, stmt);
+       finish_for_stmt (stmt);
       }
       break;
 
@@ -7265,14 +7285,15 @@ tsubst_expr (t, args, complain, in_decl)
        val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
        finish_switch_cond (val, stmt);
        tsubst_expr (SWITCH_BODY (t), args, complain, in_decl);
-       finish_switch_stmt (val, stmt);
+       finish_switch_stmt (stmt);
       }
       break;
 
     case CASE_LABEL:
       prep_stmt (t);
       finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl),
-                        tsubst_expr (CASE_HIGH (t), args, complain, in_decl));
+                        tsubst_expr (CASE_HIGH (t), args, complain,
+                                     in_decl));
       break;
 
     case LABEL_STMT:
@@ -7420,6 +7441,7 @@ tree
 instantiate_template (tmpl, targ_ptr)
      tree tmpl, targ_ptr;
 {
+  tree clone;
   tree fndecl;
   tree gen_tmpl;
   tree spec;
@@ -7440,25 +7462,23 @@ instantiate_template (tmpl, targ_ptr)
   if (spec != NULL_TREE)
     return spec;
 
-  if (DECL_TEMPLATE_INFO (tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
+  gen_tmpl = most_general_template (tmpl);
+  if (tmpl != gen_tmpl)
     {
       /* The TMPL is a partial instantiation.  To get a full set of
         arguments we must add the arguments used to perform the
         partial instantiation.  */
       targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl),
                                              targ_ptr);
-      gen_tmpl = most_general_template (tmpl);
 
       /* Check to see if we already have this specialization.  */
       spec = retrieve_specialization (gen_tmpl, targ_ptr);
       if (spec != NULL_TREE)
        return spec;
     }
-  else
-    gen_tmpl = tmpl;
 
   len = DECL_NTPARMS (gen_tmpl);
-  inner_args = innermost_args (targ_ptr);
+  inner_args = INNERMOST_TEMPLATE_ARGS (targ_ptr);
   i = len;
   while (i--)
     {
@@ -7485,6 +7505,13 @@ instantiate_template (tmpl, targ_ptr)
   if (flag_external_templates)
     add_pending_template (fndecl);
 
+  /* If we've just instantiated the main entry point for a function,
+     instantiate all the alternate entry points as well.  */
+  for (clone = TREE_CHAIN (gen_tmpl);
+       clone && DECL_CLONED_FUNCTION_P (clone);
+       clone = TREE_CHAIN (clone))
+    instantiate_template (clone, targ_ptr);
+
   return fndecl;
 }
 
@@ -7502,7 +7529,7 @@ overload_template_name (type)
     return;
 
   decl = build_decl (TYPE_DECL, id, type);
-  SET_DECL_ARTIFICIAL (decl);
+  DECL_ARTIFICIAL (decl) = 1;
   pushdecl_class_level (decl);
 }
 
@@ -7642,7 +7669,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
    sections are symmetric.  PARM is the type of a function parameter
    or the return type of the conversion function.  ARG is the type of
    the argument passed to the call, or the type of the value
-   intialized with the result of the conversion function.  */
+   initialized with the result of the conversion function.  */
 
 static void
 maybe_adjust_types_for_deduction (strict, parm, arg)
@@ -7711,7 +7738,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
     *parm = TREE_TYPE (*parm);
 }
 
-/* Like type_unfication.
+/* Like type_unification.
 
    If SUBR is 1, we're being called recursively (to unify the
    arguments of a function or method parameter of a function
@@ -7827,13 +7854,8 @@ type_unification_real (tparms, targs, parms, args, subr,
       if (!subr)
        maybe_adjust_types_for_deduction (strict, &parm, &arg);
 
-      switch (unify (tparms, targs, parm, arg, sub_strict))
-       {
-       case 0:
-         break;
-       case 1:
-         return 1;
-       }
+      if (unify (tparms, targs, parm, arg, sub_strict))
+        return 1;
     }
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
@@ -8021,6 +8043,52 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
   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 (targs, parms, args)
+     tree targs, parms, args;
+{
+  int i;
+  int nparms = TREE_VEC_LENGTH (parms);
+  tree new_parms = tsubst (parms, add_outermost_template_args (args, targs),
+                          /*complain=*/0, NULL_TREE);
+  if (new_parms == error_mark_node)
+    return 1;
+
+  args = INNERMOST_TEMPLATE_ARGS (args);
+
+  for (i = 0; i < nparms; i++)
+    {
+      tree parm = TREE_VEC_ELT (new_parms, i);
+      tree arg = TREE_VEC_ELT (args, i);
+
+      /* In case we are deducing from a function argument of a function
+        templates, some parameters may not be deduced yet.  So we
+        make sure that only fully substituted elements of PARM are
+        compared below.  */
+
+      if (!uses_template_parms (parm) && !template_args_equal (parm, arg))
+       return 1;
+    }
+  return 0;
+}
+
 /* 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
@@ -8033,7 +8101,6 @@ try_class_unification (tparms, targs, parm, arg)
      tree parm;
      tree arg;
 {
-  int i;
   tree copy_of_targs;
 
   if (!CLASSTYPE_TEMPLATE_INFO (arg)
@@ -8071,18 +8138,17 @@ try_class_unification (tparms, targs, parm, arg)
      with S<I, I, I>.  If we kept the already deduced knowledge, we
      would reject the possibility I=1.  */
   copy_of_targs = make_tree_vec (TREE_VEC_LENGTH (targs));
-  i = unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),
-            CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE);
   
   /* If unification failed, we're done.  */
-  if (i != 0)
+  if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),
+            CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE))
     return NULL_TREE;
-  else
-    return arg;
+
+  return arg;
 }
 
 /* Subroutine of get_template_base.  RVAL, if non-NULL, is a base we
-   have alreay discovered to be satisfactory.  ARG_BINFO is the binfo
+   have already discovered to be satisfactory.  ARG_BINFO is the binfo
    for the base class of ARG that we are currently examining.  */
 
 static tree
@@ -8229,7 +8295,7 @@ check_cv_quals_for_unify (strict, arg, parm)
 }
 
 /* Takes parameters as for type_unification.  Returns 0 if the
-   type deduction suceeds, 1 otherwise.  The parameter STRICT is a
+   type deduction succeeds, 1 otherwise.  The parameter STRICT is a
    bitwise or of the following flags:
 
      UNIFY_ALLOW_NONE:
@@ -8298,6 +8364,7 @@ unify (tparms, targs, parm, arg, strict)
 
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
 
       if (TEMPLATE_TYPE_LEVEL (parm)
@@ -8317,53 +8384,61 @@ unify (tparms, targs, parm, arg, strict)
              && TREE_CODE (tparm) != TEMPLATE_DECL))
        return 1;
 
-      if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
+      if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
        {
-         if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
-           {
-             /* We arrive here when PARM does not involve template 
-                specialization.  */
+         /* ARG must be constructed from a template class.  */
+         if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
+           return 1;
 
-             /* ARG must be constructed from a template class.  */
-             if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
-               return 1;
+         {
+           tree parmtmpl = TYPE_TI_TEMPLATE (parm);
+           tree parmvec = TYPE_TI_ARGS (parm);
+           tree argvec = CLASSTYPE_TI_ARGS (arg);
+           tree argtmplvec
+             = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
+           int i;
 
-             {
-               tree parmtmpl = TYPE_TI_TEMPLATE (parm);
-               tree parmvec = TYPE_TI_ARGS (parm);
-               tree argvec = CLASSTYPE_TI_ARGS (arg);
-               tree argtmplvec
-                 = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_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.  */
-
-               if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
-                   == error_mark_node)
-                 return 1;
+           /* 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.  */
+
+           if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
+               == error_mark_node)
+             return 1;
          
-               /* Deduce arguments T, i from TT<T> or TT<i>.  
-                  We check each element of PARMVEC and ARGVEC individually
-                  rather than the whole TREE_VEC since they can have
-                  different number of elements.  */
+           /* Deduce arguments T, i from TT<T> or TT<i>.  
+              We check each element of PARMVEC and ARGVEC individually
+              rather than the whole TREE_VEC since they can have
+              different number of elements.  */
 
-               for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
-                 {
-                   tree t = TREE_VEC_ELT (parmvec, i);
+           for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
+             {
+               tree t = TREE_VEC_ELT (parmvec, i);
 
-                   if (unify (tparms, targs, t, 
-                              TREE_VEC_ELT (argvec, i), 
-                              UNIFY_ALLOW_NONE))
-                     return 1;
-                 }
+               if (unify (tparms, targs, t, 
+                          TREE_VEC_ELT (argvec, i), 
+                          UNIFY_ALLOW_NONE))
+                 return 1;
              }
-             arg = CLASSTYPE_TI_TEMPLATE (arg);
-           }
+         }
+         arg = CLASSTYPE_TI_TEMPLATE (arg);
+
+         /* Fall through to deduce template name.  */
+       }
+
+      if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+         || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+       {
+         /* Deduce template name TT from TT, TT<>, TT<T> and TT<i>.  */
+
+         /* Simple cases: Value already set, does match or doesn't.  */
+         if (targ != NULL_TREE && template_args_equal (targ, arg))
+           return 0;
+         else if (targ)
+           return 1;
        }
       else
        {
@@ -8384,13 +8459,13 @@ unify (tparms, targs, parm, arg, strict)
                                          /*complain=*/0);
          if (arg == error_mark_node)
            return 1;
-       }
 
-      /* Simple cases: Value already set, does match or doesn't.  */
-      if (targ != NULL_TREE && same_type_p (targ, arg))
-       return 0;
-      else if (targ)
-       return 1;
+         /* Simple cases: Value already set, does match or doesn't.  */
+         if (targ != NULL_TREE && same_type_p (targ, arg))
+           return 0;
+         else if (targ)
+           return 1;
+       }
 
       /* Make sure that ARG is not a variable-sized array.  (Note that
         were talking about variable-sized arrays (like `int[n]'),
@@ -8438,8 +8513,10 @@ unify (tparms, targs, parm, arg, strict)
         parameter-list and, if the corresponding template-argument is
         deduced, the template-argument type shall match the type of the
         template-parameter exactly, except that a template-argument
-        deduced from an array bound may be of any integral type.  */
-      if (same_type_p (TREE_TYPE (arg), TREE_TYPE (parm)))
+        deduced from an array bound may be of any integral type. 
+        The non-type parameter might use already deduced type parameters.  */
+      if (same_type_p (TREE_TYPE (arg),
+                       tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE)))
        /* OK */;
       else if ((strict & UNIFY_ALLOW_INTEGER)
               && (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
@@ -8504,6 +8581,7 @@ unify (tparms, targs, parm, arg, strict)
 
     case REAL_TYPE:
     case COMPLEX_TYPE:
+    case VECTOR_TYPE:
     case INTEGER_TYPE:
     case BOOLEAN_TYPE:
     case VOID_TYPE:
@@ -8548,7 +8626,7 @@ unify (tparms, targs, parm, arg, strict)
          return 1;
        if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))
          return 1;
-       for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
+       for (i = 0; i < TREE_VEC_LENGTH (parm); ++i)
          if (unify (tparms, targs,
                     TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
                     UNIFY_ALLOW_NONE))
@@ -8607,7 +8685,7 @@ unify (tparms, targs, parm, arg, strict)
               Then, we should unify `int' and `U'.  */
            t = arg;
          else
-           /* There's no chance of unication succeeding.  */
+           /* There's no chance of unification succeeding.  */
            return 1;
 
          return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
@@ -8669,25 +8747,33 @@ unify (tparms, targs, parm, arg, strict)
 
     default:
       if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))
-       /* We're looking at an expression.  This can happen with
-          something like: 
+       {
+
+         /* We're looking at an expression.  This can happen with
+            something like: 
           
-            template <int I>
-            void foo(S<I>, S<I + 2>);
+              template <int I>
+              void foo(S<I>, S<I + 2>);
 
-          This is a "nondeduced context":
+            This is a "nondeduced context":
 
-            [deduct.type]
+              [deduct.type]
           
-            The nondeduced contexts are:
+              The nondeduced contexts are:
 
-            --A type that is a template-id in which one or more of
-              the template-arguments is an expression that references
-              a template-parameter.  
+              --A type that is a template-id in which one or more of
+                the template-arguments is an expression that references
+                a template-parameter.  
 
-          In these cases, we assume deduction succeeded, but don't
-          actually infer any unifications.  */
-       return 0;
+            In these cases, we assume deduction succeeded, but don't
+            actually infer any unifications.  */
+
+         if (!uses_template_parms (parm)
+             && !template_args_equal (parm, arg))
+           return 1;
+         else
+           return 0;
+       }
       else
        sorry ("use of `%s' in template type unification",
               tree_code_name [(int) TREE_CODE (parm)]);
@@ -8710,6 +8796,14 @@ mark_decl_instantiated (result, extern_p)
        set correctly by tsubst.  */
     TREE_PUBLIC (result) = 1;
 
+  /* We used to set this unconditionally; we moved that to
+     do_decl_instantiation so it wouldn't get set on members of
+     explicit class template instantiations.  But we still need to set
+     it here for the 'extern template' case in order to suppress
+     implicit instantiations.  */
+  if (extern_p)
+    SET_DECL_EXPLICIT_INSTANTIATION (result);
+
   if (! extern_p)
     {
       DECL_INTERFACE_KNOWN (result) = 1;
@@ -8885,22 +8979,24 @@ get_class_bindings (tparms, parms, args)
   int i, ntparms = TREE_VEC_LENGTH (tparms);
   tree vec = make_tree_vec (ntparms);
 
-  args = innermost_args (args);
-
-  if (unify (tparms, vec, parms, args, UNIFY_ALLOW_NONE))
+  if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args),
+            UNIFY_ALLOW_NONE))
     return NULL_TREE;
 
   for (i =  0; i < ntparms; ++i)
     if (! TREE_VEC_ELT (vec, i))
       return NULL_TREE;
 
+  if (verify_class_unification (vec, parms, args))
+    return NULL_TREE;
+
   return vec;
 }
 
 /* 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.  EXPLICIT_ARGS is any template arguments explicity
+   template itself.  EXPLICIT_ARGS is any template arguments explicitly
    mentioned in a template-id.  If there is no most specialized
    template, error_mark_node is returned.  If there are no templates
    at all, NULL_TREE is returned.  */
@@ -8970,7 +9066,9 @@ most_specialized (fns, decl, explicit_args)
 }
 
 /* If DECL is a specialization of some template, return the most
-   general such template.  For example, given:
+   general such template.  Otherwise, returns NULL_TREE.
+
+   For example, given:
 
      template <class T> struct S { template <class U> void f(U); };
 
@@ -8987,14 +9085,37 @@ tree
 most_general_template (decl)
      tree decl;
 {
-  while (DECL_TEMPLATE_INFO (decl)
-        && !(TREE_CODE (decl) == TEMPLATE_DECL
-             && DECL_TEMPLATE_SPECIALIZATION (decl))
-        /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or
-           IDENTIFIER_NODE in some cases.  (See cp-tree.h for
-           details.)  */
-        && TREE_CODE (DECL_TI_TEMPLATE (decl)) == TEMPLATE_DECL)
-    decl = DECL_TI_TEMPLATE (decl);
+  /* If DECL is a FUNCTION_DECL, find the TEMPLATE_DECL of which it is
+     an immediate specialization.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      if (DECL_TEMPLATE_INFO (decl)) {
+       decl = DECL_TI_TEMPLATE (decl);
+
+       /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE for a
+          template friend.  */
+       if (TREE_CODE (decl) != TEMPLATE_DECL)
+         return NULL_TREE;
+      } else
+       return NULL_TREE;
+    }
+
+  /* Look for more and more general templates.  */
+  while (DECL_TEMPLATE_INFO (decl))
+    {
+      /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or IDENTIFIER_NODE
+        in some cases.  (See cp-tree.h for details.)  */
+      if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
+       break;
+
+      /* Stop if we run into an explicitly specialized class template.  */
+      if (!DECL_NAMESPACE_SCOPE_P (decl)
+         && DECL_CONTEXT (decl)
+         && CLASSTYPE_TEMPLATE_SPECIALIZATION (DECL_CONTEXT (decl)))
+       break;
+
+      decl = DECL_TI_TEMPLATE (decl);
+    }
 
   return decl;
 }
@@ -9020,7 +9141,7 @@ most_specialized_class (tmpl, args)
        = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args);
       if (spec_args)
        {
-         list = decl_tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list);
+         list = tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list);
          TREE_TYPE (list) = TREE_TYPE (t);
        }
     }
@@ -9069,7 +9190,7 @@ do_decl_instantiation (declspecs, declarator, storage)
   int extern_p = 0;
 
   if (!decl)
-    /* An error ocurred, for which grokdeclarator has already issued
+    /* An error occurred, for which grokdeclarator has already issued
        an appropriate message.  */
     return;
   else if (! DECL_LANG_SPECIFIC (decl))
@@ -9127,7 +9248,7 @@ do_decl_instantiation (declspecs, declarator, storage)
         We check DECL_INTERFACE_KNOWN so as not to complain when the first
         instantiation was `extern' and the second is not, and EXTERN_P for
         the opposite case.  If -frepo, chances are we already got marked
-        as an explicit instantion because of the repo file.  */
+        as an explicit instantiation because of the repo file.  */
       if (DECL_INTERFACE_KNOWN (result) && !extern_p && !flag_use_repository)
        cp_pedwarn ("duplicate explicit instantiation of `%#D'", result);
 
@@ -9185,9 +9306,15 @@ mark_class_instantiated (t, extern_p)
     }
 }     
 
+/* Perform an explicit instantiation of template class T.  STORAGE, if
+   non-null, is the RID for extern, inline or static.  COMPLAIN is
+   non-zero if this is called from the parser, zero if called recursively,
+   since the standard is unclear (as detailed below).  */
 void
-do_type_instantiation (t, storage)
+do_type_instantiation (t, storage, complain)
      tree t, storage;
+     int complain;
 {
   int extern_p = 0;
   int nomem_p = 0;
@@ -9211,8 +9338,9 @@ do_type_instantiation (t, storage)
 
   if (!COMPLETE_TYPE_P (t))
     {
-      cp_error ("explicit instantiation of `%#T' before definition of template",
-               t);
+      if (complain)
+       cp_error ("explicit instantiation of `%#T' before definition of template",
+                 t);
       return;
     }
 
@@ -9242,8 +9370,11 @@ do_type_instantiation (t, storage)
 
         No program shall both explicitly instantiate and explicitly
         specialize a template.  */
-      cp_error ("explicit instantiation of `%#T' after", t);
-      cp_error_at ("explicit specialization here", t);
+      if (complain)
+       {
+         cp_error ("explicit instantiation of `%#T' after", t);
+         cp_error_at ("explicit specialization here", t);
+       }
       return;
     }
   else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
@@ -9257,7 +9388,8 @@ do_type_instantiation (t, storage)
         was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
         are we already got marked as an explicit instantion because of the
         repo file.  All these cases are OK.  */
-      if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository)
+      if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
+         && complain)
        cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
       
       /* If we've already instantiated the template, just return now.  */
@@ -9287,7 +9419,7 @@ do_type_instantiation (t, storage)
 
        Of course, we can't instantiate member template classes, since
        we don't have any arguments for them.  Note that the standard
-       is unclear on whether the instatiation of the members are
+       is unclear on whether the instantiation of the members are
        *explicit* instantiations or not.  We choose to be generous,
        and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow
        the explicit instantiation of a class where some of the members
@@ -9316,7 +9448,7 @@ do_type_instantiation (t, storage)
     for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
       if (IS_AGGR_TYPE (TREE_VALUE (tmp))
          && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))
-       do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage);
+       do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage, 0);
   }
 }
 
@@ -9345,10 +9477,13 @@ regenerate_decl_from_template (decl, tmpl)
      tree decl;
      tree tmpl;
 {
+  /* The most general version of TMPL.  */
+  tree gen_tmpl;
+  /* The arguments used to instantiate DECL, from the most general
+     template.  */
   tree args;
   tree code_pattern;
   tree new_decl;
-  tree gen_tmpl;
   int unregistered;
 
   args = DECL_TI_ARGS (decl);
@@ -9404,6 +9539,7 @@ regenerate_decl_from_template (decl, tmpl)
   DECL_TI_TEMPLATE (new_decl) = DECL_TI_TEMPLATE (decl);
   DECL_ASSEMBLER_NAME (new_decl) = DECL_ASSEMBLER_NAME (decl);
   DECL_RTL (new_decl) = DECL_RTL (decl);
+  DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl);
 
   /* Call duplicate decls to merge the old and new declarations.  */
   duplicate_decls (new_decl, decl);
@@ -9443,7 +9579,7 @@ instantiate_decl (d, defer_ok)
 
   if (DECL_TEMPLATE_INSTANTIATED (d))
     /* D has already been instantiated.  It might seem reasonable to
-       check whether or not D is an explict instantiation, and, if so,
+       check whether or not D is an explicit instantiation, and, if so,
        stop here.  But when an explicit instantiation is deferred
        until the end of the compilation, DECL_EXPLICIT_INSTANTIATION
        is set, even though we still need to do the instantiation.  */
@@ -9463,6 +9599,8 @@ instantiate_decl (d, defer_ok)
   if (! push_tinst_level (d))
     return d;
 
+  timevar_push (TV_PARSE);
+
   /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
      for the instantiation.  This is not always the most general
      template.  Consider, for example:
@@ -9474,32 +9612,30 @@ instantiate_decl (d, defer_ok)
      and an instantiation of S<double>::f<int>.  We want TD to be the
      specialization S<T>::f<int>, not the more general S<T>::f<U>.  */
   td = tmpl;
-  for (td = tmpl;
-       /* An instantiation cannot have a definition, so we need a
-         more general template.  */
-       DECL_TEMPLATE_INSTANTIATION (td)
-        /* We must also deal with friend templates.  Given:
-
-             template <class T> struct S { 
-               template <class U> friend void f() {};
-             };
-        
-           S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
-           so far as the language is concerned, but that's still
-           where we get the pattern for the instantiation from.  On
-           ther hand, if the definition comes outside the class, say:
-
-             template <class T> struct S { 
-               template <class U> friend void f();
-              };
-             template <class U> friend void f() {}
-
-           we don't need to look any further.  That's what the check for
-           DECL_INITIAL is for.  */
-       || (TREE_CODE (d) == FUNCTION_DECL
-           && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td)
-           && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td)));
-       )
+  while (/* An instantiation cannot have a definition, so we need a
+           more general template.  */
+        DECL_TEMPLATE_INSTANTIATION (td)
+          /* We must also deal with friend templates.  Given:
+
+               template <class T> struct S { 
+                 template <class U> friend void f() {};
+               };
+
+             S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
+             so far as the language is concerned, but that's still
+             where we get the pattern for the instantiation from.  On
+             other hand, if the definition comes outside the class, say:
+
+               template <class T> struct S { 
+                 template <class U> friend void f();
+               };
+               template <class U> friend void f() {}
+
+             we don't need to look any further.  That's what the check for
+             DECL_INITIAL is for.  */
+         || (TREE_CODE (d) == FUNCTION_DECL
+             && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td)
+             && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td))))
     {
       /* The present template, TD, should not be a definition.  If it
         were a definition, we should be using it!  Note that we
@@ -9549,12 +9685,6 @@ instantiate_decl (d, defer_ok)
        import_export_decl (d);
     }
 
-  /* Reject all external templates except inline functions.  */
-  if (DECL_INTERFACE_KNOWN (d)
-      && ! DECL_NOT_REALLY_EXTERN (d)
-      && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d)))
-    goto out;
-
   /* We need to set up DECL_INITIAL regardless of pattern_defined if
      the variable is a static const initialized in the class body.  */
   if (TREE_CODE (d) == VAR_DECL 
@@ -9562,6 +9692,11 @@ instantiate_decl (d, defer_ok)
       && DECL_INITIAL (d) == NULL_TREE
       && DECL_INITIAL (code_pattern) != NULL_TREE)
     ;
+  /* Reject all external templates except inline functions.  */
+  else if (DECL_INTERFACE_KNOWN (d)
+          && ! DECL_NOT_REALLY_EXTERN (d)
+          && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (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.  */
@@ -9614,8 +9749,13 @@ instantiate_decl (d, defer_ok)
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
     {
+      htab_t saved_local_specializations;
+
+      /* Save away the current list, in case we are instantiating one
+        template from within the body of another.  */
+      saved_local_specializations = local_specializations;
+
       /* Set up the list of local specializations.  */
-      my_friendly_assert (local_specializations == NULL, 20000422);
       local_specializations = htab_create (37, 
                                           htab_hash_pointer,
                                           htab_eq_pointer,
@@ -9623,11 +9763,10 @@ instantiate_decl (d, defer_ok)
 
       /* Set up context.  */
       start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
-      store_parm_decls ();
 
       /* We already set up __FUNCTION__, etc., so we don't want to do
         it again now.  */
-      current_function_name_declared = 1;
+      function_name_declared_p = 1;
 
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
@@ -9635,7 +9774,7 @@ instantiate_decl (d, defer_ok)
 
       /* We don't need the local specializations any more.  */
       htab_delete (local_specializations);
-      local_specializations = NULL;
+      local_specializations = saved_local_specializations;
 
       /* Finish the function.  */
       expand_body (finish_function (0));
@@ -9651,6 +9790,8 @@ out:
   pop_from_top_level ();
   pop_tinst_level ();
 
+  timevar_pop (TV_PARSE);
+
   return d;
 }
 
@@ -9671,11 +9812,9 @@ instantiate_pending_templates ()
       t = &pending_templates;
       while (*t)
        {
-         tree srcloc = TREE_PURPOSE (*t);
          tree instantiation = TREE_VALUE (*t);
 
-         input_filename = SRCLOC_FILE (srcloc);
-         lineno = SRCLOC_LINE (srcloc);
+         reopen_tinst_level (TREE_PURPOSE (*t));
 
          if (TYPE_P (instantiation))
            {
@@ -9726,6 +9865,8 @@ instantiate_pending_templates ()
              else 
                t = &TREE_CHAIN (*t);
            }
+         tinst_depth = 0;
+         current_tinst_level = NULL_TREE;
        }
       template_tail = t;
 
@@ -9764,12 +9905,13 @@ instantiate_pending_templates ()
   return instantiated_something;
 }
 
-/* Substitute ARGVEC into T, which is a TREE_LIST.  In particular, it
-   is an initializer list: the TREE_PURPOSEs are DECLs, and the
-   TREE_VALUEs are initializer values.  Used by instantiate_decl.  */
+/* Substitute ARGVEC into T, which is a list of initializers for
+   either base class or a non-static data member.  The TREE_PURPOSEs
+   are DECLs, and the TREE_VALUEs are the initializer values.  Used by
+   instantiate_decl.  */
 
 static tree
-tsubst_expr_values (t, argvec)
+tsubst_initializer_list (t, argvec)
      tree t, argvec;
 {
   tree first = NULL_TREE;
@@ -9777,42 +9919,27 @@ tsubst_expr_values (t, argvec)
 
   for (; t; t = TREE_CHAIN (t))
     {
-      tree pur = tsubst_copy (TREE_PURPOSE (t), argvec,
-                             /*complain=*/1, NULL_TREE);
-      tree val = tsubst_expr (TREE_VALUE (t), argvec, /*complain=*/1, 
-                             NULL_TREE);
-      *p = build_tree_list (pur, val);
-      p = &TREE_CHAIN (*p);
-    }
-  return first;
-}
-
-/* D is an undefined function declaration in the presence of templates with
-   the same name, listed in FNS.  If one of them can produce D as an
-   instantiation, remember this so we can instantiate it at EOF if D has
-   not been defined by that time.  */
+      tree decl;
+      tree init;
+      tree val;
 
-void
-add_maybe_template (d, fns)
-     tree d, fns;
-{
-  tree t;
+      decl = tsubst_copy (TREE_PURPOSE (t), argvec, /*complain=*/1,
+                         NULL_TREE);
+      init = tsubst_expr (TREE_VALUE (t), argvec, /*complain=*/1,
+                         NULL_TREE);
 
-  if (DECL_MAYBE_TEMPLATE (d))
-    return;
+      if (!init)
+       ;
+      else if (TREE_CODE (init) == TREE_LIST)
+       for (val = init; val; val = TREE_CHAIN (val))
+         TREE_VALUE (val) = convert_from_reference (TREE_VALUE (val));
+      else
+       init = convert_from_reference (init);
 
-  t = most_specialized (fns, d, NULL_TREE);
-  if (! t)
-    return;
-  if (t == error_mark_node)
-    {
-      cp_error ("ambiguous template instantiation for `%D'", d);
-      return;
+      *p = build_tree_list (decl, init);
+      p = &TREE_CHAIN (*p);
     }
-
-  *maybe_template_tail = tree_cons (t, d, NULL_TREE);
-  maybe_template_tail = &TREE_CHAIN (*maybe_template_tail);
-  DECL_MAYBE_TEMPLATE (d) = 1;
+  return first;
 }
 
 /* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL.  */
@@ -9859,6 +9986,82 @@ tsubst_enum (tag, newtag, args)
     }
 
   finish_enum (newtag);
+  DECL_SOURCE_LINE (TYPE_NAME (newtag)) = DECL_SOURCE_LINE (TYPE_NAME (tag));
+  DECL_SOURCE_FILE (TYPE_NAME (newtag)) = DECL_SOURCE_FILE (TYPE_NAME (tag));
+}
+
+/* DECL is a FUNCTION_DECL that is a template specialization.  Return
+   its type -- but without substituting the innermost set of template
+   arguments.  So, innermost set of template parameters will appear in
+   the type.  If CONTEXTP is non-NULL, then the partially substituted
+   DECL_CONTEXT (if any) will also be filled in.  Similarly, TPARMSP
+   will be filled in with the substituted template parameters, if it
+   is non-NULL.  */
+
+tree 
+get_mostly_instantiated_function_type (decl, contextp, tparmsp)
+     tree decl;
+     tree *contextp;
+     tree *tparmsp;
+{
+  tree context = NULL_TREE;
+  tree fn_type;
+  tree tmpl;
+  tree targs;
+  tree tparms;
+  int parm_depth;
+
+  tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
+  targs = DECL_TI_ARGS (decl);
+  tparms = DECL_TEMPLATE_PARMS (tmpl);
+  parm_depth = TMPL_PARMS_DEPTH (tparms);
+
+  /* There should be as many levels of arguments as there are levels
+     of parameters.  */
+  my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0);
+
+  fn_type = TREE_TYPE (tmpl);
+  if (DECL_STATIC_FUNCTION_P (decl))
+    context = DECL_CONTEXT (decl);
+
+  if (parm_depth == 1)
+    /* No substitution is necessary.  */
+    ;
+  else
+    {
+      int i;
+      tree partial_args;
+
+      /* Replace the innermost level of the TARGS with NULL_TREEs to
+        let tsubst know not to substitute for those parameters.  */
+      partial_args = make_tree_vec (TREE_VEC_LENGTH (targs));
+      for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i)
+       SET_TMPL_ARGS_LEVEL (partial_args, i,
+                            TMPL_ARGS_LEVEL (targs, i));
+      SET_TMPL_ARGS_LEVEL (partial_args,
+                          TMPL_ARGS_DEPTH (targs),
+                          make_tree_vec (DECL_NTPARMS (tmpl)));
+
+      /* Now, do the (partial) substitution to figure out the
+        appropriate function type.  */
+      fn_type = tsubst (fn_type, partial_args, /*complain=*/1, NULL_TREE);
+      if (DECL_STATIC_FUNCTION_P (decl))
+       context = tsubst (context, partial_args, /*complain=*/1, NULL_TREE);
+
+      /* Substitute into the template parameters to obtain the real
+        innermost set of parameters.  This step is important if the
+        innermost set of template parameters contains value
+        parameters whose types depend on outer template parameters.  */
+      TREE_VEC_LENGTH (partial_args)--;
+      tparms = tsubst_template_parms (tparms, partial_args, /*complain=*/1);
+    }
+
+  if (contextp)
+    *contextp = context;
+  if (tparmsp)
+    *tparmsp = tparms;
+
+  return fn_type;
 }
 
 /* Set the DECL_ASSEMBLER_NAME for DECL, which is a FUNCTION_DECL that
@@ -9875,12 +10078,17 @@ set_mangled_name_for_template_decl (decl)
   tree parm_types;
   tree tparms;
   tree targs;
-  tree tmpl;
-  int parm_depth;
 
   my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0);
   my_friendly_assert (DECL_TEMPLATE_INFO (decl) != NULL_TREE, 0);
 
+  /* Under the new ABI, we don't need special machinery.  */
+  if (flag_new_abi)
+    {
+      set_mangled_name_for_decl (decl);
+      return;
+    }
+
   /* The names of template functions must be mangled so as to indicate
      what template is being specialized with what template arguments.
      For example, each of the following three functions must get
@@ -9896,14 +10104,6 @@ set_mangled_name_for_template_decl (decl)
        mangle the name of such an entity.  */
     return;
 
-  tmpl = most_general_template (DECL_TI_TEMPLATE (decl));
-  tparms = DECL_TEMPLATE_PARMS (tmpl);
-  parm_depth = TMPL_PARMS_DEPTH (tparms);
-
-  /* There should be as many levels of arguments as there are levels
-     of parameters.  */
-  my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0);
-
   /* We now compute the PARMS and RET_TYPE to give to
      build_decl_overload_real.  The PARMS and RET_TYPE are the
      parameter and return types of the template, after all but the
@@ -9922,46 +10122,12 @@ set_mangled_name_for_template_decl (decl)
      {int, U}.  Thus, the args that we want to subsitute into the
      return and parameter type for the function are those in TARGS,
      with the innermost level omitted.  */
-  fn_type = TREE_TYPE (tmpl);
-  if (DECL_STATIC_FUNCTION_P (decl))
-    context = DECL_CONTEXT (decl);
-
-  if (parm_depth == 1)
-    /* No substitution is necessary.  */
-    ;
-  else
-    {
-      int i;
-      tree partial_args;
-
-      /* Replace the innermost level of the TARGS with NULL_TREEs to
-        let tsubst know not to subsitute for those parameters.  */
-      partial_args = make_tree_vec (TREE_VEC_LENGTH (targs));
-      for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i)
-       SET_TMPL_ARGS_LEVEL (partial_args, i,
-                            TMPL_ARGS_LEVEL (targs, i));
-      SET_TMPL_ARGS_LEVEL (partial_args,
-                          TMPL_ARGS_DEPTH (targs),
-                          make_tree_vec (DECL_NTPARMS (tmpl)));
-
-      /* Now, do the (partial) substitution to figure out the
-        appropriate function type.  */
-      fn_type = tsubst (fn_type, partial_args, /*complain=*/1, NULL_TREE);
-      if (DECL_STATIC_FUNCTION_P (decl))
-       context = tsubst (context, partial_args, /*complain=*/1, NULL_TREE);
-
-      /* Substitute into the template parameters to obtain the real
-        innermost set of parameters.  This step is important if the
-        innermost set of template parameters contains value
-        parameters whose types depend on outer template parameters.  */
-      TREE_VEC_LENGTH (partial_args)--;
-      tparms = tsubst_template_parms (tparms, partial_args, /*complain=*/1);
-    }
+  fn_type = get_mostly_instantiated_function_type (decl, &context, &tparms);
 
   /* Now, get the innermost parameters and arguments, and figure out
      the parameter and return types.  */
   tparms = INNERMOST_TEMPLATE_PARMS (tparms);
-  targs = innermost_args (targs);
+  targs = INNERMOST_TEMPLATE_ARGS (targs);
   ret_type = TREE_TYPE (fn_type);
   parm_types = TYPE_ARG_TYPES (fn_type);
 
@@ -9984,10 +10150,31 @@ set_mangled_name_for_template_decl (decl)
   my_friendly_assert (TREE_VEC_LENGTH (tparms) == TREE_VEC_LENGTH (targs),
                      0);
 
-  /* Actually set the DCL_ASSEMBLER_NAME.  */
+  /* Actually set the DECL_ASSEMBLER_NAME.  */
   DECL_ASSEMBLER_NAME (decl)
     = build_decl_overload_real (decl, parm_types, ret_type,
                                tparms, targs, 
                                DECL_FUNCTION_MEMBER_P (decl) 
-                               + DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
+                               + DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
+}
+
+/* Return truthvalue if we're processing a template different from
+   the last one involved in diagnostics.  */
+int
+problematic_instantiation_changed ()
+{
+  return last_template_error_tick != tinst_level_tick;
+}
+
+/* Remember current template involved in diagnostics.  */
+void
+record_last_problematic_instantiation ()
+{
+  last_template_error_tick = tinst_level_tick;
+}
+
+tree
+current_instantiation ()
+{
+  return current_tinst_level;
 }