OSDN Git Service

cp:
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 1463dbe..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,
-   2001  Free Software Foundation, Inc.
+   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,7 +108,7 @@ 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));
@@ -120,7 +118,6 @@ static tree convert_nontype_argument PARAMS ((tree, tree));
 static tree convert_template_argument PARAMS ((tree, tree, tree, int,
                                              int , tree));
 static tree get_bindings_overload PARAMS ((tree, tree, tree));
-static tree get_bindings_order PARAMS ((tree, tree, int));
 static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
 static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
 static int inline_needs_template_parms PARAMS ((tree));
@@ -135,7 +132,7 @@ 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, 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));
@@ -144,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));
@@ -166,7 +162,6 @@ 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));
@@ -177,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);
 }
@@ -211,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))
@@ -223,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;
 }
@@ -618,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] 
@@ -630,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 <>. */
@@ -705,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));
            }
@@ -714,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
@@ -849,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;
                    }
@@ -1003,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;
     }
 
@@ -1028,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;
@@ -1042,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.  */
@@ -1206,6 +1209,9 @@ copy_default_args_to_explicit_spec (decl)
   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);
@@ -1219,40 +1225,53 @@ copy_default_args_to_explicit_spec (decl)
   old_type = TREE_TYPE (decl);
   spec_types = TYPE_ARG_TYPES (old_type);
   
-  /* DECL may contain more parameters than TMPL due to the extra
-     in-charge parameter in constructors and destructors.  */
   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))
-       spec_types = TREE_CHAIN (spec_types);
+        {
+          /* 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);
 
-  /* Put the extra parameters back together -- but note that
-     build_cplus_method_type will automatically add the `this'
-     pointer.  */
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
-      && DECL_HAS_IN_CHARGE_PARM_P (decl))
+  /* Compute the new FUNCTION_TYPE.  */
+  if (object_type)
     {
-      tree t = TREE_CHAIN (TYPE_ARG_TYPES (old_type));
-      new_spec_types = hash_tree_cons (TREE_PURPOSE (t),
-                                      TREE_VALUE (t),
-                                      new_spec_types);
+      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);
     }
-  
-  /* Compute the new FUNCTION_TYPE.  */
-  if (TREE_CODE (old_type) == METHOD_TYPE)
-    new_type = build_cplus_method_type (TYPE_METHOD_BASETYPE (old_type),
-                                       TREE_TYPE (old_type),
-                                       new_spec_types);
   else
     new_type = build_function_type (TREE_TYPE (old_type),
-                                 new_spec_types);
+                                   new_spec_types);
   new_type = build_type_attribute_variant (new_type,
                                           TYPE_ATTRIBUTES (old_type));
   new_type = build_exception_variant (new_type,
@@ -1336,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;
            }
@@ -1349,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;
 
@@ -1377,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;
        }
@@ -1393,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);
@@ -1407,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;
        }
@@ -1438,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)
@@ -1499,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);
@@ -1531,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;
                }
 
@@ -1574,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;
            }
@@ -1640,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)
@@ -1657,30 +1676,21 @@ check_explicit_specialization (declarator, decl, template_count, flags)
             DECL is specializing.  */
          copy_default_args_to_explicit_spec (decl);
 
-         /* 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 
-
-              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.  */
@@ -1731,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); 
     }
 }
 
@@ -1924,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]
 
@@ -1988,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 (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;
 
@@ -2228,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)));
       }
 
@@ -2244,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]
 
@@ -2269,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,
@@ -2312,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;
@@ -2400,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;
@@ -2430,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'";
 
@@ -2464,7 +2477,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
          {
            if (msg)
              {
-               cp_error (msg, decl);
+               error (msg, decl);
                msg = 0;
              }
 
@@ -2533,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
@@ -2611,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
@@ -2658,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
@@ -2670,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
@@ -2708,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))
@@ -2741,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;
     }
 
@@ -2758,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));
@@ -2775,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;
        }
 
@@ -2785,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;
        }
@@ -2879,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;
            }
@@ -2900,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;
        }
@@ -2912,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;
     }
 
@@ -2960,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);
@@ -3293,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);
@@ -3319,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),
@@ -3332,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;
@@ -3348,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;
     }
@@ -3362,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
@@ -3401,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;
@@ -3441,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);
     }
 
@@ -3485,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)
@@ -3536,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 
@@ -3727,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))
@@ -3740,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)
@@ -3761,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;
     }
 
@@ -3807,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;
@@ -3875,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;
     }
 
@@ -3897,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 
@@ -3941,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
@@ -3965,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
@@ -3984,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.  */
@@ -4168,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;
             }
        }
 
@@ -4194,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.
@@ -4423,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;
 {
@@ -4438,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 ();
@@ -4584,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);
+      SET_DECL_RTL (new_friend, NULL_RTX);
+      SET_DECL_ASSEMBLER_NAME (new_friend, NULL_TREE);
     }
       
   if (DECL_NAMESPACE_SCOPE_P (new_friend))
@@ -4878,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))
            {
@@ -4967,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);
@@ -4995,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);
@@ -5089,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))
@@ -5162,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);
     }
 
@@ -5287,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
@@ -5302,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;
 }
@@ -5378,16 +5410,16 @@ 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 = 
@@ -5420,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:
@@ -5460,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);
@@ -5536,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;
@@ -5784,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)
@@ -5792,14 +5821,9 @@ 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);
@@ -5823,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) 
@@ -5833,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);
-           
-           /* 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:
@@ -5908,18 +5894,21 @@ tsubst_decl (t, args, type, in_decl)
               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);
+             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);
@@ -5928,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))
@@ -5943,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;
 
@@ -5994,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.  */
@@ -6021,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));
          }
 
@@ -6061,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;
 
@@ -6100,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.  */
@@ -6144,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;
@@ -6171,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;
        }
@@ -6271,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))
     {
@@ -6283,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:
@@ -6349,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;
          }
@@ -6397,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)
@@ -6420,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);
@@ -6447,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);
@@ -6559,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);
@@ -6586,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;
@@ -6598,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);
@@ -6622,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:
@@ -6684,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;
          }
 
@@ -6730,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;
          }
@@ -6757,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,
@@ -6789,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:
@@ -6816,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:
@@ -6829,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 (size_int (len)));
-       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)]);
@@ -6940,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.  */
@@ -7180,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);
 
@@ -7187,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;
@@ -7210,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;
     }
@@ -7226,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;
@@ -7234,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:
@@ -7241,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:
@@ -7255,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;
       }
 
@@ -7271,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;
@@ -7280,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)
@@ -7303,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),
@@ -7351,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),
@@ -7378,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;
 
@@ -7427,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:
@@ -7461,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
@@ -7475,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
@@ -7488,7 +7525,6 @@ tsubst_expr (t, args, complain, in_decl)
     case HANDLER:
       {
        tree decl;
-       tree blocks;
 
        prep_stmt (t);
        stmt = begin_handler ();
@@ -7503,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
@@ -7565,7 +7568,6 @@ tree
 instantiate_template (tmpl, targ_ptr)
      tree tmpl, targ_ptr;
 {
-  tree clone;
   tree fndecl;
   tree gen_tmpl;
   tree spec;
@@ -7579,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)
@@ -7612,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;
            }
        }
@@ -7630,11 +7645,11 @@ 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;
 }
@@ -7664,13 +7679,15 @@ instantiate_template (tmpl, targ_ptr)
      [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].
 
    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
@@ -7776,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:
@@ -7800,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);
     }
@@ -7840,7 +7881,11 @@ 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;
 }
 
 /* Most parms like fn_type_unification.
@@ -7850,31 +7895,35 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
    template).  */
 
 static int
-type_unification_real (tparms, targs, parms, args, subr,
-                      strict, allow_incomplete, len)
-     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, len;
+     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:
@@ -7884,14 +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 (len == 0)
+  if (xlen == 0)
     return 0;
 
+ again:
+  parms = xparms;
+  args = xargs;
+  len = xlen;
+
   while (parms
         && parms != void_list_node
         && args
@@ -7925,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;
@@ -7958,16 +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, sub_strict))
-        return 1;
+        if (unify (tparms, targs, parm, arg, arg_strict))
+          return 1;
+      }
 
       /* Are we done with the interesting parms?  */
       if (--len == 0)
-       return 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.  */
@@ -7978,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;
@@ -8111,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
@@ -8395,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;
 
@@ -8413,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:
@@ -8422,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)
@@ -8432,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
@@ -8458,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.  */
@@ -8560,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;
 
@@ -8568,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;
@@ -8630,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;
 
@@ -8645,8 +8761,6 @@ unify (tparms, targs, parm, arg, strict)
 
     case POINTER_TYPE:
       {
-       int sub_strict;
-
        if (TREE_CODE (arg) != POINTER_TYPE)
          return 1;
        
@@ -8658,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)
@@ -8712,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
@@ -8769,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,
@@ -8823,6 +8944,7 @@ unify (tparms, targs, parm, arg, strict)
                                    DEDUCE_EXACT, 0, -1);
 
     case OFFSET_TYPE:
+    offset:
       if (TREE_CODE (arg) != OFFSET_TYPE)
        return 1;
       if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
@@ -8841,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:
@@ -8938,6 +9061,8 @@ mark_decl_instantiated (result, extern_p)
 
 /* 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.
@@ -8945,18 +9070,21 @@ mark_decl_instantiated (result, extern_p)
    LEN is passed through to fn_type_unification.  */
    
 int
-more_specialized (pat1, pat2, len)
+more_specialized (pat1, pat2, deduce, len)
      tree pat1, pat2;
+     int deduce;
      int len;
 {
   tree targs;
   int winner = 0;
 
-  targs = get_bindings_order (pat1, DECL_TEMPLATE_RESULT (pat2), len);
+  targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2),
+                             NULL_TREE, 0, deduce, len);
   if (targs)
     --winner;
 
-  targs = get_bindings_order (pat2, DECL_TEMPLATE_RESULT (pat1), len);
+  targs = get_bindings_real (pat2, DECL_TEMPLATE_RESULT (pat1),
+                             NULL_TREE, 0, deduce, len);
   if (targs)
     ++winner;
 
@@ -8993,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.  LEN is passed through to fn_type_unification.  */
+   found.  DEDUCE and LEN are passed through to fn_type_unification.  */
    
 static tree
-get_bindings_real (fn, decl, explicit_args, check_rettype, len)
+get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
      tree fn, decl, explicit_args;
-     int check_rettype, len;
+     int check_rettype, deduce, len;
 {
   int ntparms = DECL_NTPARMS (fn);
   tree targs = make_tree_vec (ntparms);
@@ -9044,7 +9172,7 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, len)
                           decl_arg_types,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT, len);
+                          deduce, len);
 
   if (i != 0)
     return NULL_TREE;
@@ -9058,7 +9186,7 @@ tree
 get_bindings (fn, decl, explicit_args)
      tree fn, decl, explicit_args;
 {
-  return get_bindings_real (fn, decl, explicit_args, 1, -1);
+  return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1);
 }
 
 /* But for resolve_overloaded_unification, we only care about the parameter
@@ -9068,22 +9196,12 @@ static tree
 get_bindings_overload (fn, decl, explicit_args)
      tree fn, decl, explicit_args;
 {
-  return get_bindings_real (fn, decl, explicit_args, 0, -1);
-}
-
-/* And for more_specialized, we want to be able to stop partway.  */
-
-static tree
-get_bindings_order (fn, decl, len)
-     tree fn, decl;
-     int len;
-{
-  return get_bindings_real (fn, decl, NULL_TREE, 0, len);
+  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:
@@ -9137,7 +9255,8 @@ most_specialized_instantiation (instantiations)
   champ = instantiations;
   for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1);
+      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn),
+                               DEDUCE_EXACT, -1);
       if (fate == 1)
        ;
       else
@@ -9154,7 +9273,8 @@ most_specialized_instantiation (instantiations)
 
   for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1);
+      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn),
+                               DEDUCE_EXACT, -1);
       if (fate != 1)
        return error_mark_node;
     }
@@ -9305,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;
 
@@ -9315,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)
@@ -9331,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
@@ -9354,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;
     }
@@ -9370,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))
@@ -9378,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;
     }
 
@@ -9395,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);
@@ -9417,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)
     {
@@ -9445,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;
     }
 
@@ -9459,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;
     }
@@ -9467,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])
@@ -9478,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;
        }
@@ -9492,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;
@@ -9506,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))
@@ -9657,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.  */
@@ -9783,7 +9902,25 @@ instantiate_decl (d, defer_ok)
 
   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))
        {
@@ -9805,14 +9942,15 @@ instantiate_decl (d, defer_ok)
        import_export_decl (d);
     }
 
-  /* We need to set up DECL_INITIAL regardless, if
-     the variable is initialized in the class body.  */
-  if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d))
-    ;
+  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
@@ -9831,8 +9969,8 @@ 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;
@@ -9885,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);
@@ -9925,6 +10059,7 @@ int
 instantiate_pending_templates ()
 {
   tree *t;
+  tree last = NULL_TREE;
   int instantiated_something = 0;
   int reconsider;
   
@@ -9963,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
            {
@@ -9985,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);
 
@@ -10187,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
@@ -10319,17 +10336,13 @@ invalid_nontype_parm_type_p (type, complain)
     return 0;
   else if (TYPE_PTRMEMFUNC_P (type))
     return 0;
-  else if (!pedantic && TREE_CODE (type) == REAL_TYPE)
-    return 0; /* GNU extension */
-  else if (!pedantic && TREE_CODE (type) == COMPLEX_TYPE)
-    return 0; /* GNU extension */
   else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
     return 0;
   else if (TREE_CODE (type) == TYPENAME_TYPE)
     return 0;
            
   if (complain)
-    cp_error ("`%#T' is not a valid type for a template constant parameter",
+    error ("`%#T' is not a valid type for a template constant parameter",
               type);
   return 1;
 }