OSDN Git Service

cp:
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 8d7f33b..a60cacf 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle parameterized types (templates) for GNU C++.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002  Free Software Foundation, Inc.
    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
    Rewritten by Jason Merrill (jason@cygnus.com).
 
@@ -29,19 +29,17 @@ Boston, MA 02111-1307, USA.  */
 #include "config.h"
 #include "system.h"
 #include "obstack.h"
-
 #include "tree.h"
 #include "flags.h"
 #include "cp-tree.h"
+#include "tree-inline.h"
 #include "decl.h"
 #include "parse.h"
 #include "lex.h"
 #include "output.h"
-#include "defaults.h"
 #include "except.h"
 #include "toplev.h"
 #include "rtl.h"
-#include "defaults.h"
 #include "ggc.h"
 #include "timevar.h"
 
@@ -59,10 +57,7 @@ extern struct obstack permanent_obstack;
    (for a function or static data member), or a TYPE (for a class)
    indicating what we are hoping to instantiate.  */
 static tree pending_templates;
-static tree *template_tail = &pending_templates;
-
-static tree maybe_templates;
-static tree *maybe_template_tail = &maybe_templates;
+static tree last_pending_template;
 
 int processing_template_parmlist;
 static int template_header_count;
@@ -86,6 +81,10 @@ static htab_t local_specializations;
 #define UNIFY_ALLOW_LESS_CV_QUAL 2
 #define UNIFY_ALLOW_DERIVED 4
 #define UNIFY_ALLOW_INTEGER 8
+#define UNIFY_ALLOW_OUTER_LEVEL 16
+#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
+#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
+#define UNIFY_ALLOW_MAX_CORRECTION 128
 
 #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
                             virtual, or a base class of a virtual
@@ -99,7 +98,6 @@ static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
                                   unification_kind_t, int));
 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 ((const char *, tree, tree));
@@ -110,10 +108,10 @@ static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int));
 static void tsubst_enum        PARAMS ((tree, tree, tree));
 static tree add_to_template_args PARAMS ((tree, tree));
 static tree add_outermost_template_args PARAMS ((tree, tree));
-static void maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
+static int maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
                                                    tree*)); 
 static int  type_unification_real PARAMS ((tree, tree, tree, tree,
-                                        int, unification_kind_t, int));
+                                        int, unification_kind_t, int, int));
 static void note_template_header PARAMS ((int));
 static tree maybe_fold_nontype_arg PARAMS ((tree));
 static tree convert_nontype_argument PARAMS ((tree, tree));
@@ -127,14 +125,14 @@ static void push_inline_template_parms_recursive PARAMS ((tree, int));
 static tree retrieve_specialization PARAMS ((tree, tree));
 static tree retrieve_local_specialization PARAMS ((tree));
 static tree register_specialization PARAMS ((tree, tree, tree));
-static tree register_local_specialization PARAMS ((tree, tree));
+static void register_local_specialization PARAMS ((tree, tree));
 static int unregister_specialization PARAMS ((tree, tree));
 static tree reduce_template_parm_level PARAMS ((tree, tree, int));
 static tree build_template_decl PARAMS ((tree, tree));
 static int mark_template_parm PARAMS ((tree, void *));
 static tree tsubst_friend_function PARAMS ((tree, tree));
 static tree tsubst_friend_class PARAMS ((tree, tree));
-static tree get_bindings_real PARAMS ((tree, tree, tree, int));
+static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
 static int template_decl_level PARAMS ((tree));
 static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
 static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
@@ -143,10 +141,9 @@ static tree tsubst_template_parms PARAMS ((tree, tree, int));
 static void regenerate_decl_from_template PARAMS ((tree, tree));
 static tree most_specialized PARAMS ((tree, tree, tree));
 static tree most_specialized_class PARAMS ((tree, tree));
-static void set_mangled_name_for_template_decl PARAMS ((tree));
 static int template_class_depth_real PARAMS ((tree, int));
 static tree tsubst_aggr_type PARAMS ((tree, tree, int, tree, int));
-static tree tsubst_decl PARAMS ((tree, tree, tree, tree));
+static tree tsubst_decl PARAMS ((tree, tree, tree));
 static tree tsubst_arg_types PARAMS ((tree, tree, int, tree));
 static tree tsubst_function_type PARAMS ((tree, tree, int, tree));
 static void check_specialization_scope PARAMS ((void));
@@ -157,6 +154,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));
@@ -164,7 +162,9 @@ static tree determine_specialization PARAMS ((tree, tree, tree *, int));
 static int template_args_equal PARAMS ((tree, tree));
 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));
+static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
+static void copy_default_args_to_explicit_spec PARAMS ((tree));
+static int invalid_nontype_parm_type_p PARAMS ((tree, int));
 
 /* Called once to initialize pt.c.  */
 
@@ -172,7 +172,6 @@ void
 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);
 }
@@ -206,7 +205,7 @@ finish_member_template_decl (decl)
       return NULL_TREE;
     }
   else if (TREE_CODE (decl) == FIELD_DECL)
-    cp_error ("data member `%D' cannot be a member template", decl);
+    error ("data member `%D' cannot be a member template", decl);
   else if (DECL_TEMPLATE_INFO (decl))
     {
       if (!DECL_TEMPLATE_SPECIALIZATION (decl))
@@ -218,7 +217,7 @@ finish_member_template_decl (decl)
        return decl;
     } 
   else
-    cp_error ("invalid member template declaration `%D'", decl);
+    error ("invalid member template declaration `%D'", decl);
 
   return error_mark_node;
 }
@@ -320,7 +319,7 @@ push_inline_template_parms_recursive (parmlist, levels)
 
   ++processing_template_decl;
   current_template_parms
-    = tree_cons (build_int_2 (0, processing_template_decl),
+    = tree_cons (size_int (processing_template_decl),
                 parms, current_template_parms);
   TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
 
@@ -613,7 +612,7 @@ check_specialization_scope ()
      shall be declared in the namespace of which the class template
      is a member.  */
   if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
-    cp_error ("explicit specialization in non-namespace scope `%D'",
+    error ("explicit specialization in non-namespace scope `%D'",
              scope);
 
   /* [temp.expl.spec] 
@@ -625,7 +624,7 @@ check_specialization_scope ()
      explicitly specialize a class member template if its enclosing
      class templates are not explicitly specialized as well.  */
   if (current_template_parms) 
-    cp_error ("enclosing class templates are not explicitly specialized");
+    error ("enclosing class templates are not explicitly specialized");
 }
 
 /* We've just seen template <>. */
@@ -700,7 +699,7 @@ maybe_process_partial_specialization (type)
          if (current_namespace
              != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
            {
-             cp_pedwarn ("specializing `%#T' in different namespace", type);
+             pedwarn ("specializing `%#T' in different namespace", type);
              cp_pedwarn_at ("  from definition of `%#D'",
                             CLASSTYPE_TI_TEMPLATE (type));
            }
@@ -709,10 +708,10 @@ maybe_process_partial_specialization (type)
            push_template_decl (TYPE_MAIN_DECL (type));
        }
       else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
-       cp_error ("specialization of `%T' after instantiation", type);
+       error ("specialization of `%T' after instantiation", type);
     }
   else if (processing_specialization)
-    cp_error ("explicit specialization of non-template `%T'", type);
+    error ("explicit specialization of non-template `%T'", type);
 }
 
 /* Retrieve the specialization (in the sense of [temp.spec] - a
@@ -844,7 +843,7 @@ register_specialization (spec, tmpl, args)
                  if (TREE_USED (fn) 
                      || DECL_EXPLICIT_INSTANTIATION (fn))
                    {
-                     cp_error ("specialization of %D after instantiation",
+                     error ("specialization of %D after instantiation",
                                fn);
                      return spec;
                    }
@@ -921,7 +920,7 @@ unregister_specialization (spec, tmpl)
 /* Like register_specialization, but for local declarations.  We are
    registering SPEC, an instantiation of TMPL.  */
 
-static tree
+static void
 register_local_specialization (spec, tmpl)
      tree spec;
      tree tmpl;
@@ -930,8 +929,6 @@ register_local_specialization (spec, tmpl)
 
   slot = htab_find_slot (local_specializations, tmpl, INSERT);
   *slot = spec;
-
-  return spec;
 }
 
 /* Print the list of candidate FNS in an error message.  */
@@ -1000,7 +997,7 @@ determine_specialization (template_id, decl, targs_out,
 
   if (!is_overloaded_fn (fns))
     {
-      cp_error ("`%D' is not a function template", fns);
+      error ("`%D' is not a function template", fns);
       return error_mark_node;
     }
 
@@ -1025,6 +1022,9 @@ determine_specialization (template_id, decl, targs_out,
        /* This is just an ordinary non-member function.  Nothing can
           be a specialization of that.  */
        continue;
+      else if (DECL_ARTIFICIAL (fn))
+       /* Cannot specialize functions that are created implicitly.  */
+       continue;
       else
        {
          tree decl_arg_types;
@@ -1039,6 +1039,12 @@ determine_specialization (template_id, decl, targs_out,
             Here, S<int>::f is a non-template, but S<int> is a
             template class.  If FN has the same type as DECL, we
             might be in business.  */
+
+         if (!DECL_TEMPLATE_INFO (fn))
+           /* Its enclosing class is an explicit specialization
+              of a template class.  This is not a candidate.  */
+           continue;
+
          if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
                            TREE_TYPE (TREE_TYPE (fn))))
            /* The return types differ.  */
@@ -1151,7 +1157,128 @@ determine_specialization (template_id, decl, targs_out,
     *targs_out = TREE_PURPOSE (templates);
   return TREE_VALUE (templates);
 }
+
+/* Returns a chain of parameter types, exactly like the SPEC_TYPES,
+   but with the default argument values filled in from those in the
+   TMPL_TYPES.  */
       
+static tree
+copy_default_args_to_explicit_spec_1 (spec_types,
+                                     tmpl_types)
+     tree spec_types;
+     tree tmpl_types;
+{
+  tree new_spec_types;
+
+  if (!spec_types)
+    return NULL_TREE;
+
+  if (spec_types == void_list_node)
+    return void_list_node;
+
+  /* Substitute into the rest of the list.  */
+  new_spec_types =
+    copy_default_args_to_explicit_spec_1 (TREE_CHAIN (spec_types),
+                                         TREE_CHAIN (tmpl_types));
+  
+  /* Add the default argument for this parameter.  */
+  return hash_tree_cons (TREE_PURPOSE (tmpl_types),
+                        TREE_VALUE (spec_types),
+                        new_spec_types);
+}
+
+/* DECL is an explicit specialization.  Replicate default arguments
+   from the template it specializes.  (That way, code like:
+
+     template <class T> void f(T = 3);
+     template <> void f(double);
+     void g () { f (); } 
+
+   works, as required.)  An alternative approach would be to look up
+   the correct default arguments at the call-site, but this approach
+   is consistent with how implicit instantiations are handled.  */
+
+static void
+copy_default_args_to_explicit_spec (decl)
+     tree decl;
+{
+  tree tmpl;
+  tree spec_types;
+  tree tmpl_types;
+  tree new_spec_types;
+  tree old_type;
+  tree new_type;
+  tree t;
+  tree object_type = NULL_TREE;
+  tree in_charge = NULL_TREE;
+  tree vtt = NULL_TREE;
+
+  /* See if there's anything we need to do.  */
+  tmpl = DECL_TI_TEMPLATE (decl);
+  tmpl_types = TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (tmpl)));
+  for (t = tmpl_types; t; t = TREE_CHAIN (t))
+    if (TREE_PURPOSE (t))
+      break;
+  if (!t)
+    return;
+
+  old_type = TREE_TYPE (decl);
+  spec_types = TYPE_ARG_TYPES (old_type);
+  
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+    {
+      /* Remove the this pointer, but remember the object's type for
+         CV quals.  */
+      object_type = TREE_TYPE (TREE_VALUE (spec_types));
+      spec_types = TREE_CHAIN (spec_types);
+      tmpl_types = TREE_CHAIN (tmpl_types);
+      
+      if (DECL_HAS_IN_CHARGE_PARM_P (decl))
+        {
+          /* DECL may contain more parameters than TMPL due to the extra
+             in-charge parameter in constructors and destructors.  */
+          in_charge = spec_types;
+         spec_types = TREE_CHAIN (spec_types);
+       }
+      if (DECL_HAS_VTT_PARM_P (decl))
+       {
+         vtt = spec_types;
+         spec_types = TREE_CHAIN (spec_types);
+       }
+    }
+
+  /* Compute the merged default arguments.  */
+  new_spec_types = 
+    copy_default_args_to_explicit_spec_1 (spec_types, tmpl_types);
+
+  /* Compute the new FUNCTION_TYPE.  */
+  if (object_type)
+    {
+      if (vtt)
+        new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
+                                        TREE_VALUE (vtt),
+                                        new_spec_types);
+
+      if (in_charge)
+        /* Put the in-charge parameter back.  */
+        new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
+                                        TREE_VALUE (in_charge),
+                                        new_spec_types);
+
+      new_type = build_cplus_method_type (object_type,
+                                         TREE_TYPE (old_type),
+                                         new_spec_types);
+    }
+  else
+    new_type = build_function_type (TREE_TYPE (old_type),
+                                   new_spec_types);
+  new_type = build_type_attribute_variant (new_type,
+                                          TYPE_ATTRIBUTES (old_type));
+  new_type = build_exception_variant (new_type,
+                                     TYPE_RAISES_EXCEPTIONS (old_type));
+  TREE_TYPE (decl) = new_type;
+}
+
 /* Check to see if the function just declared, as indicated in
    DECLARATOR, and in DECL, is a specialization of a function
    template.  We may also discover that the declaration is an explicit
@@ -1228,7 +1355,7 @@ 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",
+             error ("template-id `%D' in declaration of primary template",
                        declarator);
              return decl;
            }
@@ -1241,19 +1368,19 @@ check_explicit_specialization (declarator, decl, template_count, flags)
       return error_mark_node;
 
     case tsk_invalid_expl_inst:
-      cp_error ("template parameter list used in explicit instantiation");
+      error ("template parameter list used in explicit instantiation");
 
       /* Fall through.  */
 
     case tsk_expl_inst:
       if (have_def)
-       cp_error ("definition provided for explicit instantiation");
+       error ("definition provided for explicit instantiation");
       
       explicit_instantiation = 1;
       break;
 
     case tsk_excessive_parms:
-      cp_error ("too many template parameter lists in declaration of `%D'", 
+      error ("too many template parameter lists in declaration of `%D'", 
                decl);
       return error_mark_node;
 
@@ -1269,7 +1396,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
     case tsk_insufficient_parms:
       if (template_header_count)
        {
-         cp_error("too few template parameter lists in declaration of `%D'", 
+         error("too few template parameter lists in declaration of `%D'", 
                   decl);
          return decl;
        }
@@ -1285,7 +1412,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
 
             That used to be legal C++.  */
          if (pedantic)
-           cp_pedwarn
+           pedwarn
              ("explicit specialization not preceded by `template <>'");
          specialization = 1;
          SET_DECL_TEMPLATE_SPECIALIZATION (decl);
@@ -1299,10 +1426,10 @@ check_explicit_specialization (declarator, decl, template_count, flags)
             template <class T> void f<int>(); */
 
          if (uses_template_parms (declarator))
-           cp_error ("partial specialization `%D' of function template",
+           error ("partial specialization `%D' of function template",
                      declarator);
          else
-           cp_error ("template-id `%D' in declaration of primary template",
+           error ("template-id `%D' in declaration of primary template",
                      declarator);
          return decl;
        }
@@ -1330,12 +1457,12 @@ check_explicit_specialization (declarator, decl, template_count, flags)
       for (; t; t = TREE_CHAIN (t))
        if (TREE_PURPOSE (t))
          {
-           cp_pedwarn
+           pedwarn
              ("default argument specified in explicit specialization");
            break;
          }
       if (current_lang_name == lang_name_c)
-       cp_error ("template specialization with C linkage");
+       error ("template specialization with C linkage");
     }
 
   if (specialization || member_specialization || explicit_instantiation)
@@ -1391,7 +1518,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
       else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR)
        {
          /* A friend declaration.  We can't do much, because we don't
-          know what this resolves to, yet.  */
+            know what this resolves to, yet.  */
          my_friendly_assert (is_friend != 0, 0);
          my_friendly_assert (!explicit_instantiation, 0);
          SET_DECL_IMPLICIT_INSTANTIATION (decl);
@@ -1423,7 +1550,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
                     program is ill-formed.  
 
                     Similar language is found in [temp.explicit].  */
-                 cp_error ("specialization of implicitly-declared special member function");
+                 error ("specialization of implicitly-declared special member function");
                  return error_mark_node;
                }
 
@@ -1466,7 +1593,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
              
          if (fns == NULL_TREE) 
            {
-             cp_error ("no member function `%D' declared in `%T'",
+             error ("no member function `%D' declared in `%T'",
                        name, ctype);
              return error_mark_node;
            }
@@ -1532,7 +1659,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
              return tmpl;
            }
 
-         /* If we though that the DECL was a member function, but it
+         /* If we thought that the DECL was a member function, but it
             turns out to be specializing a static member function,
             make DECL a static member function as well.  */
          if (DECL_STATIC_FUNCTION_P (tmpl)
@@ -1545,30 +1672,25 @@ check_explicit_specialization (declarator, decl, template_count, flags)
          /* Set up the DECL_TEMPLATE_INFO for DECL.  */
          DECL_TEMPLATE_INFO (decl) = tree_cons (tmpl, targs, NULL_TREE);
 
-         /* Mangle the function name appropriately.  Note that we do
-            not mangle specializations of non-template member
-            functions of template classes, e.g. with
-
-              template <class T> struct S { void f(); }
-
-            and given the specialization 
+         /* Inherit default function arguments from the template
+            DECL is specializing.  */
+         copy_default_args_to_explicit_spec (decl);
 
-              template <> void S<int>::f() {}
-
-            we do not mangle S<int>::f() here.  That's because it's
-            just an ordinary member function and doesn't need special
-            treatment.  We do this here so that the ordinary,
-            non-template, name-mangling algorithm will not be used
-            later.  */
-         if ((is_member_template (tmpl) || ctype == NULL_TREE)
-             && name_mangling_version >= 1)
-           set_mangled_name_for_template_decl (decl);
+         /* This specialization has the same protection as the
+            template it specializes.  */
+         TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
+         TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
 
          if (is_friend && !have_def)
            /* This is not really a declaration of a specialization.
               It's just the name of an instantiation.  But, it's not
               a request for an instantiation, either.  */
            SET_DECL_IMPLICIT_INSTANTIATION (decl);
+         else if (DECL_CONSTRUCTOR_P (decl) || DECL_DESTRUCTOR_P (decl))
+           /* This is indeed a specialization.  In case of constructors
+              and destructors, we need in-charge and not-in-charge
+              versions in V3 ABI.  */
+           clone_function_decl (decl, /*update_method_vec_p=*/0);
 
          /* Register this specialization so that we can find it
             again.  */
@@ -1619,7 +1741,7 @@ maybe_check_template_type (type)
        ; 
       else if (template_header_count > context_depth + 1)
        /* There are two many template parameter lists.  */
-       cp_error ("too many template parameter lists in declaration of `%T'", type); 
+       error ("too many template parameter lists in declaration of `%T'", type); 
     }
 }
 
@@ -1765,6 +1887,9 @@ reduce_template_parm_level (index, type, levels)
                                     decl, type);
       TEMPLATE_PARM_DESCENDANTS (index) = t;
 
+      DECL_ARTIFICIAL (decl) = 1;
+      SET_DECL_TEMPLATE_PARM_P (decl);
+
       /* Template template parameters need this.  */
       DECL_TEMPLATE_PARMS (decl)
        = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
@@ -1809,7 +1934,8 @@ process_template_parm (list, next)
       my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
       /* is a const-param */
       parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
-                            PARM, 0, NULL_TREE);
+                            PARM, 0, NULL);
+      SET_DECL_TEMPLATE_PARM_P (parm);
 
       /* [temp.param]
 
@@ -1819,21 +1945,8 @@ process_template_parm (list, next)
 
       /* A template parameter is not modifiable.  */
       TREE_READONLY (parm) = 1;
-      if (IS_AGGR_TYPE (TREE_TYPE (parm))
-         && TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM
-         && TREE_CODE (TREE_TYPE (parm)) != TYPENAME_TYPE)
-       {
-         cp_error ("`%#T' is not a valid type for a template constant parameter",
-                   TREE_TYPE (parm));
-         if (DECL_NAME (parm) == NULL_TREE)
-           error ("  a template type parameter must begin with `class' or `typename'");
-         TREE_TYPE (parm) = void_type_node;
-       }
-      else if (pedantic
-              && (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE
-                  || TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE))
-       cp_pedwarn ("`%T' is not a valid type for a template constant parameter",
-                   TREE_TYPE (parm));
+      if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
+        TREE_TYPE (parm) = void_type_node;
       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
       DECL_INITIAL (parm) = DECL_INITIAL (decl) 
        = build_template_parm_index (idx, processing_template_decl,
@@ -1886,17 +1999,19 @@ end_template_parm_list (parms)
      tree parms;
 {
   int nparms;
-  tree parm;
+  tree parm, next;
   tree saved_parmlist = make_tree_vec (list_length (parms));
 
   current_template_parms
-    = tree_cons (build_int_2 (0, processing_template_decl),
+    = tree_cons (size_int (processing_template_decl),
                 saved_parmlist, current_template_parms);
 
-  for (parm = parms, nparms = 0; 
-       parm; 
-       parm = TREE_CHAIN (parm), nparms++)
-    TREE_VEC_ELT (saved_parmlist, nparms) = parm;
+  for (parm = parms, nparms = 0; parm; parm = next, nparms++)
+    {
+      next = TREE_CHAIN (parm);
+      TREE_VEC_ELT (saved_parmlist, nparms) = parm;
+      TREE_CHAIN (parm) = NULL_TREE;
+    }
 
   --processing_template_parmlist;
 
@@ -2126,11 +2241,11 @@ process_partial_specialization (decl)
           specialization.  */
        if (!did_error_intro)
          {
-           cp_error ("template parameters not used in partial specialization:");
+           error ("template parameters not used in partial specialization:");
            did_error_intro = 1;
          }
 
-       cp_error ("        `%D'", 
+       error ("        `%D'", 
                  TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
       }
 
@@ -2142,7 +2257,7 @@ process_partial_specialization (decl)
       (inner_args, 
        INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE
                                                   (maintmpl)))))
-    cp_error ("partial specialization `%T' does not specialize any template arguments", type);
+    error ("partial specialization `%T' does not specialize any template arguments", type);
 
   /* [temp.class.spec]
 
@@ -2167,7 +2282,7 @@ process_partial_specialization (decl)
          && TREE_CODE (arg) != TEMPLATE_PARM_INDEX)
        {
          if (tpd.arg_uses_template_parms[i])
-           cp_error ("template argument `%E' involves template parameter(s)", arg);
+           error ("template argument `%E' involves template parameter(s)", arg);
          else 
            {
              /* Look at the corresponding template parameter,
@@ -2210,7 +2325,7 @@ process_partial_specialization (decl)
                    if (tpd2.parms[j] != 0
                        && tpd.arg_uses_template_parms [j])
                      {
-                       cp_error ("type `%T' of template argument `%E' depends on template parameter(s)", 
+                       error ("type `%T' of template argument `%E' depends on template parameter(s)", 
                                  type,
                                  arg);
                        break;
@@ -2272,7 +2387,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
                              current_class_type)))
       /* And, if it was a member function, it really was defined in
         the scope of the class.  */
-      && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_DEFINED_IN_CLASS_P (decl)))
+      && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_INITIALIZED_IN_CLASS_P (decl)))
     /* We already checked these parameters when the template was
        declared, so there's no need to do it again now.  This function
        was defined in class scope, but we're processing it's body now
@@ -2298,7 +2413,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
            seen_def_arg_p = 1;
          else if (seen_def_arg_p)
            {
-             cp_error ("no default argument for `%D'", TREE_VALUE (parm));
+             error ("no default argument for `%D'", TREE_VALUE (parm));
              /* For better subsequent error-recovery, we indicate that
                 there should have been a default argument.  */
              TREE_PURPOSE (parm) = error_mark_node;
@@ -2328,9 +2443,9 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
 
   /* Figure out what error message to issue.  */
   if (TREE_CODE (decl) == FUNCTION_DECL)
-    msg = "default argument for template parameter in function template `%D'";
+    msg = "default template arguments may not be used in function templates";
   else if (is_partial)
-    msg = "default argument in partial specialization `%D'";
+    msg = "default template arguments may not be used in partial specializations";
   else
     msg = "default argument for template parameter for class enclosing `%D'";
 
@@ -2362,7 +2477,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
          {
            if (msg)
              {
-               cp_error (msg, decl);
+               error (msg, decl);
                msg = 0;
              }
 
@@ -2431,17 +2546,17 @@ push_template_decl_real (decl, is_friend)
   if (primary)
     {
       if (current_lang_name == lang_name_c)
-       cp_error ("template with C linkage");
+       error ("template with C linkage");
       else if (TREE_CODE (decl) == TYPE_DECL 
               && ANON_AGGRNAME_P (DECL_NAME (decl))) 
-       cp_error ("template class without a name");
+       error ("template class without a name");
       else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
                && CLASS_TYPE_P (TREE_TYPE (decl)))
               || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))
               || TREE_CODE (decl) == FUNCTION_DECL)
        /* OK */;
       else
-       cp_error ("template declaration of `%#D'", decl);
+       error ("template declaration of `%#D'", decl);
     }
 
   /* Check to see that the rules regarding the use of default
@@ -2509,13 +2624,13 @@ push_template_decl_real (decl, is_friend)
            tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl));
          else
            {
-             cp_error ("`%D' does not declare a template type", decl);
+             error ("`%D' does not declare a template type", decl);
              return decl;
            }
        }
-      else if (! DECL_TEMPLATE_INFO (decl))
+      else if (!DECL_LANG_SPECIFIC (decl) || !DECL_TEMPLATE_INFO (decl))
        {
-         cp_error ("template definition of non-template `%#D'", decl);
+         error ("template definition of non-template `%#D'", decl);
          return decl;
        }
       else
@@ -2556,7 +2671,7 @@ push_template_decl_real (decl, is_friend)
       i = TMPL_PARMS_DEPTH (parms);
       if (TMPL_ARGS_DEPTH (args) != i)
        {
-         cp_error ("expected %d levels of template parms for `%#D', got %d",
+         error ("expected %d levels of template parms for `%#D', got %d",
                    i, decl, TMPL_ARGS_DEPTH (args));
        }
       else
@@ -2568,12 +2683,12 @@ push_template_decl_real (decl, is_friend)
            if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
              {
                if (current == decl)
-                 cp_error ("got %d template parameters for `%#D'",
+                 error ("got %d template parameters for `%#D'",
                            TREE_VEC_LENGTH (a), decl);
                else
-                 cp_error ("got %d template parameters for `%#T'",
+                 error ("got %d template parameters for `%#T'",
                            TREE_VEC_LENGTH (a), current);
-               cp_error ("  but %d required", TREE_VEC_LENGTH (t));
+               error ("  but %d required", TREE_VEC_LENGTH (t));
              }
 
            /* Perhaps we should also check that the parms are used in the
@@ -2606,7 +2721,9 @@ push_template_decl_real (decl, is_friend)
     {
       SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info);
       if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL)
-         && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE)
+         && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
+         /* Don't change the name if we've already set it up.  */
+         && !IDENTIFIER_TEMPLATE (DECL_NAME (decl)))
        DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl));
     }
   else if (DECL_LANG_SPECIFIC (decl))
@@ -2639,7 +2756,7 @@ redeclare_class_template (type, parms)
 
   if (!TYPE_TEMPLATE_INFO (type))
     {
-      cp_error ("`%T' is not a template type", type);
+      error ("`%T' is not a template type", type);
       return;
     }
 
@@ -2656,7 +2773,7 @@ redeclare_class_template (type, parms)
   if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
     {
       cp_error_at ("previous declaration `%D'", tmpl);
-      cp_error ("used %d template parameter%s instead of %d",
+      error ("used %d template parameter%s instead of %d",
                TREE_VEC_LENGTH (tmpl_parms), 
                TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s",
                TREE_VEC_LENGTH (parms));
@@ -2673,7 +2790,7 @@ redeclare_class_template (type, parms)
       if (TREE_CODE (tmpl_parm) != TREE_CODE (parm))
        {
          cp_error_at ("template parameter `%#D'", tmpl_parm);
-         cp_error ("redeclared here as `%#D'", parm);
+         error ("redeclared here as `%#D'", parm);
          return;
        }
 
@@ -2683,7 +2800,7 @@ redeclare_class_template (type, parms)
 
             A template-parameter may not be given default arguments
             by two different declarations in the same scope.  */
-         cp_error ("redefinition of default argument for `%#D'", parm);
+         error ("redefinition of default argument for `%#D'", parm);
          cp_error_at ("  original definition appeared here", tmpl_parm);
          return;
        }
@@ -2777,17 +2894,17 @@ convert_nontype_argument (type, expr)
          if (TREE_CODE (e) != ADDR_EXPR)
            {
            bad_argument:
-             cp_error ("`%E' is not a valid template argument", expr);
+             error ("`%E' is not a valid template argument", expr);
              if (TYPE_PTR_P (expr_type))
                {
                  if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE)
-                   cp_error ("it must be the address of a function with external linkage");
+                   error ("it must be the address of a function with external linkage");
                  else
-                   cp_error ("it must be the address of an object with external linkage");
+                   error ("it must be the address of an object with external linkage");
                }
              else if (TYPE_PTRMEM_P (expr_type)
                       || TYPE_PTRMEMFUNC_P (expr_type))
-               cp_error ("it must be a pointer-to-member of the form `&X::Y'");
+               error ("it must be a pointer-to-member of the form `&X::Y'");
 
              return NULL_TREE;
            }
@@ -2798,7 +2915,7 @@ convert_nontype_argument (type, expr)
 
       if (TREE_CODE (referent) == STRING_CST)
        {
-         cp_error ("string literal %E is not a valid template argument because it is the address of an object with static linkage", 
+         error ("string literal %E is not a valid template argument because it is the address of an object with static linkage", 
                    referent);
          return NULL_TREE;
        }
@@ -2810,28 +2927,25 @@ convert_nontype_argument (type, expr)
        goto bad_argument;
       else if (!DECL_EXTERNAL_LINKAGE_P (referent))
        {
-         cp_error ("address of non-extern `%E' cannot be used as template argument", referent); 
+         error ("address of non-extern `%E' cannot be used as template argument", referent); 
          return error_mark_node;
        }
     }
   else if (INTEGRAL_TYPE_P (expr_type) 
           || TYPE_PTRMEM_P (expr_type) 
-          || TYPE_PTRMEMFUNC_P (expr_type)
-          /* The next two are g++ extensions.  */
-          || TREE_CODE (expr_type) == REAL_TYPE
-          || TREE_CODE (expr_type) == COMPLEX_TYPE)
+          || TYPE_PTRMEMFUNC_P (expr_type))
     {
       if (! TREE_CONSTANT (expr))
        {
        non_constant:
-         cp_error ("non-constant `%E' cannot be used as template argument",
+         error ("non-constant `%E' cannot be used as template argument",
                    expr);
          return NULL_TREE;
        }
     }
   else 
     {
-      cp_error ("object `%E' cannot be used as template argument", expr);
+      error ("object `%E' cannot be used as template argument", expr);
       return NULL_TREE;
     }
 
@@ -2858,19 +2972,6 @@ convert_nontype_argument (type, expr)
       
       return expr;
        
-    case REAL_TYPE:
-    case COMPLEX_TYPE:
-      /* These are g++ extensions.  */
-      if (TREE_CODE (expr_type) != TREE_CODE (type))
-       return error_mark_node;
-
-      expr = digest_init (type, expr, (tree*) 0);
-      
-      if (TREE_CODE (expr) != REAL_CST)
-       goto non_constant;
-
-      return expr;
-
     case POINTER_TYPE:
       {
        tree type_pointed_to = TREE_TYPE (type);
@@ -3020,13 +3121,7 @@ convert_nontype_argument (type, expr)
 
     case RECORD_TYPE:
       {
-       if (!TYPE_PTRMEMFUNC_P (type))
-         /* This handles templates like
-              template<class T, T t> void f();
-            when T is substituted with any class.  The second template
-            parameter becomes invalid and the template candidate is
-            rejected.  */
-         return error_mark_node;
+       my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 20010112);
 
        /* For a non-type template-parameter of type pointer to member
           function, no conversions apply.  If the template-argument
@@ -3197,23 +3292,30 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
   requires_type = (TREE_CODE (parm) == TYPE_DECL
                   || requires_tmpl_type);
 
-  /* Check if it is a class template.  If REQUIRES_TMPL_TYPE is true,
-     we also accept implicitly created TYPE_DECL as a valid argument.
-     This is necessary to handle the case where we pass a template name
-     to a template template parameter in a scope where we've derived from
-     in instantiation of that template, so the template name refers to that
-     instantiation.  We really ought to handle this better.  */
-  is_tmpl_type 
-    = ((TREE_CODE (arg) == TEMPLATE_DECL
-       && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
-       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
-       || (TREE_CODE (arg) == RECORD_TYPE
-          && CLASSTYPE_TEMPLATE_INFO (arg)
-          && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
-          && DECL_ARTIFICIAL (TYPE_NAME (arg))
-          && requires_tmpl_type
-          && is_base_of_enclosing_class (arg, current_class_type)));
-  if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+  if (TREE_CODE (arg) != RECORD_TYPE)
+    is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
+                    && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+                   || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+                   || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
+  else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg)
+          && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg)))
+    {
+      if (is_base_of_enclosing_class (arg, current_class_type))
+       /* This is a template name used within the scope of the
+          template. It could be the template, or it could be the
+          instantiation. Choose whichever makes sense.  */
+       is_tmpl_type = requires_tmpl_type;
+      else
+       is_tmpl_type = 1;
+    }
+  else
+    /* It is a non-template class, or a specialization of a template
+       class, or a non-template member of a template class.  */
+    is_tmpl_type = 0;
+  
+  if (is_tmpl_type
+      && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+         || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
     arg = TYPE_STUB_DECL (arg);
   else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
     arg = CLASSTYPE_TI_TEMPLATE (arg);
@@ -3223,7 +3325,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      cp_pedwarn ("to refer to a type member of a template parameter, use `typename %E'", arg);
+      pedwarn ("to refer to a type member of a template parameter, use `typename %E'", arg);
       
       arg = make_typename_type (TREE_OPERAND (arg, 0),
                                TREE_OPERAND (arg, 1),
@@ -3236,14 +3338,14 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
        {
          if (complain)
            {
-             cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
+             error ("type/value mismatch at argument %d in template parameter list for `%D'",
                        i + 1, in_decl);
              if (is_type)
-               cp_error ("  expected a constant of type `%T', got `%T'",
+               error ("  expected a constant of type `%T', got `%T'",
                          TREE_TYPE (parm),
                          (is_tmpl_type ? DECL_NAME (arg) : arg));
              else
-               cp_error ("  expected a type, got `%E'", arg);
+               error ("  expected a type, got `%E'", arg);
            }
        }
       return error_mark_node;
@@ -3252,12 +3354,12 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
     {
       if (in_decl && complain)
        {
-         cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
+         error ("type/value mismatch at argument %d in template parameter list for `%D'",
                    i + 1, in_decl);
          if (is_tmpl_type)
-           cp_error ("  expected a type, got `%T'", DECL_NAME (arg));
+           error ("  expected a type, got `%T'", DECL_NAME (arg));
          else
-           cp_error ("  expected a class template, got `%T'", arg);
+           error ("  expected a class template, got `%T'", arg);
        }
       return error_mark_node;
     }
@@ -3266,30 +3368,38 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
     {
       if (requires_tmpl_type)
        {
-         tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
-         tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
-
-         if (coerce_template_template_parms (parmparm, argparm, complain,
-                                             in_decl, inner_args))
-           {
-             val = arg;
-                 
-             /* TEMPLATE_TEMPLATE_PARM node is preferred over 
-                TEMPLATE_DECL.  */
-             if (val != error_mark_node 
-                 && DECL_TEMPLATE_TEMPLATE_PARM_P (val))
-               val = TREE_TYPE (val);
-           }
+         if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE)
+           /* The number of argument required is not known yet.
+              Just accept it for now.  */
+           val = TREE_TYPE (arg);
          else
            {
-             if (in_decl && complain)
+             tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
+             tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
+
+             if (coerce_template_template_parms (parmparm, argparm,
+                                                 complain, in_decl,
+                                                 inner_args))
                {
-                 cp_error ("type/value mismatch at argument %d in template parameter list for `%D'",
-                           i + 1, in_decl);
-                 cp_error ("  expected a template of type `%D', got `%D'", parm, arg);
+                 val = arg;
+                 
+                 /* TEMPLATE_TEMPLATE_PARM node is preferred over 
+                    TEMPLATE_DECL.  */
+                 if (val != error_mark_node 
+                     && DECL_TEMPLATE_TEMPLATE_PARM_P (val))
+                   val = TREE_TYPE (val);
                }
+             else
+               {
+                 if (in_decl && complain)
+                   {
+                     error ("type/value mismatch at argument %d in template parameter list for `%D'",
+                               i + 1, in_decl);
+                     error ("  expected a template of type `%D', got `%D'", parm, arg);
+                   }
                  
-             val = error_mark_node;
+                 val = error_mark_node;
+               }
            }
        }
       else
@@ -3305,11 +3415,11 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
              tree t = no_linkage_check (val);
              if (t)
                {
-                 if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
-                   cp_pedwarn
+                 if (TYPE_ANONYMOUS_P (t))
+                   pedwarn
                      ("template-argument `%T' uses anonymous type", val);
                  else
-                   cp_error
+                   error
                      ("template-argument `%T' uses local type `%T'",
                       val, t);
                  return error_mark_node;
@@ -3321,6 +3431,9 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
     {
       tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
 
+      if (invalid_nontype_parm_type_p (t, complain))
+        return error_mark_node;
+      
       if (processing_template_decl)
        arg = maybe_fold_nontype_arg (arg);
 
@@ -3342,7 +3455,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
       if (val == NULL_TREE)
        val = error_mark_node;
       else if (val == error_mark_node && complain)
-       cp_error ("could not convert template argument `%E' to `%T'", 
+       error ("could not convert template argument `%E' to `%T'", 
                  arg, t);
     }
 
@@ -3386,7 +3499,7 @@ coerce_template_parms (parms, args, in_decl,
     {
       if (complain) 
        {
-         cp_error ("wrong number of template arguments (%d, should be %d)",
+         error ("wrong number of template arguments (%d, should be %d)",
                    nargs, nparms);
          
          if (in_decl)
@@ -3437,7 +3550,7 @@ coerce_template_parms (parms, args, in_decl,
        }
       else if (arg == error_mark_node)
        {
-         cp_error ("template argument %d is invalid", i + 1);
+         error ("template argument %d is invalid", i + 1);
          arg = error_mark_node;
        }
       else 
@@ -3464,13 +3577,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);
 }
@@ -3627,6 +3741,7 @@ add_pending_template (d)
   tree ti = (TYPE_P (d)
             ? CLASSTYPE_TEMPLATE_INFO (d)
             : DECL_TEMPLATE_INFO (d));
+  tree pt;
   int level;
 
   if (TI_PENDING_TEMPLATE_FLAG (ti))
@@ -3640,8 +3755,14 @@ add_pending_template (d)
   if (level)
     push_tinst_level (d);
 
-  *template_tail = tree_cons (current_tinst_level, d, NULL_TREE);
-  template_tail = &TREE_CHAIN (*template_tail);
+  pt = tree_cons (current_tinst_level, d, NULL_TREE);
+  if (last_pending_template)
+    TREE_CHAIN (last_pending_template) = pt;
+  else
+    pending_templates = pt;
+
+  last_pending_template = pt;
+
   TI_PENDING_TEMPLATE_FLAG (ti) = 1;
 
   if (level)
@@ -3661,7 +3782,7 @@ lookup_template_function (fns, arglist)
 
   if (fns == NULL_TREE)
     {
-      cp_error ("non-template used as template");
+      error ("non-template used as template");
       return error_mark_node;
     }
 
@@ -3707,17 +3828,20 @@ maybe_get_template_decl_from_type_decl (decl)
 
    If ENTERING_SCOPE is non-zero, we are about to enter the scope of
    the class we are looking up.
+   
+   If COMPLAIN is non-zero, issue error messages.
 
    If the template class is really a local class in a template
    function, then the FUNCTION_CONTEXT is the function in which it is
    being instantiated.  */
 
 tree
-lookup_template_class (d1, arglist, in_decl, context, entering_scope)
+lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
      tree d1, arglist;
      tree in_decl;
      tree context;
      int entering_scope;
+     int complain;
 {
   tree template = NULL_TREE, parmlist;
   tree t;
@@ -3775,15 +3899,24 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
      crash. Alternatively D1 might not be a template type at all.  */
   if (! template)
     {
-      cp_error ("`%T' is not a template", d1);
+      if (complain)
+        error ("`%T' is not a template", d1);
       return error_mark_node;
     }
 
-  if (TREE_CODE (template) != TEMPLATE_DECL)
+  if (TREE_CODE (template) != TEMPLATE_DECL
+         /* If we're called from the parser, make sure it's a user visible
+            template.  */
+      || ((!arglist || TREE_CODE (arglist) == TREE_LIST)
+          && !DECL_TEMPLATE_PARM_P (template)
+          && !PRIMARY_TEMPLATE_P (template)))
     {
-      cp_error ("non-template type `%T' used as a template", d1);
-      if (in_decl)
-       cp_error_at ("for template declaration `%D'", in_decl);
+      if (complain)
+        {
+          error ("non-template type `%T' used as a template", d1);
+          if (in_decl)
+           cp_error_at ("for template declaration `%D'", in_decl);
+       }
       return error_mark_node;
     }
 
@@ -3797,12 +3930,25 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
 
       parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
 
-      arglist2 = coerce_template_parms (parmlist, arglist, template, 1, 1);
+      /* Consider an example where a template template parameter declared as
+
+          template <class T, class U = std::allocator<T> > class TT
+
+        The template parameter level of T and U are one level larger than 
+        of TT.  To proper process the default argument of U, say when an 
+        instantiation `TT<int>' is seen, we need to build the full
+        arguments containing {int} as the innermost level.  Outer levels
+        can be obtained from `current_template_args ()'.  */
+
+      if (processing_template_decl)
+       arglist = add_to_template_args (current_template_args (), arglist);
+
+      arglist2 = coerce_template_parms (parmlist, arglist, template,
+                                        complain, /*require_all_args=*/1);
       if (arglist2 == error_mark_node)
        return error_mark_node;
 
-      parm = copy_template_template_parm (TREE_TYPE (template), arglist2);
-      TYPE_SIZE (parm) = 0;
+      parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
       return parm;
     }
   else 
@@ -3811,6 +3957,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
       tree gen_tmpl;
       tree type_decl;
       tree found = NULL_TREE;
+      tree *tp;
       int arg_depth;
       int parm_depth;
       int is_partial_instantiation;
@@ -3840,7 +3987,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
          arg_depth = TMPL_ARGS_DEPTH (arglist);
        }
 
-      /* Now we should enough arguments.  */
+      /* Now we should have enough arguments.  */
       my_friendly_assert (parm_depth == arg_depth, 0);
       
       /* From here on, we're only interested in the most general
@@ -3864,7 +4011,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
               --i, t = TREE_CHAIN (t))
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
-                                             arglist, template, 1, 1);
+                                             arglist, template,
+                                             complain, /*require_all_args=*/1);
              SET_TMPL_ARGS_LEVEL (bound_args, i, a);
 
              /* We temporarily reduce the length of the ARGLIST so
@@ -3883,7 +4031,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
        arglist
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
-                                  template, 1, 1);
+                                  template,
+                                  complain, /*require_all_args=*/1);
 
       if (arglist == error_mark_node)
        /* We were unable to bind the arguments.  */
@@ -3925,11 +4074,23 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
        }
       if (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);
+
+      for (tp = &DECL_TEMPLATE_INSTANTIATIONS (template);
+          *tp;
+          tp = &TREE_CHAIN (*tp))
+       if (comp_template_args (TREE_PURPOSE (*tp), arglist))
+         {
+           found = *tp;
+
+           /* Use the move-to-front heuristic to speed up future
+              searches.  */
+           *tp = TREE_CHAIN (*tp);
+           TREE_CHAIN (found) 
+             = DECL_TEMPLATE_INSTANTIATIONS (template);
+           DECL_TEMPLATE_INSTANTIATIONS (template) = found;
+
+           return TREE_VALUE (found);
+         }
 
       /* This type is a "partial instantiation" if any of the template
         arguments still involve template parameters.  Note that we set
@@ -4055,9 +4216,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
                  Create the partial instantiation.
                */
               TREE_VEC_LENGTH (arglist)--;
-              template = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
+              found = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
               TREE_VEC_LENGTH (arglist)++;
-              found = template;
             }
        }
 
@@ -4081,15 +4241,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
         is set up.  */
       if (TREE_CODE (t) != ENUMERAL_TYPE)
        DECL_NAME (type_decl) = classtype_mangled_name (t);
-      DECL_ASSEMBLER_NAME (type_decl) = DECL_NAME (type_decl);
       if (!is_partial_instantiation)
        {
-         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
             instantiate it.  I think DDD still relies on this.
@@ -4153,6 +4306,7 @@ for_each_template_parm_r (tp, walk_subtrees, d)
         explicitly here.  */
       if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data))
        return error_mark_node;
+      /* Fall through.  */
 
     case FUNCTION_TYPE:
       /* Check the return type.  */
@@ -4281,10 +4435,14 @@ for_each_template_parm (t, fn, data)
   pfd.fn = fn;
   pfd.data = data;
 
-  /* Walk the tree.  */
-  return walk_tree_without_duplicates (&t, 
-                                      for_each_template_parm_r, 
-                                      &pfd) != NULL_TREE;
+  /* Walk the tree.  (Conceptually, we would like to walk without
+     duplicates, but for_each_template_parm_r recursively calls
+     for_each_template_parm, so we would need to reorganize a fair
+     bit to use walk_tree_without_duplicates.)  */
+  return walk_tree (&t, 
+                   for_each_template_parm_r, 
+                   &pfd,
+                   NULL) != NULL_TREE;
 }
 
 int
@@ -4305,7 +4463,7 @@ static int last_template_error_tick;
 /* We're starting to instantiate D; record the template instantiation context
    for diagnostics and to restore it later.  */
 
-static int
+int
 push_tinst_level (d)
      tree d;
 {
@@ -4320,7 +4478,7 @@ push_tinst_level (d)
        return 0;
 
       last_template_error_tick = tinst_level_tick;
-      cp_error ("template instantiation depth exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum) instantiating `%D'",
+      error ("template instantiation depth exceeds maximum of %d (use -ftemplate-depth-NN to increase the maximum) instantiating `%D'",
             max_tinst_depth, d);
 
       print_instantiation_context ();
@@ -4466,19 +4624,14 @@ tsubst_friend_function (decl, args)
        = 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
-     set_mangled_name_for_template_decl.  But, the function is not a
-     template instantiation and should not be mangled like one.
-     Therefore, we remangle the function name.  We don't have to do
-     this if the NEW_FRIEND is a template since
-     set_mangled_name_for_template_decl doesn't do anything if the
-     function declaration still uses template arguments.  */
+  /* The mangled name for the NEW_FRIEND is incorrect.  The function
+     is not a template instantiation and should not be mangled like
+     one.  Therefore, we forget the mangling here; we'll recompute it
+     later if we need it.  */
   if (TREE_CODE (new_friend) != TEMPLATE_DECL)
     {
-      set_mangled_name_for_decl (new_friend);
-      DECL_RTL (new_friend) = 0;
-      make_decl_rtl (new_friend, NULL_PTR, 1);
+      SET_DECL_RTL (new_friend, NULL_RTX);
+      SET_DECL_ASSEMBLER_NAME (new_friend, NULL_TREE);
     }
       
   if (DECL_NAMESPACE_SCOPE_P (new_friend))
@@ -4760,7 +4913,7 @@ instantiate_class_template (type)
       if (t == error_mark_node)
        {
          const char *str = "candidates are:";
-         cp_error ("ambiguous class template instantiation for `%#T'", type);
+         error ("ambiguous class template instantiation for `%#T'", type);
          for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; 
               t = TREE_CHAIN (t))
            {
@@ -4849,24 +5002,17 @@ instantiate_class_template (type)
        {
          CLASSTYPE_INTERFACE_ONLY (type) = interface_only;
          SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown);
-         CLASSTYPE_VTABLE_NEEDS_WRITING (type)
-           = (! CLASSTYPE_INTERFACE_ONLY (type)
-              && CLASSTYPE_INTERFACE_KNOWN (type));
        }
       else
        {
          CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern);
          SET_CLASSTYPE_INTERFACE_UNKNOWN_X
            (type, CLASSTYPE_INTERFACE_UNKNOWN (pattern));
-         CLASSTYPE_VTABLE_NEEDS_WRITING (type)
-           = (! CLASSTYPE_INTERFACE_ONLY (type)
-              && CLASSTYPE_INTERFACE_KNOWN (type));
        }
     }
   else
     {
       SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
-      CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
     }
 
   TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
@@ -4877,7 +5023,6 @@ instantiate_class_template (type)
   TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
   TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
   TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
-  TYPE_VEC_DELETE_TAKES_SIZE (type) = TYPE_VEC_DELETE_TAKES_SIZE (pattern);
   TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern);
   TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern);
   TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern);
@@ -4971,6 +5116,7 @@ instantiate_class_template (type)
       tree newtag;
 
       newtag = tsubst (tag, args, /*complain=*/1, NULL_TREE);
+      my_friendly_assert (newtag != error_mark_node, 20010206);
       if (TREE_CODE (newtag) != ENUMERAL_TYPE)
        {
          if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
@@ -5012,7 +5158,7 @@ instantiate_class_template (type)
          {
            tree init;
 
-           if (DECL_DEFINED_IN_CLASS_P (r))
+           if (DECL_INITIALIZED_IN_CLASS_P (r))
              init = tsubst_expr (DECL_INITIAL (t), args,
                                  /*complain=*/1, NULL_TREE);
            else
@@ -5022,7 +5168,7 @@ instantiate_class_template (type)
                                            /*asmspec_tree=*/NULL_TREE, 
                                            /*flags=*/0);
 
-           if (DECL_DEFINED_IN_CLASS_P (r))
+           if (DECL_INITIALIZED_IN_CLASS_P (r))
              check_static_variable_definition (r, TREE_TYPE (r));
          }
        
@@ -5044,6 +5190,7 @@ instantiate_class_template (type)
     {
       tree r = tsubst (t, args, /*complain=*/1, NULL_TREE);
       set_current_access_from_decl (r);
+      grok_special_member_properties (r);
       finish_member_declaration (r);
     }
 
@@ -5169,12 +5316,7 @@ static tree
 maybe_fold_nontype_arg (arg)
      tree arg;
 {
-  /* If we're not in a template, ARG is already as simple as it's going to
-     get, and trying to reprocess the trees will break.  */
-  if (! processing_template_decl)
-    return arg;
-
-  if (!TYPE_P (arg) && !uses_template_parms (arg))
+  if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
     {
       /* Sometimes, one of the args was an expression involving a
         template constant parameter, like N - 1.  Now that we've
@@ -5184,10 +5326,18 @@ maybe_fold_nontype_arg (arg)
         fool build_expr_from_tree() into building an actual
         tree.  */
 
-      int saved_processing_template_decl = processing_template_decl; 
-      processing_template_decl = 0;
-      arg = fold (build_expr_from_tree (arg));
-      processing_template_decl = saved_processing_template_decl; 
+      /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
+        as simple as it's going to get, and trying to reprocess
+        the trees will break.  */
+      if (!TREE_TYPE (arg))
+       {
+         int saved_processing_template_decl = processing_template_decl; 
+         processing_template_decl = 0;
+         arg = build_expr_from_tree (arg);
+         processing_template_decl = saved_processing_template_decl; 
+       }
+
+      arg = fold (arg);
     }
   return arg;
 }
@@ -5260,21 +5410,21 @@ tsubst_template_parms (parms, args, complain)
       
       for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
        {
-         tree default_value =
-           TREE_PURPOSE (TREE_VEC_ELT (TREE_VALUE (parms), i));
-         tree parm_decl = 
-           TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), i));
-         
-         TREE_VEC_ELT (new_vec, i)
-           = build_tree_list (tsubst (default_value, args, complain,
-                                      NULL_TREE), 
-                              tsubst (parm_decl, args, complain,
-                                      NULL_TREE));
+         tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
+         tree default_value = TREE_PURPOSE (tuple);
+         tree parm_decl = TREE_VALUE (tuple);
+
+         parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+         default_value = tsubst_expr (default_value, args,
+                                      complain, NULL_TREE);
+         tuple = build_tree_list (maybe_fold_nontype_arg (default_value), 
+                                  parm_decl);
+         TREE_VEC_ELT (new_vec, i) = tuple;
        }
       
       *new_parms = 
-       tree_cons (build_int_2 (0, (TMPL_PARMS_DEPTH (parms) 
-                                   - TMPL_ARGS_DEPTH (args))),
+       tree_cons (size_int (TMPL_PARMS_DEPTH (parms) 
+                            - TMPL_ARGS_DEPTH (args)),
                   new_vec, NULL_TREE);
     }
 
@@ -5302,12 +5452,7 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
     {
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
-       {
-         tree r = build_ptrmemfunc_type
-           (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl));
-         return cp_build_qualified_type_real (r, TYPE_QUALS (t),
-                                              complain);
-       }
+       return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl);
 
       /* else fall through */
     case ENUMERAL_TYPE:
@@ -5342,7 +5487,7 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
            return error_mark_node;
 
          r = lookup_template_class (t, argvec, in_decl, context,
-                                    entering_scope);
+                                    entering_scope, complain);
 
          return cp_build_qualified_type_real (r, TYPE_QUALS (t),
                                               complain);
@@ -5418,19 +5563,18 @@ tsubst_default_arguments (fn)
 
 /* Substitute the ARGS into the T, which is a _DECL.  TYPE is the
    (already computed) substitution of ARGS into TREE_TYPE (T), if
-   appropriate.  Return the result of the substitution.  IN_DECL is as
-   for tsubst.  */
+   appropriate.  Return the result of the substitution.  */
 
 static tree
-tsubst_decl (t, args, type, in_decl)
+tsubst_decl (t, args, type)
      tree t;
      tree args;
      tree type;
-     tree in_decl;
 {
   int saved_lineno;
   const char *saved_filename;
   tree r = NULL_TREE;
+  tree in_decl = t;
 
   /* Set the filename and linenumber to improve error-reporting.  */
   saved_lineno = lineno;
@@ -5666,6 +5810,9 @@ tsubst_decl (t, args, type, in_decl)
        r = copy_decl (t);
        DECL_USE_TEMPLATE (r) = 0;
        TREE_TYPE (r) = type;
+       /* Clear out the mangled name and RTL for the instantiation.  */
+       SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
+       SET_DECL_RTL (r, NULL_RTX);
 
        DECL_CONTEXT (r) = ctx;
        DECL_VIRTUAL_CONTEXT (r)
@@ -5674,18 +5821,13 @@ tsubst_decl (t, args, type, in_decl)
                              /*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.  */
-           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));
-         }
+         /* Type-conversion operator.  Reconstruct the name, in
+            case it's the name of one of the template's parameters.  */
+         DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type));
 
        DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
                                     /*complain=*/1, t);
-       DECL_TEMPLATE_RESULT (r) = NULL_TREE;
+       DECL_RESULT (r) = NULL_TREE;
 
        TREE_STATIC (r) = 0;
        TREE_PUBLIC (r) = TREE_PUBLIC (t);
@@ -5705,9 +5847,9 @@ tsubst_decl (t, args, type, in_decl)
            TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
          }
 
-       /* Set up the DECL_TEMPLATE_INFO for R and compute its mangled
-          name.  There's no need to do this in the special friend
-          case mentioned above where GEN_TMPL is NULL.  */
+       /* Set up the DECL_TEMPLATE_INFO for R.  There's no need to do
+          this in the special friend case mentioned above where
+          GEN_TMPL is NULL.  */
        if (gen_tmpl)
          {
            DECL_TEMPLATE_INFO (r) 
@@ -5715,44 +5857,6 @@ tsubst_decl (t, args, type, in_decl)
            SET_DECL_IMPLICIT_INSTANTIATION (r);
            register_specialization (r, gen_tmpl, argvec);
 
-           /* Set the mangled name for R.  */
-           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
-                  specially, in order to conform to 14.5.5.1
-                  [temp.over.link].  */
-               tree tmpl = DECL_TI_TEMPLATE (t);
-               
-               /* TMPL will be NULL if this is a specialization of a
-                  member function of a template class.  */
-               if (name_mangling_version < 1
-                   || tmpl == NULL_TREE
-                   || (member && !is_member_template (tmpl)
-                       && !DECL_TEMPLATE_INFO (tmpl)))
-                 set_mangled_name_for_decl (r);
-               else
-                 set_mangled_name_for_template_decl (r);
-             }
-           
-           DECL_RTL (r) = 0;
-           make_decl_rtl (r, NULL_PTR, 1);
-           
-           /* Like grokfndecl.  If we don't do this, pushdecl will
-              mess up our TREE_CHAIN because it doesn't find a
-              previous decl.  Sigh.  */
-           if (member
-               && ! uses_template_parms (r)
-               && (IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r)) 
-                   == NULL_TREE))
-             SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r);
-
            /* We're not supposed to instantiate default arguments
               until they are called, for a template.  But, for a
               declaration like:
@@ -5786,18 +5890,25 @@ tsubst_decl (t, args, type, in_decl)
            maybe_retrofit_in_chrg (r);
            if (DECL_CONSTRUCTOR_P (r))
              grok_ctor_properties (ctx, r);
-           clone_function_decl(r, /*update_method_vec_p=*/0);
+           /* If this is an instantiation of a member template, clone it.
+              If it isn't, that'll be handled by
+              clone_constructors_and_destructors.  */
+           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));
+         grok_op_properties (r, DECL_FRIEND_P (r));
       }
       break;
 
     case PARM_DECL:
       {
        r = copy_node (t);
+       if (DECL_TEMPLATE_PARM_P (t))
+         SET_DECL_TEMPLATE_PARM_P (r);
+       
        TREE_TYPE (r) = type;
-       c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
+       c_apply_type_quals_to_decl (cp_type_quals (type), r);
 
        if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
          DECL_INITIAL (r) = TREE_TYPE (r);
@@ -5806,9 +5917,8 @@ tsubst_decl (t, args, type, in_decl)
                                     /*complain=*/1, in_decl);
 
        DECL_CONTEXT (r) = NULL_TREE;
-       if (PROMOTE_PROTOTYPES
-           && (TREE_CODE (type) == INTEGER_TYPE
-               || TREE_CODE (type) == ENUMERAL_TYPE)
+       if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES
+           && INTEGRAL_TYPE_P (type)
            && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
          DECL_ARG_TYPE (r) = integer_type_node;
        if (TREE_CHAIN (t))
@@ -5821,15 +5931,15 @@ tsubst_decl (t, args, type, in_decl)
       {
        r = copy_decl (t);
        TREE_TYPE (r) = type;
-       c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
+       c_apply_type_quals_to_decl (cp_type_quals (type), r);
 
        /* We don't have to set DECL_CONTEXT here; it is set by
           finish_member_declaration.  */
        DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args,
                                        /*complain=*/1, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
-       if (TREE_CODE (type) == VOID_TYPE
-         cp_error_at ("instantiation of `%D' as type void", r);
+       if (VOID_TYPE_P (type)
+         cp_error_at ("instantiation of `%D' as type `%T'", r, type);
       }
       break;
 
@@ -5872,12 +5982,13 @@ tsubst_decl (t, args, type, in_decl)
          ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, 
                                  /*complain=*/1,
                                  in_decl, /*entering_scope=*/1);
+       else if (DECL_NAMESPACE_SCOPE_P (t))
+         ctx = DECL_CONTEXT (t);
        else
          {
            /* Subsequent calls to pushdecl will fill this in.  */
            ctx = NULL_TREE;
-           if (!DECL_NAMESPACE_SCOPE_P (t))
-             local_p = 1;
+           local_p = 1;
          }
 
        /* Check to see if we already have this specialization.  */
@@ -5899,22 +6010,24 @@ tsubst_decl (t, args, type, in_decl)
 
        r = copy_decl (t);
        TREE_TYPE (r) = type;
-       c_apply_type_quals_to_decl (CP_TYPE_QUALS (type), r);
+       c_apply_type_quals_to_decl (cp_type_quals (type), r);
        DECL_CONTEXT (r) = ctx;
+       /* Clear out the mangled name and RTL for the instantiation.  */
+       SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
+       SET_DECL_RTL (r, NULL_RTX);
 
        /* Don't try to expand the initializer until someone tries to use
           this variable; otherwise we run into circular dependencies.  */
        DECL_INITIAL (r) = NULL_TREE;
-       DECL_RTL (r) = 0;
+       SET_DECL_RTL (r, NULL_RTX);
        DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
 
        /* For __PRETTY_FUNCTION__ we have to adjust the initializer.  */
        if (DECL_PRETTY_FUNCTION_P (r))
          {
-           DECL_INITIAL (r) = tsubst (DECL_INITIAL (t),
-                                      args,
-                                      /*complain=*/1,
-                                      NULL_TREE);
+           const char *const name = (*decl_printable_name)
+                               (current_function_decl, 2);
+           DECL_INITIAL (r) = cp_fname_init (name);
            TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r));
          }
 
@@ -5939,8 +6052,8 @@ tsubst_decl (t, args, type, in_decl)
          register_local_specialization (r, t);
 
        TREE_CHAIN (r) = NULL_TREE;
-       if (TREE_CODE (r) == VAR_DECL && TREE_CODE (type) == VOID_TYPE)
-         cp_error_at ("instantiation of `%D' as type void", r);
+       if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
+         cp_error_at ("instantiation of `%D' as type `%T'", r, type);
       }
       break;
 
@@ -5978,6 +6091,16 @@ tsubst_arg_types (arg_types, args, complain, in_decl)
   type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
   if (type == error_mark_node)
     return error_mark_node;
+  if (VOID_TYPE_P (type))
+    {
+      if (complain)
+        {
+          error ("invalid parameter type `%T'", type);
+          if (in_decl)
+            cp_error_at ("in declaration `%D'", in_decl);
+        }
+      return error_mark_node;
+    }
 
   /* Do array-to-pointer, function-to-pointer conversion, and ignore
      top-level qualifiers as required.  */
@@ -6022,7 +6145,7 @@ tsubst_function_type (t, args, complain, in_decl)
   /* The TYPE_CONTEXT is not used for function/method types.  */
   my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
 
-  /* Substitue the return type.  */
+  /* Substitute the return type.  */
   return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
   if (return_type == error_mark_node)
     return error_mark_node;
@@ -6049,7 +6172,7 @@ tsubst_function_type (t, args, complain, in_decl)
             -- Attempting to create "pointer to member of T" when T
             is not a class type.  */
          if (complain)
-           cp_error ("creating pointer to member function of non-class type `%T'",
+           error ("creating pointer to member function of non-class type `%T'",
                      r);
          return error_mark_node;
        }
@@ -6149,7 +6272,7 @@ tsubst (t, args, complain, in_decl)
     return error_mark_node;
 
   if (DECL_P (t))
-    return tsubst_decl (t, args, type, in_decl);
+    return tsubst_decl (t, args, type);
 
   switch (TREE_CODE (t))
     {
@@ -6161,7 +6284,6 @@ tsubst (t, args, complain, in_decl)
 
     case ERROR_MARK:
     case IDENTIFIER_NODE:
-    case OP_IDENTIFIER:
     case VOID_TYPE:
     case REAL_TYPE:
     case COMPLEX_TYPE:
@@ -6227,7 +6349,7 @@ tsubst (t, args, complain, in_decl)
                 Attempting to create an array with a size that is
                 zero or negative.  */
            if (complain)
-             cp_error ("creating array with size zero (`%E')", max);
+             error ("creating array with size zero (`%E')", max);
 
            return error_mark_node;
          }
@@ -6275,7 +6397,7 @@ tsubst (t, args, complain, in_decl)
                  {
                    my_friendly_assert (TYPE_P (arg), 0);
                    return cp_build_qualified_type_real
-                     (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t),
+                     (arg, cp_type_quals (arg) | cp_type_quals (t),
                       complain);
                  }
                else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
@@ -6298,7 +6420,8 @@ tsubst (t, args, complain, in_decl)
                    r = lookup_template_class (arg, 
                                               argvec, in_decl, 
                                               DECL_CONTEXT (arg),
-                                              /*entering_scope=*/0);
+                                              /*entering_scope=*/0,
+                                              complain);
                    return cp_build_qualified_type_real (r, 
                                                         TYPE_QUALS (t),
                                                         complain);
@@ -6325,15 +6448,15 @@ tsubst (t, args, complain, in_decl)
          case TEMPLATE_TYPE_PARM:
          case TEMPLATE_TEMPLATE_PARM:
          case BOUND_TEMPLATE_TEMPLATE_PARM:
-           if (CP_TYPE_QUALS (t))
+           if (cp_type_quals (t))
              {
                r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
-               r = cp_build_qualified_type_real (r, CP_TYPE_QUALS (t),
+               r = cp_build_qualified_type_real (r, cp_type_quals (t),
                                                  complain);
              }
            else
              {
-               r = copy_node (t);
+               r = copy_type (t);
                TEMPLATE_TYPE_PARM_INDEX (r)
                  = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
                                                r, levels);
@@ -6398,8 +6521,13 @@ tsubst (t, args, complain, in_decl)
            && value == TREE_VALUE (t)
            && chain == TREE_CHAIN (t))
          return t;
-       result = hash_tree_cons (purpose, value, chain);
-       TREE_PARMLIST (result) = TREE_PARMLIST (t);
+       if (TREE_PARMLIST (t))
+         {
+           result = tree_cons (purpose, value, chain);
+           TREE_PARMLIST (result) = 1;
+         }
+       else
+         result = hash_tree_cons (purpose, value, chain);
        return result;
       }
     case TREE_VEC:
@@ -6432,7 +6560,7 @@ tsubst (t, args, complain, in_decl)
       {
        enum tree_code code;
 
-       if (type == TREE_TYPE (t))
+       if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
          return t;
 
        code = TREE_CODE (t);
@@ -6459,9 +6587,9 @@ tsubst (t, args, complain, in_decl)
                             last_file != input_filename))
              {
                if (TREE_CODE (type) == VOID_TYPE)
-                 cp_error ("forming reference to void");
+                 error ("forming reference to void");
                else
-                 cp_error ("forming %s to reference type `%T'",
+                 error ("forming %s to reference type `%T'",
                            (code == POINTER_TYPE) ? "pointer" : "reference",
                            type);
                last_line = lineno;
@@ -6471,7 +6599,11 @@ tsubst (t, args, complain, in_decl)
            return error_mark_node;
          }
        else if (code == POINTER_TYPE)
-         r = build_pointer_type (type);
+         {
+           r = build_pointer_type (type);
+           if (TREE_CODE (type) == METHOD_TYPE)
+             r = build_ptrmemfunc_type (r);
+         }
        else
          r = build_reference_type (type);
        r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
@@ -6495,11 +6627,34 @@ tsubst (t, args, complain, in_decl)
               -- Attempting to create "pointer to member of T" when T
                  is not a class type.  */
            if (complain)
-             cp_error ("creating pointer to member of non-class type `%T'", 
+             error ("creating pointer to member of non-class type `%T'", 
                        r);
            return error_mark_node;
          }
-       return build_offset_type (r, type);
+       if (TREE_CODE (type) == REFERENCE_TYPE)
+         {
+           if (complain)
+             error ("creating pointer to member reference type `%T'", type);
+           
+           return error_mark_node;
+         }
+       my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231);
+       if (TREE_CODE (type) == FUNCTION_TYPE)
+         /* This is really a method type. The cv qualifiers of the
+            this pointer should _not_ be determined by the cv
+            qualifiers of the class type.  They should be held
+            somewhere in the FUNCTION_TYPE, but we don't do that at
+            the moment.  Consider
+               typedef void (Func) () const;
+
+               template <typename T1> void Foo (Func T1::*);
+
+             */
+         return build_cplus_method_type (TYPE_MAIN_VARIANT (r),
+                                         TREE_TYPE (type),
+                                         TYPE_ARG_TYPES (type));
+       else
+         return build_offset_type (r, type);
       }
     case FUNCTION_TYPE:
     case METHOD_TYPE:
@@ -6557,7 +6712,7 @@ tsubst (t, args, complain, in_decl)
            || TREE_CODE (type) == REFERENCE_TYPE)
          {
            if (complain)
-             cp_error ("creating array of `%T'", type);
+             error ("creating array of `%T'", type);
            return error_mark_node;
          }
 
@@ -6603,7 +6758,7 @@ tsubst (t, args, complain, in_decl)
        if (!IS_AGGR_TYPE (ctx))
          {
            if (complain)
-             cp_error ("`%T' is not a class, struct, or union type",
+             error ("`%T' is not a class, struct, or union type",
                        ctx);
            return error_mark_node;
          }
@@ -6630,11 +6785,23 @@ tsubst (t, args, complain, in_decl)
        if (f == error_mark_node)
          return f;
        return cp_build_qualified_type_real (f, 
-                                            CP_TYPE_QUALS (f) 
-                                            | CP_TYPE_QUALS (t),
+                                            cp_type_quals (f) 
+                                            | cp_type_quals (t),
                                             complain);
       }
 
+    case UNBOUND_CLASS_TEMPLATE:
+      {
+       tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
+                                    in_decl, /*entering_scope=*/1);
+       tree name = TYPE_IDENTIFIER (t);
+
+       if (ctx == error_mark_node || name == error_mark_node)
+         return error_mark_node;
+
+       return make_unbound_class_template (ctx, name, complain);
+      }
+
     case INDIRECT_REF:
       {
        tree e = tsubst (TREE_OPERAND (t, 0), args, complain,
@@ -6662,7 +6829,7 @@ tsubst (t, args, complain, in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return build_parse_node (ARRAY_REF, e1, e2, tsubst_expr);
+       return build_nt (ARRAY_REF, e1, e2, tsubst_expr);
       }
 
     case CALL_EXPR:
@@ -6689,7 +6856,7 @@ tsubst (t, args, complain, in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return build_parse_node (TREE_CODE (t), e1, e2);
+       return build_nt (TREE_CODE (t), e1, e2);
       }
 
     case TYPEOF_TYPE:
@@ -6702,24 +6869,6 @@ tsubst (t, args, complain, in_decl)
        return TREE_TYPE (e1); 
       }
 
-    case FUNCTION_NAME:
-      {
-       const char *name;
-       int len;
-       tree type;
-       tree str;
-
-       /* This code should match declare_hidden_char_array in
-          c-common.c.  */
-       name = (*decl_printable_name) (current_function_decl, 2);
-       len = strlen (name) + 1;
-       type =  build_array_type (char_type_node,
-                                 build_index_type (build_int_2 (len, 0)));
-       str = build_string (len, name);
-       TREE_TYPE (str) = type;
-       return str;
-      }
-
     default:
       sorry ("use of `%s' in template",
             tree_code_name [(int) TREE_CODE (t)]);
@@ -6813,7 +6962,7 @@ tsubst_copy (t, args, complain, in_decl)
 
     case LOOKUP_EXPR:
       {
-       /* We must tsbust into a LOOKUP_EXPR in case the names to
+       /* We must tsubst into a LOOKUP_EXPR in case the names to
           which it refers is a conversion operator; in that case the
           name will change.  We avoid making unnecessary copies,
           however.  */
@@ -6841,10 +6990,6 @@ tsubst_copy (t, args, complain, in_decl)
         tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
 
     case INDIRECT_REF:
-    case PREDECREMENT_EXPR:
-    case PREINCREMENT_EXPR:
-    case POSTDECREMENT_EXPR:
-    case POSTINCREMENT_EXPR:
     case NEGATE_EXPR:
     case TRUTH_NOT_EXPR:
     case BIT_NOT_EXPR:
@@ -6897,6 +7042,10 @@ tsubst_copy (t, args, complain, in_decl)
     case SCOPE_REF:
     case DOTSTAR_EXPR:
     case MEMBER_REF:
+    case PREDECREMENT_EXPR:
+    case PREINCREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
       return build_nt
        (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
         tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
@@ -7053,6 +7202,8 @@ tsubst_copy (t, args, complain, in_decl)
     case METHOD_TYPE:
     case ARRAY_TYPE:
     case TYPENAME_TYPE:
+    case UNBOUND_CLASS_TEMPLATE:
+    case TYPEOF_TYPE:
     case TYPE_DECL:
       return tsubst (t, args, complain, in_decl);
 
@@ -7060,10 +7211,7 @@ tsubst_copy (t, args, complain, in_decl)
       if (IDENTIFIER_TYPENAME_P (t))
        {
          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));
+         return mangle_conv_op_name_for_type (new_type);
        }
       else
        return t;
@@ -7083,9 +7231,6 @@ tsubst_copy (t, args, complain, in_decl)
                                        in_decl),
                           tsubst (TREE_TYPE (t), args, complain, in_decl));
 
-    case FUNCTION_NAME:
-      return tsubst (t, args, complain, in_decl);
-
     default:
       return t;
     }
@@ -7099,7 +7244,7 @@ tsubst_expr (t, args, complain, in_decl)
      int complain;
      tree in_decl;
 {
-  tree stmt;
+  tree stmt, tmp;
 
   if (t == NULL_TREE || t == error_mark_node)
     return t;
@@ -7107,6 +7252,9 @@ tsubst_expr (t, args, complain, in_decl)
   if (processing_template_decl)
     return tsubst_copy (t, args, complain, in_decl);
 
+  if (!statement_code_p (TREE_CODE (t)))
+    return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+    
   switch (TREE_CODE (t))
     {
     case RETURN_INIT:
@@ -7114,7 +7262,6 @@ tsubst_expr (t, args, complain, in_decl)
       finish_named_return_value
        (TREE_OPERAND (t, 0),
         tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl));
-      tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
       break;
 
     case CTOR_INITIALIZER:
@@ -7128,7 +7275,6 @@ tsubst_expr (t, args, complain, in_decl)
        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;
       }
 
@@ -7144,6 +7290,12 @@ tsubst_expr (t, args, complain, in_decl)
                                     args, complain, in_decl));
       break;
 
+    case USING_STMT:
+      prep_stmt (t);
+      do_using_directive (tsubst_expr (USING_STMT_NAMESPACE (t),
+                                      args, complain, in_decl));
+      break;
+      
     case DECL_STMT:
       {
        tree decl;
@@ -7153,11 +7305,22 @@ tsubst_expr (t, args, complain, in_decl)
        decl = DECL_STMT_DECL (t);
        if (TREE_CODE (decl) == LABEL_DECL)
          finish_label_decl (DECL_NAME (decl));
+       else if (TREE_CODE (decl) == USING_DECL)
+         {
+           tree scope = DECL_INITIAL (decl);
+           tree name = DECL_NAME (decl);
+           
+           scope = tsubst_expr (scope, args, complain, in_decl);
+           do_local_using_decl (build_nt (SCOPE_REF, scope, name));
+         }
        else
          {
            init = DECL_INITIAL (decl);
            decl = tsubst (decl, args, complain, in_decl);
-           init = tsubst_expr (init, args, complain, in_decl);
+           if (DECL_PRETTY_FUNCTION_P (decl))
+             init = DECL_INITIAL (decl);
+           else
+             init = tsubst_expr (init, args, complain, in_decl);
            if (decl != error_mark_node)
              {
                 if (TREE_CODE (decl) != TYPE_DECL)
@@ -7176,17 +7339,21 @@ tsubst_expr (t, args, complain, in_decl)
                cp_finish_decl (decl, init, NULL_TREE, 0);
              }
          }
-       return decl;
+
+       /* A DECL_STMT can also be used as an expression, in the condition
+          clause of a if/for/while construct.  If we aren't followed by
+          another statement, return our decl.  */
+       if (TREE_CHAIN (t) == NULL_TREE)
+         return decl;
       }
+      break;
 
     case FOR_STMT:
       {
-       tree tmp;
        prep_stmt (t);
 
        stmt = begin_for_stmt ();
-       for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
-         tsubst_expr (tmp, args, complain, in_decl);
+       tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
        finish_for_init_stmt (stmt);
        finish_for_cond (tsubst_expr (FOR_COND (t), args,
                                      complain, in_decl),
@@ -7224,8 +7391,6 @@ tsubst_expr (t, args, complain, in_decl)
 
     case IF_STMT:
       {
-       tree tmp;
-
        prep_stmt (t);
        stmt = begin_if_stmt ();
        finish_if_stmt_cond (tsubst_expr (IF_COND (t),
@@ -7251,15 +7416,18 @@ tsubst_expr (t, args, complain, in_decl)
 
     case COMPOUND_STMT:
       {
-       tree substmt;
-
        prep_stmt (t);
-       stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
-       for (substmt = COMPOUND_BODY (t); 
-            substmt != NULL_TREE;
-            substmt = TREE_CHAIN (substmt))
-         tsubst_expr (substmt, args, complain, in_decl);
-       return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
+       if (COMPOUND_STMT_BODY_BLOCK (t))
+         stmt = begin_function_body ();
+       else
+         stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
+
+       tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+
+       if (COMPOUND_STMT_BODY_BLOCK (t))
+         finish_function_body (stmt);
+       else
+         finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
       }
       break;
 
@@ -7300,15 +7468,15 @@ tsubst_expr (t, args, complain, in_decl)
 
     case GOTO_STMT:
       prep_stmt (t);
-      t = GOTO_DESTINATION (t);
-      if (TREE_CODE (t) != LABEL_DECL)
+      tmp = GOTO_DESTINATION (t);
+      if (TREE_CODE (tmp) != LABEL_DECL)
        /* Computed goto's must be tsubst'd into.  On the other hand,
           non-computed gotos must not be; the identifier in question
           will have no binding.  */
-       t = tsubst_expr (t, args, complain, in_decl);
+       tmp = tsubst_expr (tmp, args, complain, in_decl);
       else
-       t = DECL_NAME (t);
-      finish_goto_stmt (t);
+       tmp = DECL_NAME (tmp);
+      finish_goto_stmt (tmp);
       break;
 
     case ASM_STMT:
@@ -7334,8 +7502,6 @@ tsubst_expr (t, args, complain, in_decl)
        }
       else
        {
-         tree handler;
-
          if (FN_TRY_BLOCK_P (t))
            stmt = begin_function_try_block ();
          else
@@ -7348,9 +7514,7 @@ tsubst_expr (t, args, complain, in_decl)
          else
            finish_try_block (stmt);
 
-         handler = TRY_HANDLERS (t);
-         for (; handler; handler = TREE_CHAIN (handler))
-           tsubst_expr (handler, args, complain, in_decl);
+         tsubst_expr (TRY_HANDLERS (t), args, complain, in_decl);
          if (FN_TRY_BLOCK_P (t))
            finish_function_handler_sequence (stmt);
          else
@@ -7361,7 +7525,6 @@ tsubst_expr (t, args, complain, in_decl)
     case HANDLER:
       {
        tree decl;
-       tree blocks;
 
        prep_stmt (t);
        stmt = begin_handler ();
@@ -7376,59 +7539,26 @@ tsubst_expr (t, args, complain, in_decl)
          }
        else
          decl = NULL_TREE;
-       blocks = finish_handler_parms (decl, stmt);
+       finish_handler_parms (decl, stmt);
        tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
-       finish_handler (blocks, stmt);
+       finish_handler (stmt);
       }
       break;
 
     case TAG_DEFN:
       prep_stmt (t);
-      t = TREE_TYPE (t);
-      tsubst (t, args, complain, NULL_TREE);
+      tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
+      break;
+
+    case CTOR_STMT:
+      add_stmt (copy_node (t));
       break;
 
     default:
-      return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+      abort ();
     }
-  return NULL_TREE;
-}
-
-/* TMPL is a TEMPLATE_DECL for a cloned constructor or destructor.
-   Instantiate it with the ARGS.  */
 
-static tree
-instantiate_clone (tmpl, args)
-     tree tmpl;
-     tree args;
-{
-  tree spec;
-  tree clone;
-
-  /* Instantiated the cloned function, rather than the clone.  */
-  spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), args);
-
-  /* Then, see if we've already cloned the instantiation.  */
-  for (clone = TREE_CHAIN (spec);
-       clone && DECL_CLONED_FUNCTION_P (clone);
-       clone = TREE_CHAIN (clone))
-    if (DECL_NAME (clone) == DECL_NAME (tmpl))
-      return clone;
-
-  /* If we haven't, do so know.  */
-  if (!clone)
-    clone_function_decl (spec, /*update_method_vec_p=*/0);
-
-  /* Look again.  */
-  for (clone = TREE_CHAIN (spec);
-       clone && DECL_CLONED_FUNCTION_P (clone);
-       clone = TREE_CHAIN (clone))
-    if (DECL_NAME (clone) == DECL_NAME (tmpl))
-      return clone;
-
-  /* We should always have found the clone by now.  */
-  my_friendly_abort (20000411);
-  return NULL_TREE;
+  return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
 }
 
 /* Instantiate the indicated variable or function template TMPL with
@@ -7438,7 +7568,6 @@ tree
 instantiate_template (tmpl, targ_ptr)
      tree tmpl, targ_ptr;
 {
-  tree clone;
   tree fndecl;
   tree gen_tmpl;
   tree spec;
@@ -7452,8 +7581,21 @@ instantiate_template (tmpl, targ_ptr)
 
   /* If this function is a clone, handle it specially.  */
   if (DECL_CLONED_FUNCTION_P (tmpl))
-    return instantiate_clone (tmpl, targ_ptr);
-
+    {
+      tree spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr);
+      tree clone;
+      
+      /* Look for the clone. */
+      for (clone = TREE_CHAIN (spec);
+          clone && DECL_CLONED_FUNCTION_P (clone);
+          clone = TREE_CHAIN (clone))
+       if (DECL_NAME (clone) == DECL_NAME (tmpl))
+         return clone;
+      /* We should always have found the clone by now.  */
+      my_friendly_abort (20000411);
+      return NULL_TREE;
+    }
+  
   /* Check to see if we already have this specialization.  */
   spec = retrieve_specialization (tmpl, targ_ptr);
   if (spec != NULL_TREE)
@@ -7485,8 +7627,8 @@ instantiate_template (tmpl, targ_ptr)
          tree nt = target_type (t);
          if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_MAIN_DECL (nt)))
            {
-             cp_error ("type `%T' composed from a local class is not a valid template-argument", t);
-             cp_error ("  trying to instantiate `%D'", gen_tmpl);
+             error ("type `%T' composed from a local class is not a valid template-argument", t);
+             error ("  trying to instantiate `%D'", gen_tmpl);
              return error_mark_node;
            }
        }
@@ -7503,33 +7645,15 @@ instantiate_template (tmpl, targ_ptr)
     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);
+     instantiate all the alternate entry points as well.  We do this
+     by cloning the instantiation of the main entry point, not by
+     instantiating the template clones.  */
+  if (TREE_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (TREE_CHAIN (gen_tmpl)))
+    clone_function_decl (fndecl, /*update_method_vec_p=*/0);
 
   return fndecl;
 }
 
-/* Push the name of the class template into the scope of the instantiation.  */
-
-void
-overload_template_name (type)
-     tree type;
-{
-  tree id = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type));
-  tree decl;
-
-  if (IDENTIFIER_CLASS_VALUE (id)
-      && TREE_TYPE (IDENTIFIER_CLASS_VALUE (id)) == type)
-    return;
-
-  decl = build_decl (TYPE_DECL, id, type);
-  DECL_ARTIFICIAL (decl) = 1;
-  pushdecl_class_level (decl);
-}
-
 /* The FN is a TEMPLATE_DECL for a function.  The ARGS are the
    arguments that are being used when calling it.  TARGS is a vector
    into which the deduced template arguments are placed.  
@@ -7538,10 +7662,8 @@ overload_template_name (type)
    all the types, and 1 for complete failure.  An error message will be
    printed only for an incomplete match.
 
-   If FN is a conversion operator, RETURN_TYPE is the type desired as
-   the result of the conversion operator.
-
-   TPARMS is a vector of template parameters.
+   If FN is a conversion operator, or we are trying to produce a specific
+   specialization, RETURN_TYPE is the return type desired.
 
    The EXPLICIT_TARGS are explicit template arguments provided via a
    template-id.
@@ -7557,21 +7679,28 @@ overload_template_name (type)
      [temp.deduct.conv].
 
    DEDUCE_EXACT:
+     We are deducing arguments when doing an explicit instantiation
+     as in [temp.explicit], when determining an explicit specialization
+     as in [temp.expl.spec], or when taking the address of a function
+     template, as in [temp.deduct.funcaddr]. 
+
+   DEDUCE_ORDER:
      We are deducing arguments when calculating the partial
      ordering between specializations of function or class
-     templates, as in [temp.func.order] and [temp.class.order],
-     when doing an explicit instantiation as in [temp.explicit],
-     when determining an explicit specialization as in
-     [temp.expl.spec], or when taking the address of a function
-     template, as in [temp.deduct.funcaddr]. 
+     templates, as in [temp.func.order] and [temp.class.order].
 
-   The other arguments are as for type_unification.  */
+   LEN is the number of parms to consider before returning success, or -1
+   for all.  This is used in partial ordering to avoid comparing parms for
+   which no actual argument was passed, since they are not considered in
+   overload resolution (and are explicitly excluded from consideration in
+   partial ordering in [temp.func.order]/6).  */
 
 int
 fn_type_unification (fn, explicit_targs, targs, args, return_type,
-                    strict)
+                    strict, len)
      tree fn, explicit_targs, targs, args, return_type;
      unification_kind_t strict;
+     int len;
 {
   tree parms;
   tree fntype;
@@ -7619,21 +7748,17 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
     }
      
   parms = TYPE_ARG_TYPES (fntype);
-
-  if (DECL_CONV_FN_P (fn))
-    {
-      /* This is a template conversion operator.  Remove `this', since
-         we could be comparing conversions from different classes.  */
-      parms = TREE_CHAIN (parms);
-      args = TREE_CHAIN (args);
-      my_friendly_assert (return_type != NULL_TREE, 20000227);
-    }
+  /* Never do unification on the 'this' parameter.  */
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+    parms = TREE_CHAIN (parms);
   
   if (return_type)
     {
       /* We've been given a return type to match, prepend it.  */
       parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
       args = tree_cons (NULL_TREE, return_type, args);
+      if (len >= 0)
+       ++len;
     }
 
   /* We allow incomplete unification without an error message here
@@ -7642,7 +7767,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
      event.  */
   result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), 
                                  targs, parms, args, /*subr=*/0,
-                                 strict, /*allow_incomplete*/1);
+                                 strict, /*allow_incomplete*/1, len);
 
   if (result == 0) 
     /* All is well so far.  Now, check:
@@ -7668,12 +7793,14 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
    the argument passed to the call, or the type of the value
    initialized with the result of the conversion function.  */
 
-static void
+static int
 maybe_adjust_types_for_deduction (strict, parm, arg)
      unification_kind_t strict;
      tree* parm;
      tree* arg;
 {
+  int result = 0;
+  
   switch (strict)
     {
     case DEDUCE_CALL:
@@ -7692,8 +7819,30 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
 
     case DEDUCE_EXACT:
       /* There is nothing to do in this case.  */
-      return;
+      return 0;
 
+    case DEDUCE_ORDER:
+      /* DR 214. [temp.func.order] is underspecified, and leads to no
+         ordering between things like `T *' and `T const &' for `U *'.
+         The former has T=U and the latter T=U*. The former looks more
+         specialized and John Spicer considers it well-formed (the EDG
+         compiler accepts it).
+
+         John also confirms that deduction should proceed as in a function
+         call. Which implies the usual ARG and PARM conversions as DEDUCE_CALL.
+         However, in ordering, ARG can have REFERENCE_TYPE, but no argument
+         to an actual call can have such a type.
+         
+         If both ARG and PARM are REFERENCE_TYPE, we change neither.
+         If only ARG is a REFERENCE_TYPE, we look through that and then
+         proceed as with DEDUCE_CALL (which could further convert it).  */
+      if (TREE_CODE (*arg) == REFERENCE_TYPE)
+        {
+          if (TREE_CODE (*parm) == REFERENCE_TYPE)
+            return 0;
+          *arg = TREE_TYPE (*arg);
+        }
+      break;
     default:
       my_friendly_abort (0);
     }
@@ -7732,41 +7881,49 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
      type deduction.  */
   *parm = TYPE_MAIN_VARIANT (*parm);
   if (TREE_CODE (*parm) == REFERENCE_TYPE)
-    *parm = TREE_TYPE (*parm);
+    {
+      *parm = TREE_TYPE (*parm);
+      result |= UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
+    }
+  return result;
 }
 
-/* Like type_unification.
+/* Most parms like fn_type_unification.
 
    If SUBR is 1, we're being called recursively (to unify the
    arguments of a function or method parameter of a function
    template).  */
 
 static int
-type_unification_real (tparms, targs, parms, args, subr,
-                      strict, allow_incomplete)
-     tree tparms, targs, parms, args;
+type_unification_real (tparms, targs, xparms, xargs, subr,
+                      strict, allow_incomplete, xlen)
+     tree tparms, targs, xparms, xargs;
      int subr;
      unification_kind_t strict;
-     int allow_incomplete;
+     int allow_incomplete, xlen;
 {
   tree parm, arg;
   int i;
   int ntparms = TREE_VEC_LENGTH (tparms);
   int sub_strict;
+  int saw_undeduced = 0;
+  tree parms, args;
+  int len;
 
   my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
-  my_friendly_assert (parms == NULL_TREE 
-                     || TREE_CODE (parms) == TREE_LIST, 290);
+  my_friendly_assert (xparms == NULL_TREE 
+                     || TREE_CODE (xparms) == TREE_LIST, 290);
   /* ARGS could be NULL (via a call from parse.y to
      build_x_function_call).  */
-  if (args)
-    my_friendly_assert (TREE_CODE (args) == TREE_LIST, 291);
+  if (xargs)
+    my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
   my_friendly_assert (ntparms > 0, 292);
 
   switch (strict)
     {
     case DEDUCE_CALL:
-      sub_strict = UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_DERIVED;
+      sub_strict = (UNIFY_ALLOW_OUTER_LEVEL | UNIFY_ALLOW_MORE_CV_QUAL
+                    | UNIFY_ALLOW_DERIVED);
       break;
       
     case DEDUCE_CONV:
@@ -7776,11 +7933,23 @@ type_unification_real (tparms, targs, parms, args, subr,
     case DEDUCE_EXACT:
       sub_strict = UNIFY_ALLOW_NONE;
       break;
+    
+    case DEDUCE_ORDER:
+      sub_strict = UNIFY_ALLOW_NONE;
+      break;
       
     default:
       my_friendly_abort (0);
     }
 
+  if (xlen == 0)
+    return 0;
+
+ again:
+  parms = xparms;
+  args = xargs;
+  len = xlen;
+
   while (parms
         && parms != void_list_node
         && args
@@ -7814,7 +7983,7 @@ type_unification_real (tparms, targs, parms, args, subr,
              arg = NULL_TREE;
            }
 
-         if (strict == DEDUCE_EXACT)
+         if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
            {
              if (same_type_p (parm, type))
                continue;
@@ -7847,12 +8016,20 @@ type_unification_real (tparms, targs, parms, args, subr,
            }
          arg = TREE_TYPE (arg);
        }
+      
+      {
+        int arg_strict = sub_strict;
+        
+        if (!subr)
+         arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
 
-      if (!subr)
-       maybe_adjust_types_for_deduction (strict, &parm, &arg);
+        if (unify (tparms, targs, parm, arg, arg_strict))
+          return 1;
+      }
 
-      if (unify (tparms, targs, parm, arg, sub_strict))
-        return 1;
+      /* Are we done with the interesting parms?  */
+      if (--len == 0)
+       goto done;
     }
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
@@ -7863,10 +8040,23 @@ type_unification_real (tparms, targs, parms, args, subr,
       && parms != void_list_node
       && TREE_PURPOSE (parms) == NULL_TREE)
     return 1;
+
+ done:
   if (!subr)
     for (i = 0; i < ntparms; i++)
       if (TREE_VEC_ELT (targs, i) == NULL_TREE)
        {
+         tree tparm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
+
+         /* If this is an undeduced nontype parameter that depends on
+            a type parameter, try another pass; its type may have been
+            deduced from a later argument than the one from which
+            this parameter can be deduced.  */
+         if (TREE_CODE (tparm) == PARM_DECL
+             && uses_template_parms (TREE_TYPE (tparm))
+             && !saw_undeduced++)
+           goto again;
+
          if (!allow_incomplete)
            error ("incomplete type unification");
          return 2;
@@ -7996,7 +8186,7 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
   if (uses_template_parms (arg))
     return 1;
 
-  maybe_adjust_types_for_deduction (strict, &parm, &arg);
+  sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
 
   /* We don't copy orig_targs for this because if we have already deduced
      some template args from previous args, unify would complain when we
@@ -8040,6 +8230,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
@@ -8052,7 +8288,6 @@ try_class_unification (tparms, targs, parm, arg)
      tree parm;
      tree arg;
 {
-  int i;
   tree copy_of_targs;
 
   if (!CLASSTYPE_TEMPLATE_INFO (arg)
@@ -8090,14 +8325,13 @@ 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
@@ -8236,11 +8470,11 @@ check_cv_quals_for_unify (strict, arg, parm)
      tree arg;
      tree parm;
 {
-  if (!(strict & UNIFY_ALLOW_MORE_CV_QUAL)
+  if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
       && !at_least_as_qualified_p (arg, parm))
     return 0;
 
-  if (!(strict & UNIFY_ALLOW_LESS_CV_QUAL)
+  if (!(strict & (UNIFY_ALLOW_LESS_CV_QUAL | UNIFY_ALLOW_OUTER_LESS_CV_QUAL))
       && !at_least_as_qualified_p (parm, arg))
     return 0;
 
@@ -8254,7 +8488,8 @@ check_cv_quals_for_unify (strict, arg, parm)
      UNIFY_ALLOW_NONE:
        Require an exact match between PARM and ARG.
      UNIFY_ALLOW_MORE_CV_QUAL:
-       Allow the deduced ARG to be more cv-qualified than ARG.
+       Allow the deduced ARG to be more cv-qualified (by qualification
+       conversion) than ARG.
      UNIFY_ALLOW_LESS_CV_QUAL:
        Allow the deduced ARG to be less cv-qualified than ARG.
      UNIFY_ALLOW_DERIVED:
@@ -8263,7 +8498,27 @@ check_cv_quals_for_unify (strict, arg, parm)
        ARG.
      UNIFY_ALLOW_INTEGER:
        Allow any integral type to be deduced.  See the TEMPLATE_PARM_INDEX
-       case for more information.  */
+       case for more information. 
+     UNIFY_ALLOW_OUTER_LEVEL:
+       This is the outermost level of a deduction. Used to determine validity
+       of qualification conversions. A valid qualification conversion must
+       have const qualified pointers leading up to the inner type which
+       requires additional CV quals, except at the outer level, where const
+       is not required [conv.qual]. It would be normal to set this flag in
+       addition to setting UNIFY_ALLOW_MORE_CV_QUAL.
+     UNIFY_ALLOW_OUTER_MORE_CV_QUAL:
+       This is the outermost level of a deduction, and PARM can be more CV
+       qualified at this point.
+     UNIFY_ALLOW_OUTER_LESS_CV_QUAL:
+       This is the outermost level of a deduction, and PARM can be less CV
+       qualified at this point.
+     UNIFY_ALLOW_MAX_CORRECTION:
+       This is an INTEGER_TYPE's maximum value.  Used if the range may
+       have been derived from a size specification, such as an array size.
+       If the size was given by a nontype template parameter N, the maximum
+       value will have the form N-1.  The flag says that we can (and indeed
+       must) unify N with (ARG + 1), an exception to the normal rules on
+       folding PARM.  */
 
 static int
 unify (tparms, targs, parm, arg, strict)
@@ -8273,6 +8528,7 @@ unify (tparms, targs, parm, arg, strict)
   int idx;
   tree targ;
   tree tparm;
+  int strict_in = strict;
 
   /* I don't think this will do the right thing with respect to types.
      But the only case I've seen it in so far has been array bounds, where
@@ -8299,17 +8555,32 @@ unify (tparms, targs, parm, arg, strict)
      cv-qualification mismatches.  */
   if (TREE_CODE (arg) == TREE_CODE (parm)
       && TYPE_P (arg)
+      /* It is the elements of the array which hold the cv quals of an array
+         type, and the elements might be template type parms. We'll check
+         when we recurse.  */
+      && TREE_CODE (arg) != ARRAY_TYPE
       /* We check the cv-qualifiers when unifying with template type
         parameters below.  We want to allow ARG `const T' to unify with
         PARM `T' for example, when computing which of two templates
         is more specialized, for example.  */
       && TREE_CODE (arg) != TEMPLATE_TYPE_PARM
-      && !check_cv_quals_for_unify (strict, arg, parm))
+      && !check_cv_quals_for_unify (strict_in, arg, parm))
     return 1;
 
+  if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
+      && TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
+    strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
+  strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
+  strict &= ~UNIFY_ALLOW_DERIVED;
+  strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
+  strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
+  strict &= ~UNIFY_ALLOW_MAX_CORRECTION;
+  
   switch (TREE_CODE (parm))
     {
     case TYPENAME_TYPE:
+    case SCOPE_REF:
+    case UNBOUND_CLASS_TEMPLATE:
       /* In a type which contains a nested-name-specifier, template
         argument values cannot be deduced for template parameters used
         within the nested-name-specifier.  */
@@ -8339,16 +8610,18 @@ unify (tparms, targs, parm, arg, strict)
 
       if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
        {
-         /* ARG must be constructed from a template class.  */
-         if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
+         /* ARG must be constructed from a template class or a template
+            template parameter.  */
+         if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
+             && (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 argvec = TYPE_TI_ARGS (arg);
            tree argtmplvec
-             = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
+             = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
            int i;
 
            /* The parameter and argument roles have to be switched here 
@@ -8377,7 +8650,7 @@ unify (tparms, targs, parm, arg, strict)
                  return 1;
              }
          }
-         arg = CLASSTYPE_TI_TEMPLATE (arg);
+         arg = TYPE_TI_TEMPLATE (arg);
 
          /* Fall through to deduce template name.  */
        }
@@ -8399,7 +8672,7 @@ unify (tparms, targs, parm, arg, strict)
             a match unless we are allowing additional qualification.
             If ARG is `const int' and PARM is just `T' that's OK;
             that binds `const int' to `T'.  */
-         if (!check_cv_quals_for_unify (strict | UNIFY_ALLOW_LESS_CV_QUAL, 
+         if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, 
                                         arg, parm))
            return 1;
 
@@ -8407,8 +8680,8 @@ unify (tparms, targs, parm, arg, strict)
             PARM is `const T'.  Then, T should be `volatile int'.  */
          arg = 
            cp_build_qualified_type_real (arg,
-                                         CP_TYPE_QUALS (arg) 
-                                         & ~CP_TYPE_QUALS (parm),
+                                         cp_type_quals (arg) 
+                                         & ~cp_type_quals (parm),
                                          /*complain=*/0);
          if (arg == error_mark_node)
            return 1;
@@ -8429,6 +8702,7 @@ unify (tparms, targs, parm, arg, strict)
         here.  */
       if (TREE_CODE (arg) == ARRAY_TYPE 
          && !uses_template_parms (arg)
+         && TYPE_DOMAIN (arg)
          && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (arg)))
              != INTEGER_CST))
        return 1;
@@ -8468,13 +8742,17 @@ unify (tparms, targs, parm, arg, strict)
         template-parameter exactly, except that a template-argument
         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 */;
+      tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
+      if (same_type_p (TREE_TYPE (arg), tparm))
+         /* OK */;
       else if ((strict & UNIFY_ALLOW_INTEGER)
-              && (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE
-                  || TREE_CODE (TREE_TYPE (parm)) == BOOLEAN_TYPE))
+              && (TREE_CODE (tparm) == INTEGER_TYPE
+                  || TREE_CODE (tparm) == BOOLEAN_TYPE))
        /* OK */;
+      else if (uses_template_parms (tparm))
+       /* We haven't deduced the type of this parameter yet.  Try again
+          later.  */
+       return 0;
       else
        return 1;
 
@@ -8483,8 +8761,6 @@ unify (tparms, targs, parm, arg, strict)
 
     case POINTER_TYPE:
       {
-       int sub_strict;
-
        if (TREE_CODE (arg) != POINTER_TYPE)
          return 1;
        
@@ -8496,28 +8772,34 @@ unify (tparms, targs, parm, arg, strict)
 
           We pass down STRICT here rather than UNIFY_ALLOW_NONE.
           This will allow for additional cv-qualification of the
-          pointed-to types if appropriate.  In general, this is a bit
-          too generous; we are only supposed to allow qualification
-          conversions and this method will allow an ARG of char** and
-          a deduced ARG of const char**.  However, overload
-          resolution will subsequently invalidate the candidate, so
-          this is probably OK.  */
-       sub_strict = strict;
+          pointed-to types if appropriate.  */
        
-       if (TREE_CODE (TREE_TYPE (arg)) != RECORD_TYPE)
+       if (TREE_CODE (TREE_TYPE (arg)) == RECORD_TYPE)
          /* The derived-to-base conversion only persists through one
             level of pointers.  */
-         sub_strict &= ~UNIFY_ALLOW_DERIVED;
+         strict |= (strict_in & UNIFY_ALLOW_DERIVED);
+
+       if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
+           && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+         {
+           /* Avoid getting confused about cv-quals; don't recurse here.
+              Pointers to members should really be just OFFSET_TYPE, not
+              this two-level nonsense... */
+
+           parm = TREE_TYPE (parm);
+           arg = TREE_TYPE (arg);
+           goto offset;
+         }
 
        return unify (tparms, targs, TREE_TYPE (parm), 
-                     TREE_TYPE (arg), sub_strict);
+                     TREE_TYPE (arg), strict);
       }
 
     case REFERENCE_TYPE:
       if (TREE_CODE (arg) != REFERENCE_TYPE)
        return 1;
       return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
-                   UNIFY_ALLOW_NONE);
+                   strict & UNIFY_ALLOW_MORE_CV_QUAL);
 
     case ARRAY_TYPE:
       if (TREE_CODE (arg) != ARRAY_TYPE)
@@ -8550,7 +8832,8 @@ unify (tparms, targs, parm, arg, strict)
            return 1;
          if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
              && unify (tparms, targs, TYPE_MAX_VALUE (parm),
-                       TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER))
+                       TYPE_MAX_VALUE (arg),
+                       UNIFY_ALLOW_INTEGER | UNIFY_ALLOW_MAX_CORRECTION))
            return 1;
        }
       /* We have already checked cv-qualification at the top of the
@@ -8607,7 +8890,7 @@ unify (tparms, targs, parm, arg, strict)
        {
          tree t = NULL_TREE;
 
-         if (strict & UNIFY_ALLOW_DERIVED)
+         if (strict_in & UNIFY_ALLOW_DERIVED)
            {
              /* First, we try to unify the PARM and ARG directly.  */
              t = try_class_unification (tparms, targs,
@@ -8658,9 +8941,10 @@ unify (tparms, targs, parm, arg, strict)
        return 1;
       return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
                                    TYPE_ARG_TYPES (arg), 1, 
-                                   DEDUCE_EXACT, 0);
+                                   DEDUCE_EXACT, 0, -1);
 
     case OFFSET_TYPE:
+    offset:
       if (TREE_CODE (arg) != OFFSET_TYPE)
        return 1;
       if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
@@ -8679,7 +8963,8 @@ unify (tparms, targs, parm, arg, strict)
       return 1;
 
     case MINUS_EXPR:
-      if (TREE_CODE (TREE_OPERAND (parm, 1)) == INTEGER_CST)
+      if (tree_int_cst_equal (TREE_OPERAND (parm, 1), integer_one_node)
+         && (strict_in & UNIFY_ALLOW_MAX_CORRECTION))
        {
          /* We handle this case specially, since it comes up with
             arrays.  In particular, something like:
@@ -8700,25 +8985,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)]);
@@ -8766,27 +9059,32 @@ mark_decl_instantiated (result, extern_p)
     defer_fn (result);
 }
 
-/* Given two function templates PAT1 and PAT2, and explicit template
-   arguments EXPLICIT_ARGS return:
+/* Given two function templates PAT1 and PAT2, return:
 
+   DEDUCE should be DEDUCE_EXACT or DEDUCE_ORDER.
+   
    1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
    -1 if PAT2 is more specialized than PAT1.
-   0 if neither is more specialized.  */
+   0 if neither is more specialized.
+
+   LEN is passed through to fn_type_unification.  */
    
 int
-more_specialized (pat1, pat2, explicit_args)
-     tree pat1, pat2, explicit_args;
+more_specialized (pat1, pat2, deduce, len)
+     tree pat1, pat2;
+     int deduce;
+     int len;
 {
   tree targs;
   int winner = 0;
 
-  targs
-    = get_bindings_overload (pat1, DECL_TEMPLATE_RESULT (pat2), explicit_args);
+  targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2),
+                             NULL_TREE, 0, deduce, len);
   if (targs)
     --winner;
 
-  targs
-    = get_bindings_overload (pat2, DECL_TEMPLATE_RESULT (pat1), explicit_args);
+  targs = get_bindings_real (pat2, DECL_TEMPLATE_RESULT (pat1),
+                             NULL_TREE, 0, deduce, len);
   if (targs)
     ++winner;
 
@@ -8823,12 +9121,12 @@ more_specialized_class (pat1, pat2)
    DECL from the function template FN, with the explicit template
    arguments EXPLICIT_ARGS.  If CHECK_RETTYPE is 1, the return type must
    also match.  Return NULL_TREE if no satisfactory arguments could be
-   found.  */
-
+   found.  DEDUCE and LEN are passed through to fn_type_unification.  */
+   
 static tree
-get_bindings_real (fn, decl, explicit_args, check_rettype)
+get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
      tree fn, decl, explicit_args;
-     int check_rettype;
+     int check_rettype, deduce, len;
 {
   int ntparms = DECL_NTPARMS (fn);
   tree targs = make_tree_vec (ntparms);
@@ -8865,18 +9163,16 @@ get_bindings_real (fn, decl, explicit_args, check_rettype)
        return NULL_TREE;
     }
 
-  /* If FN is a static member function, adjust the type of DECL
-     appropriately.  */
   decl_arg_types = TYPE_ARG_TYPES (decl_type);
-  if (DECL_STATIC_FUNCTION_P (fn) 
-      && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+  /* Never do unification on the 'this' parameter.  */
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
     decl_arg_types = TREE_CHAIN (decl_arg_types);
 
   i = fn_type_unification (fn, explicit_args, targs, 
                           decl_arg_types,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT);
+                          deduce, len);
 
   if (i != 0)
     return NULL_TREE;
@@ -8890,21 +9186,22 @@ tree
 get_bindings (fn, decl, explicit_args)
      tree fn, decl, explicit_args;
 {
-  return get_bindings_real (fn, decl, explicit_args, 1);
+  return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1);
 }
 
-/* But for more_specialized, we only care about the parameter types.  */
+/* But for resolve_overloaded_unification, we only care about the parameter
+   types.  */
 
 static tree
 get_bindings_overload (fn, decl, explicit_args)
      tree fn, decl, explicit_args;
 {
-  return get_bindings_real (fn, decl, explicit_args, 0);
+  return get_bindings_real (fn, decl, explicit_args, 0, DEDUCE_EXACT, -1);
 }
 
 /* Return the innermost template arguments that, when applied to a
    template specialization whose innermost template parameters are
-   TPARMS, and whose specialization arguments are ARGS, yield the
+   TPARMS, and whose specialization arguments are PARMS, yield the
    ARGS.  
 
    For example, suppose we have:
@@ -8924,30 +9221,30 @@ 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 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.  */
+   template itself.  If there is no most specialized template,
+   error_mark_node is returned.  If there are no templates at all,
+   NULL_TREE is returned.  */
 
 tree
-most_specialized_instantiation (instantiations, explicit_args)
+most_specialized_instantiation (instantiations)
      tree instantiations;
-     tree explicit_args;
 {
   tree fn, champ;
   int fate;
@@ -8958,8 +9255,8 @@ most_specialized_instantiation (instantiations, explicit_args)
   champ = instantiations;
   for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (TREE_VALUE (champ), 
-                              TREE_VALUE (fn), explicit_args);
+      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn),
+                               DEDUCE_EXACT, -1);
       if (fate == 1)
        ;
       else
@@ -8976,8 +9273,8 @@ most_specialized_instantiation (instantiations, explicit_args)
 
   for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (TREE_VALUE (champ), 
-                              TREE_VALUE (fn), explicit_args);
+      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn),
+                               DEDUCE_EXACT, -1);
       if (fate != 1)
        return error_mark_node;
     }
@@ -9005,7 +9302,7 @@ most_specialized (fns, decl, explicit_args)
        candidates = tree_cons (NULL_TREE, candidate, candidates);
     }
 
-  return most_specialized_instantiation (candidates, explicit_args);
+  return most_specialized_instantiation (candidates);
 }
 
 /* If DECL is a specialization of some template, return the most
@@ -9128,7 +9425,7 @@ void
 do_decl_instantiation (declspecs, declarator, storage)
      tree declspecs, declarator, storage;
 {
-  tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE);
+  tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL);
   tree result = NULL_TREE;
   int extern_p = 0;
 
@@ -9138,7 +9435,7 @@ do_decl_instantiation (declspecs, declarator, storage)
     return;
   else if (! DECL_LANG_SPECIFIC (decl))
     {
-      cp_error ("explicit instantiation of non-template `%#D'", decl);
+      error ("explicit instantiation of non-template `%#D'", decl);
       return;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
@@ -9154,13 +9451,13 @@ do_decl_instantiation (declspecs, declarator, storage)
       result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0);
       if (result && TREE_CODE (result) != VAR_DECL)
        {
-         cp_error ("no matching template for `%D' found", result);
+         error ("no matching template for `%D' found", result);
          return;
        }
     }
   else if (TREE_CODE (decl) != FUNCTION_DECL)
     {
-      cp_error ("explicit instantiation of `%#D'", decl);
+      error ("explicit instantiation of `%#D'", decl);
       return;
     }
   else
@@ -9177,7 +9474,7 @@ do_decl_instantiation (declspecs, declarator, storage)
 
         No program shall both explicitly instantiate and explicitly
         specialize a template.  */
-      cp_pedwarn ("explicit instantiation of `%#D' after", result);
+      pedwarn ("explicit instantiation of `%#D' after", result);
       cp_pedwarn_at ("explicit specialization here", result);
       return;
     }
@@ -9193,7 +9490,7 @@ do_decl_instantiation (declspecs, declarator, storage)
         the opposite case.  If -frepo, chances are we already got marked
         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);
+       pedwarn ("duplicate explicit instantiation of `%#D'", result);
 
       /* If we've already instantiated the template, just return now.  */
       if (DECL_INTERFACE_KNOWN (result))
@@ -9201,12 +9498,12 @@ do_decl_instantiation (declspecs, declarator, storage)
     }
   else if (!DECL_IMPLICIT_INSTANTIATION (result))
     {
-      cp_error ("no matching template for `%D' found", result);
+      error ("no matching template for `%D' found", result);
       return;
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      cp_pedwarn ("explicit instantiation of non-template `%#D'", result);
+      pedwarn ("explicit instantiation of non-template `%#D'", result);
       return;
     }
 
@@ -9218,11 +9515,11 @@ do_decl_instantiation (declspecs, declarator, storage)
   else if (storage == ridpointers[(int) RID_EXTERN])
     {
       if (pedantic)
-       cp_pedwarn ("ISO C++ forbids the use of `extern' on explicit instantiations");
+       pedwarn ("ISO C++ forbids the use of `extern' on explicit instantiations");
       extern_p = 1;
     }
   else
-    cp_error ("storage class `%D' applied to template instantiation",
+    error ("storage class `%D' applied to template instantiation",
              storage);
 
   SET_DECL_EXPLICIT_INSTANTIATION (result);
@@ -9240,7 +9537,6 @@ mark_class_instantiated (t, extern_p)
   SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
   SET_CLASSTYPE_INTERFACE_KNOWN (t);
   CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
-  CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
   TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
   if (! extern_p)
     {
@@ -9268,7 +9564,7 @@ do_type_instantiation (t, storage, complain)
 
   if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))
     {
-      cp_error ("explicit instantiation of non-template type `%T'", t);
+      error ("explicit instantiation of non-template type `%T'", t);
       return;
     }
 
@@ -9282,7 +9578,7 @@ do_type_instantiation (t, storage, complain)
   if (!COMPLETE_TYPE_P (t))
     {
       if (complain)
-       cp_error ("explicit instantiation of `%#T' before definition of template",
+       error ("explicit instantiation of `%#T' before definition of template",
                  t);
       return;
     }
@@ -9290,7 +9586,7 @@ do_type_instantiation (t, storage, complain)
   if (storage != NULL_TREE)
     {
       if (pedantic)
-       cp_pedwarn("ISO C++ forbids the use of `%s' on explicit instantiations", 
+       pedwarn("ISO C++ forbids the use of `%s' on explicit instantiations", 
                   IDENTIFIER_POINTER (storage));
 
       if (storage == ridpointers[(int) RID_INLINE])
@@ -9301,7 +9597,7 @@ do_type_instantiation (t, storage, complain)
        static_p = 1;
       else
        {
-         cp_error ("storage class `%D' applied to template instantiation",
+         error ("storage class `%D' applied to template instantiation",
                    storage);
          extern_p = 0;
        }
@@ -9315,7 +9611,7 @@ do_type_instantiation (t, storage, complain)
         specialize a template.  */
       if (complain)
        {
-         cp_error ("explicit instantiation of `%#T' after", t);
+         error ("explicit instantiation of `%#T' after", t);
          cp_error_at ("explicit specialization here", t);
        }
       return;
@@ -9329,11 +9625,11 @@ do_type_instantiation (t, storage, complain)
 
          If CLASSTYPE_INTERFACE_ONLY, then the first explicit instantiation
         was `extern'.  If EXTERN_P then the second is.  If -frepo, chances
-        are we already got marked as an explicit instantion because of the
+        are we already got marked as an explicit instantiation because of the
         repo file.  All these cases are OK.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
          && complain)
-       cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
+       pedwarn ("duplicate explicit instantiation of `%#T'", t);
       
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
@@ -9480,8 +9776,8 @@ regenerate_decl_from_template (decl, tmpl)
      functions, this is not so.  See tsubst_friend_function for
      details.  */
   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);
+  COPY_DECL_ASSEMBLER_NAME (decl, new_decl);
+  COPY_DECL_RTL (decl, new_decl);
   DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl);
 
   /* Call duplicate decls to merge the old and new declarations.  */
@@ -9508,6 +9804,7 @@ instantiate_decl (d, defer_ok)
   tree gen_tmpl;
   int pattern_defined;
   int line = lineno;
+  int need_push;
   const char *file = input_filename;
 
   /* This function should only be used to instantiate templates for
@@ -9600,13 +9897,30 @@ instantiate_decl (d, defer_ok)
   else
     pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
 
-  push_to_top_level ();
   lineno = DECL_SOURCE_LINE (d);
   input_filename = DECL_SOURCE_FILE (d);
 
   if (pattern_defined)
     {
-      repo_template_used (d);
+      /* Let the repository code that this template definition is
+        available.
+
+        The repository doesn't need to know about cloned functions
+        because they never actually show up in the object file.  It
+        does need to know about the clones; those are the symbols
+        that the linker will be emitting error messages about.  */
+      if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (d)
+         || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (d))
+       {
+         tree t;
+
+         for (t = TREE_CHAIN (d);
+              t && DECL_CLONED_FUNCTION_P (t); 
+              t = TREE_CHAIN (t))
+           repo_template_used (t);
+       }
+      else
+       repo_template_used (d);
 
       if (flag_external_templates && ! DECL_INTERFACE_KNOWN (d))
        {
@@ -9628,17 +9942,15 @@ instantiate_decl (d, defer_ok)
        import_export_decl (d);
     }
 
-  /* 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 
-      && TREE_READONLY (d)
-      && DECL_INITIAL (d) == NULL_TREE
-      && DECL_INITIAL (code_pattern) != NULL_TREE)
-    ;
+  if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d)
+      && DECL_INITIAL (d) == NULL_TREE)
+    /* We should have set up DECL_INITIAL in instantiate_class_template.  */
+    abort ();
   /* 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)))
+          && ! (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
@@ -9657,13 +9969,17 @@ instantiate_decl (d, defer_ok)
           member function or static data member of a class template
           shall be present in every translation unit in which it is
           explicitly instantiated.  */
-       cp_error ("explicit instantiation of `%D' but no definition available",
-                 d);
+       pedwarn
+         ("explicit instantiation of `%D' but no definition available", d);
 
       add_pending_template (d);
       goto out;
     }
 
+  need_push = !global_bindings_p ();
+  if (need_push)
+    push_to_top_level ();
+
   /* We're now committed to instantiating this template.  Mark it as
      instantiated so that recursive calls to instantiate_decl do not
      try to instantiate it again.  */
@@ -9707,10 +10023,6 @@ instantiate_decl (d, defer_ok)
       /* Set up context.  */
       start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
 
-      /* We already set up __FUNCTION__, etc., so we don't want to do
-        it again now.  */
-      function_name_declared_p = 1;
-
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
                   /*complain=*/1, tmpl);
@@ -9726,11 +10038,13 @@ instantiate_decl (d, defer_ok)
   /* We're not deferring instantiation any more.  */
   TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
 
+  if (need_push)
+    pop_from_top_level ();
+
 out:
   lineno = line;
   input_filename = file;
 
-  pop_from_top_level ();
   pop_tinst_level ();
 
   timevar_pop (TV_PARSE);
@@ -9745,6 +10059,7 @@ int
 instantiate_pending_templates ()
 {
   tree *t;
+  tree last = NULL_TREE;
   int instantiated_something = 0;
   int reconsider;
   
@@ -9783,8 +10098,11 @@ instantiate_pending_templates ()
                /* If INSTANTIATION has been instantiated, then we don't
                   need to consider it again in the future.  */
                *t = TREE_CHAIN (*t);
-             else 
-               t = &TREE_CHAIN (*t);
+             else
+               {
+                 last = *t;
+                 t = &TREE_CHAIN (*t);
+               }
            }
          else
            {
@@ -9805,43 +10123,16 @@ instantiate_pending_templates ()
                /* If INSTANTIATION has been instantiated, then we don't
                   need to consider it again in the future.  */
                *t = TREE_CHAIN (*t);
-             else 
-               t = &TREE_CHAIN (*t);
+             else
+               {
+                 last = *t;
+                 t = &TREE_CHAIN (*t);
+               }
            }
          tinst_depth = 0;
          current_tinst_level = NULL_TREE;
        }
-      template_tail = t;
-
-      /* Go through the things that are template instantiations if we are
-        using guiding declarations.  */
-      t = &maybe_templates;
-      while (*t)
-       {
-         tree template;
-         tree fn;
-         tree args;
-
-         fn = TREE_VALUE (*t);
-
-         if (DECL_INITIAL (fn))
-           /* If the FN is already defined, then it was either already
-              instantiated or, even though guiding declarations were
-              allowed, a non-template definition was provided.  */
-           ;
-         else
-           {
-             template = TREE_PURPOSE (*t);
-             args = get_bindings (template, fn, NULL_TREE);
-             fn = instantiate_template (template, args);
-             instantiate_decl (fn, /*defer_ok=*/0);
-             reconsider = 1;
-           }
-       
-         /* Remove this entry from the chain.  */
-         *t = TREE_CHAIN (*t);
-       }
-      maybe_template_tail = t;
+      last_pending_template = last;
     } 
   while (reconsider);
 
@@ -10007,100 +10298,6 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp)
   return fn_type;
 }
 
-/* Set the DECL_ASSEMBLER_NAME for DECL, which is a FUNCTION_DECL that
-   is either an instantiation or specialization of a template
-   function.  */
-
-static void
-set_mangled_name_for_template_decl (decl)
-     tree decl;
-{
-  tree context = NULL_TREE;
-  tree fn_type;
-  tree ret_type;
-  tree parm_types;
-  tree tparms;
-  tree targs;
-
-  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
-     different mangled names:
-
-       void f(int);                  
-       template <> void f<7>(int);
-       template <> void f<8>(int);  */
-
-  targs = DECL_TI_ARGS (decl);
-  if (uses_template_parms (targs))
-    /* This DECL is for a partial instantiation.  There's no need to
-       mangle the name of such an entity.  */
-    return;
-
-  /* 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
-     innermost template arguments have been substituted, not the
-     parameter and return types of the function DECL.  For example,
-     given:
-
-       template <class T> T f(T);
-
-     both PARMS and RET_TYPE should be `T' even if DECL is `int f(int)'.  
-     A more subtle example is:
-
-       template <class T> struct S { template <class U> void f(T, U); }
-
-     Here, if DECL is `void S<int>::f(int, double)', PARMS should be
-     {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 = 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_TEMPLATE_ARGS (targs);
-  ret_type = TREE_TYPE (fn_type);
-  parm_types = TYPE_ARG_TYPES (fn_type);
-
-  /* For a static member function, we generate a fake `this' pointer,
-     for the purposes of mangling.  This indicates of which class the
-     function is a member.  Because of:
-
-       [class.static] 
-
-       There shall not be a static and a nonstatic member function
-       with the same name and the same parameter types
-
-     we don't have to worry that this will result in a clash with a
-     non-static member function.  */
-  if (DECL_STATIC_FUNCTION_P (decl))
-    parm_types = hash_tree_chain (build_pointer_type (context), parm_types);
-
-  /* There should be the same number of template parameters as
-     template arguments.  */
-  my_friendly_assert (TREE_VEC_LENGTH (tparms) == TREE_VEC_LENGTH (targs),
-                     0);
-
-  /* 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));
-}
-
 /* Return truthvalue if we're processing a template different from
    the last one involved in diagnostics.  */
 int
@@ -10121,3 +10318,31 @@ current_instantiation ()
 {
   return current_tinst_level;
 }
+
+/* [temp.param] Check that template non-type parm TYPE is of an allowable
+   type. Return zero for ok, non-zero for disallowed. If COMPLAIN is
+   non-zero, then complain. */
+
+static int
+invalid_nontype_parm_type_p (type, complain)
+     tree type;
+     int complain;
+{
+  if (INTEGRAL_TYPE_P (type))
+    return 0;
+  else if (POINTER_TYPE_P (type))
+    return 0;
+  else if (TYPE_PTRMEM_P (type))
+    return 0;
+  else if (TYPE_PTRMEMFUNC_P (type))
+    return 0;
+  else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+    return 0;
+  else if (TREE_CODE (type) == TYPENAME_TYPE)
+    return 0;
+           
+  if (complain)
+    error ("`%#T' is not a valid type for a template constant parameter",
+              type);
+  return 1;
+}