error.c (dump_function_name): Don't let the user see __comp_ctor.
[gcc.git] / gcc / cp / pt.c
index f7e27ce5d020dd7319c3f083717dc255a3799c5d..87d4195b3175da953e435beca08f0cfdad497a58 100644 (file)
@@ -157,6 +157,7 @@ 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));
@@ -638,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 
@@ -746,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)
@@ -1507,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;
@@ -2108,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;
@@ -2195,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);
@@ -2415,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 ();
 
@@ -2701,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
@@ -2808,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;
@@ -2915,7 +2916,7 @@ convert_nontype_argument (type, expr)
            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;
@@ -2980,7 +2981,7 @@ convert_nontype_argument (type, expr)
            if (fn == error_mark_node)
              return error_mark_node;
 
-           if (!TREE_PUBLIC (fn))
+           if (!DECL_EXTERNAL_LINKAGE_P (fn))
              {
                if (really_overloaded_fn (expr))
                  /* Don't issue an error here; we might get a different
@@ -3333,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
@@ -3464,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);
 }
@@ -3534,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)
@@ -3551,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
@@ -3573,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);
@@ -3700,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.  
@@ -3910,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; 
@@ -3925,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);
@@ -4016,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))
@@ -4054,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));
@@ -4393,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)
@@ -4419,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, 
@@ -4620,7 +4630,7 @@ 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 or error_mark_node on
+   Returns an appropriate tsubst'd friend type or error_mark_node on
    failure.  */
 
 static tree
@@ -4906,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)
@@ -4951,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);
@@ -5125,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))
@@ -5195,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++)
     {
@@ -5277,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)
@@ -5580,7 +5590,7 @@ tsubst_decl (t, args, type, in_decl)
                 template <class T> struct S { template <class U> void f(); }
                 template <> template <class U> void S<int>::f(U); 
 
-              Here, we'll be subtituting into the specialization,
+              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.              
@@ -5654,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;
@@ -5778,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));
@@ -6156,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:
@@ -7150,6 +7163,9 @@ tsubst_expr (t, args, complain, in_decl)
            init = tsubst_expr (init, args, complain, in_decl);
            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
@@ -7653,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)
@@ -7722,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
@@ -8027,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
@@ -8039,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)
@@ -8077,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
@@ -8235,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:
@@ -8521,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:
@@ -8624,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),
@@ -8686,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)]);
@@ -8910,22 +8979,24 @@ get_class_bindings (tparms, parms, args)
   int i, ntparms = TREE_VEC_LENGTH (tparms);
   tree vec = make_tree_vec (ntparms);
 
-  args = INNERMOST_TEMPLATE_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.  */
@@ -9119,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))
@@ -9177,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);
 
@@ -9348,7 +9419,7 @@ do_type_instantiation (t, storage, complain)
 
        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
@@ -9508,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.  */
@@ -9553,7 +9624,7 @@ instantiate_decl (d, defer_ok)
              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:
+             other hand, if the definition comes outside the class, say:
 
                template <class T> struct S { 
                  template <class U> friend void f();
@@ -9614,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 
@@ -9627,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.  */
@@ -9872,34 +9942,6 @@ tsubst_initializer_list (t, argvec)
   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.  */
-
-void
-add_maybe_template (d, fns)
-     tree d, fns;
-{
-  tree t;
-
-  if (DECL_MAYBE_TEMPLATE (d))
-    return;
-
-  t = most_specialized (fns, d, NULL_TREE);
-  if (! t)
-    return;
-  if (t == error_mark_node)
-    {
-      cp_error ("ambiguous template instantiation for `%D'", d);
-      return;
-    }
-
-  *maybe_template_tail = tree_cons (t, d, NULL_TREE);
-  maybe_template_tail = &TREE_CHAIN (*maybe_template_tail);
-  DECL_MAYBE_TEMPLATE (d) = 1;
-}
-
 /* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL.  */
 
 static void
@@ -9991,7 +10033,7 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
       tree partial_args;
 
       /* Replace the innermost level of the TARGS with NULL_TREEs to
-        let tsubst know not to subsitute for those parameters.  */
+        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,
@@ -10117,7 +10159,7 @@ set_mangled_name_for_template_decl (decl)
 }
 
 /* Return truthvalue if we're processing a template different from
-   the last one involved in diagnotics.  */
+   the last one involved in diagnostics.  */
 int
 problematic_instantiation_changed ()
 {