OSDN Git Service

cp:
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 1c9e659..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,10 +29,10 @@ 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"
@@ -84,6 +84,7 @@ static htab_t local_specializations;
 #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
@@ -97,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));
@@ -162,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));
@@ -206,7 +205,7 @@ finish_member_template_decl (decl)
       return NULL_TREE;
     }
   else if (TREE_CODE (decl) == FIELD_DECL)
-    cp_error ("data member `%D' cannot be a member template", decl);
+    error ("data member `%D' cannot be a member template", decl);
   else if (DECL_TEMPLATE_INFO (decl))
     {
       if (!DECL_TEMPLATE_SPECIALIZATION (decl))
@@ -218,7 +217,7 @@ finish_member_template_decl (decl)
        return decl;
     } 
   else
-    cp_error ("invalid member template declaration `%D'", decl);
+    error ("invalid member template declaration `%D'", decl);
 
   return error_mark_node;
 }
@@ -613,7 +612,7 @@ check_specialization_scope ()
      shall be declared in the namespace of which the class template
      is a member.  */
   if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
-    cp_error ("explicit specialization in non-namespace scope `%D'",
+    error ("explicit specialization in non-namespace scope `%D'",
              scope);
 
   /* [temp.expl.spec] 
@@ -625,7 +624,7 @@ check_specialization_scope ()
      explicitly specialize a class member template if its enclosing
      class templates are not explicitly specialized as well.  */
   if (current_template_parms) 
-    cp_error ("enclosing class templates are not explicitly specialized");
+    error ("enclosing class templates are not explicitly specialized");
 }
 
 /* We've just seen template <>. */
@@ -700,7 +699,7 @@ maybe_process_partial_specialization (type)
          if (current_namespace
              != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
            {
-             cp_pedwarn ("specializing `%#T' in different namespace", type);
+             pedwarn ("specializing `%#T' in different namespace", type);
              cp_pedwarn_at ("  from definition of `%#D'",
                             CLASSTYPE_TI_TEMPLATE (type));
            }
@@ -709,10 +708,10 @@ maybe_process_partial_specialization (type)
            push_template_decl (TYPE_MAIN_DECL (type));
        }
       else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
-       cp_error ("specialization of `%T' after instantiation", type);
+       error ("specialization of `%T' after instantiation", type);
     }
   else if (processing_specialization)
-    cp_error ("explicit specialization of non-template `%T'", type);
+    error ("explicit specialization of non-template `%T'", type);
 }
 
 /* Retrieve the specialization (in the sense of [temp.spec] - a
@@ -844,7 +843,7 @@ register_specialization (spec, tmpl, args)
                  if (TREE_USED (fn) 
                      || DECL_EXPLICIT_INSTANTIATION (fn))
                    {
-                     cp_error ("specialization of %D after instantiation",
+                     error ("specialization of %D after instantiation",
                                fn);
                      return spec;
                    }
@@ -998,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;
     }
 
@@ -1040,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.  */
@@ -1350,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;
            }
@@ -1363,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;
 
@@ -1391,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;
        }
@@ -1407,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);
@@ -1421,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;
        }
@@ -1452,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)
@@ -1545,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;
                }
 
@@ -1588,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;
            }
@@ -1736,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); 
     }
 }
 
@@ -1929,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]
 
@@ -1993,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;
 
@@ -2233,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)));
       }
 
@@ -2249,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]
 
@@ -2274,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,
@@ -2317,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;
@@ -2405,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;
@@ -2469,7 +2477,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
          {
            if (msg)
              {
-               cp_error (msg, decl);
+               error (msg, decl);
                msg = 0;
              }
 
@@ -2538,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
@@ -2616,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
@@ -2663,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
@@ -2675,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
@@ -2748,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;
     }
 
@@ -2765,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));
@@ -2782,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;
        }
 
@@ -2792,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;
        }
@@ -2886,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;
            }
@@ -2907,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;
        }
@@ -2919,7 +2927,7 @@ 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;
        }
     }
@@ -2930,14 +2938,14 @@ convert_nontype_argument (type, expr)
       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;
     }
 
@@ -3284,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);
@@ -3310,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),
@@ -3323,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;
@@ -3339,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;
     }
@@ -3353,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
@@ -3393,10 +3416,10 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
              if (t)
                {
                  if (TYPE_ANONYMOUS_P (t))
-                   cp_pedwarn
+                   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;
@@ -3432,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);
     }
 
@@ -3476,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)
@@ -3527,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 
@@ -3759,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;
     }
 
@@ -3877,7 +3900,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
   if (! template)
     {
       if (complain)
-        cp_error ("`%T' is not a template", d1);
+        error ("`%T' is not a template", d1);
       return error_mark_node;
     }
 
@@ -3890,7 +3913,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
     {
       if (complain)
         {
-          cp_error ("non-template type `%T' used as a template", d1);
+          error ("non-template type `%T' used as a template", d1);
           if (in_decl)
            cp_error_at ("for template declaration `%D'", in_decl);
        }
@@ -3907,13 +3930,25 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
 
       parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
 
+      /* 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 
@@ -3952,7 +3987,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
          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
@@ -4181,9 +4216,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
                  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;
             }
        }
 
@@ -4429,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;
 {
@@ -4444,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 ();
@@ -4879,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))
            {
@@ -4989,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);
@@ -5157,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);
     }
 
@@ -5282,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
@@ -5297,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;
 }
@@ -5373,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 = 
@@ -5415,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:
@@ -5862,18 +5894,21 @@ tsubst_decl (t, args, type)
               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);
@@ -5882,7 +5917,7 @@ tsubst_decl (t, args, type)
                                     /*complain=*/1, in_decl);
 
        DECL_CONTEXT (r) = NULL_TREE;
-       if (PROMOTE_PROTOTYPES
+       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;
@@ -5896,7 +5931,7 @@ tsubst_decl (t, args, type)
       {
        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.  */
@@ -5947,12 +5982,13 @@ tsubst_decl (t, args, type)
          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.  */
@@ -5974,7 +6010,7 @@ tsubst_decl (t, args, type)
 
        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);
@@ -5989,7 +6025,7 @@ tsubst_decl (t, args, type)
        /* For __PRETTY_FUNCTION__ we have to adjust the initializer.  */
        if (DECL_PRETTY_FUNCTION_P (r))
          {
-           const char *name = (*decl_printable_name)
+           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));
@@ -6059,7 +6095,7 @@ tsubst_arg_types (arg_types, args, complain, in_decl)
     {
       if (complain)
         {
-          cp_error ("invalid parameter type `%T'", type);
+          error ("invalid parameter type `%T'", type);
           if (in_decl)
             cp_error_at ("in declaration `%D'", in_decl);
         }
@@ -6109,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;
@@ -6136,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;
        }
@@ -6248,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:
@@ -6314,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;
          }
@@ -6362,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)
@@ -6413,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);
@@ -6525,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);
@@ -6552,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;
@@ -6564,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);
@@ -6588,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:
@@ -6650,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;
          }
 
@@ -6696,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;
          }
@@ -6723,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,
@@ -7128,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);
 
@@ -7168,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;
@@ -7176,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:
@@ -7183,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:
@@ -7197,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;
       }
 
@@ -7262,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),
@@ -7310,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),
@@ -7337,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;
 
@@ -7386,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:
@@ -7420,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
@@ -7434,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
@@ -7469,51 +7547,18 @@ tsubst_expr (t, args, complain, in_decl)
 
     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
@@ -7523,7 +7568,6 @@ tree
 instantiate_template (tmpl, targ_ptr)
      tree tmpl, targ_ptr;
 {
-  tree clone;
   tree fndecl;
   tree gen_tmpl;
   tree spec;
@@ -7537,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)
@@ -7570,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;
            }
        }
@@ -7588,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;
 }
@@ -8454,7 +8511,14 @@ check_cv_quals_for_unify (strict, arg, parm)
        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.  */
+       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)
@@ -8504,16 +8568,19 @@ unify (tparms, targs, parm, arg, strict)
     return 1;
 
   if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
-      && TYPE_P (arg) && !CP_TYPE_CONST_P (arg))
+      && 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.  */
@@ -8613,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;
@@ -8712,6 +8779,18 @@ unify (tparms, targs, parm, arg, strict)
             level of pointers.  */
          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), strict);
       }
@@ -8753,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
@@ -8864,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),
@@ -8882,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:
@@ -9119,7 +9201,7 @@ get_bindings_overload (fn, decl, explicit_args)
 
 /* 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:
@@ -9343,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;
 
@@ -9353,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)
@@ -9369,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
@@ -9392,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;
     }
@@ -9408,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))
@@ -9416,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;
     }
 
@@ -9433,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);
@@ -9482,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;
     }
 
@@ -9496,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;
     }
@@ -9504,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])
@@ -9515,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;
        }
@@ -9529,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;
@@ -9543,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))
@@ -9867,7 +9949,8 @@ instantiate_decl (d, defer_ok)
   /* 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
@@ -9886,7 +9969,7 @@ 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_pedwarn
+       pedwarn
          ("explicit instantiation of `%D' but no definition available", d);
 
       add_pending_template (d);
@@ -10259,7 +10342,7 @@ invalid_nontype_parm_type_p (type, complain)
     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;
 }