OSDN Git Service

* attribs.c (strip_attrs): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 57fb871..d7335a0 100644 (file)
@@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA.  */
 #include "cp-tree.h"
 #include "tree-inline.h"
 #include "decl.h"
-#include "lex.h"
 #include "output.h"
 #include "except.h"
 #include "toplev.h"
@@ -156,7 +155,7 @@ static int verify_class_unification (tree, tree, tree);
 static tree try_class_unification (tree, tree, tree, tree);
 static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
                                           tree, tree);
-static tree determine_specialization (tree, tree, tree *, int);
+static tree determine_specialization (tree, tree, tree *, int, int);
 static int template_args_equal (tree, tree);
 static void tsubst_default_arguments (tree);
 static tree for_each_template_parm_r (tree *, int *, void *);
@@ -177,9 +176,8 @@ static tree tsubst_copy     (tree, tree, tsubst_flags_t, tree);
 static void
 push_access_scope (tree t)
 {
-  my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
-                     || TREE_CODE (t) == VAR_DECL,
-                     0);
+  gcc_assert (TREE_CODE (t) == FUNCTION_DECL
+             || TREE_CODE (t) == VAR_DECL);
 
   if (DECL_CLASS_SCOPE_P (t))
     push_nested_class (DECL_CONTEXT (t));
@@ -223,7 +221,7 @@ finish_member_template_decl (tree decl)
   if (decl == error_mark_node)
     return error_mark_node;
 
-  my_friendly_assert (DECL_P (decl), 20020812);
+  gcc_assert (DECL_P (decl));
 
   if (TREE_CODE (decl) == TYPE_DECL)
     {
@@ -358,7 +356,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) 
     {
       tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      my_friendly_assert (DECL_P (parm), 0);
+      gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
        {
@@ -386,7 +384,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
     }
 }
@@ -543,8 +541,7 @@ add_outermost_template_args (tree args, tree extra_args)
 
   /* If there are more levels of EXTRA_ARGS than there are ARGS,
      something very fishy is going on.  */
-  my_friendly_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args),
-                     0);
+  gcc_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args));
 
   /* If *all* the new arguments will be the EXTRA_ARGS, just return
      them.  */
@@ -571,7 +568,7 @@ get_innermost_template_args (tree args, int n)
   int extra_levels;
   int i;
 
-  my_friendly_assert (n >= 0, 20000603);
+  gcc_assert (n >= 0);
 
   /* If N is 1, just return the innermost set of template arguments.  */
   if (n == 1)
@@ -580,7 +577,7 @@ get_innermost_template_args (tree args, int n)
   /* If we're not removing anything, just return the arguments we were
      given.  */
   extra_levels = TMPL_ARGS_DEPTH (args) - n;
-  my_friendly_assert (extra_levels >= 0, 20000603);
+  gcc_assert (extra_levels >= 0);
   if (extra_levels == 0)
     return args;
 
@@ -697,7 +694,7 @@ note_template_header (int specialization)
 void
 begin_explicit_instantiation (void)
 {
-  my_friendly_assert (!processing_explicit_instantiation, 20020913);
+  gcc_assert (!processing_explicit_instantiation);
   processing_explicit_instantiation = true;
 }
 
@@ -705,10 +702,40 @@ begin_explicit_instantiation (void)
 void
 end_explicit_instantiation (void)
 {
-  my_friendly_assert(processing_explicit_instantiation, 20020913);
+  gcc_assert (processing_explicit_instantiation);
   processing_explicit_instantiation = false;
 }
 
+/* A explicit specialization or partial specialization TMPL is being
+   declared.  Check that the namespace in which the specialization is
+   occurring is permissible.  Returns false iff it is invalid to
+   specialize TMPL in the current namespace.  */
+   
+static bool
+check_specialization_namespace (tree tmpl)
+{
+  tree tpl_ns = decl_namespace_context (tmpl);
+
+  /* [tmpl.expl.spec]
+     
+     An explicit specialization shall be declared in the namespace of
+     which the template is a member, or, for member templates, in the
+     namespace of which the enclosing class or enclosing class
+     template is a member.  An explicit specialization of a member
+     function, member class or static data member of a class template
+     shall be declared in the namespace of which the class template is
+     a member.  */
+  if (is_associated_namespace (current_namespace, tpl_ns))
+    /* Same or super-using namespace.  */
+    return true;
+  else
+    {
+      pedwarn ("specialization of `%D' in different namespace", tmpl);
+      cp_pedwarn_at ("  from definition of `%#D'", tmpl);
+      return false;
+    }
+}
+
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
@@ -734,15 +761,7 @@ maybe_process_partial_specialization (tree type)
       if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
          && !COMPLETE_TYPE_P (type))
        {
-         tree tpl_ns = decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type));
-         if (is_associated_namespace (current_namespace, tpl_ns))
-           /* Same or super-using namespace.  */;
-         else
-           {
-             pedwarn ("specializing `%#T' in different namespace", type);
-             cp_pedwarn_at ("  from definition of `%#D'",
-                            CLASSTYPE_TI_TEMPLATE (type));
-           }
+         check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type));
          SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
          if (processing_template_decl)
            push_template_decl (TYPE_MAIN_DECL (type));
@@ -822,13 +841,12 @@ retrieve_specialization (tree tmpl, tree args)
 {
   tree s;
 
-  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
 
   /* There should be as many levels of arguments as there are
      levels of parameters.  */
-  my_friendly_assert (TMPL_ARGS_DEPTH (args) 
-                     == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)),
-                     0);
+  gcc_assert (TMPL_ARGS_DEPTH (args) 
+             == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
                      
   for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
        s != NULL_TREE;
@@ -866,7 +884,7 @@ is_specialization_of (tree decl, tree tmpl)
     }
   else 
     {
-      my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 0);
+      gcc_assert (TREE_CODE (decl) == TYPE_DECL);
 
       for (t = TREE_TYPE (decl);
           t != NULL_TREE;
@@ -888,7 +906,7 @@ is_specialization_of_friend (tree decl, tree friend)
   bool need_template = true;
   int template_depth;
 
-  my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0);
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
 
   /* For [temp.friend/6] when FRIEND is an ordinary member function
      of a template class, we want to check if DECL is a specialization
@@ -1022,7 +1040,7 @@ register_specialization (tree spec, tree tmpl, tree args)
 {
   tree s;
 
-  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
+  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
 
   if (TREE_CODE (spec) == FUNCTION_DECL 
       && uses_template_parms (DECL_TI_ARGS (spec)))
@@ -1041,9 +1059,8 @@ register_specialization (tree spec, tree tmpl, tree args)
 
   /* There should be as many levels of arguments as there are
      levels of parameters.  */
-  my_friendly_assert (TMPL_ARGS_DEPTH (args) 
-                     == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)),
-                     0);
+  gcc_assert (TMPL_ARGS_DEPTH (args) 
+             == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
 
   for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
        s != NULL_TREE;
@@ -1058,64 +1075,68 @@ register_specialization (tree spec, tree tmpl, tree args)
         more convenient to simply allow this than to try to prevent it.  */
       if (fn == spec)
        return spec;
-      else if (comp_template_args (TREE_PURPOSE (s), args))
+      else if (DECL_TEMPLATE_SPECIALIZATION (spec)
+              && comp_template_args (TREE_PURPOSE (s), args))
        {
-         if (DECL_TEMPLATE_SPECIALIZATION (spec))
+         if (DECL_TEMPLATE_INSTANTIATION (fn))
            {
-             if (DECL_TEMPLATE_INSTANTIATION (fn))
+             if (TREE_USED (fn) 
+                 || DECL_EXPLICIT_INSTANTIATION (fn))
                {
-                 if (TREE_USED (fn) 
-                     || DECL_EXPLICIT_INSTANTIATION (fn))
-                   {
-                     error ("specialization of %D after instantiation",
-                               fn);
-                     return spec;
-                   }
-                 else
-                   {
-                     /* This situation should occur only if the first
-                        specialization is an implicit instantiation,
-                        the second is an explicit specialization, and
-                        the implicit instantiation has not yet been
-                        used.  That situation can occur if we have
-                        implicitly instantiated a member function and
-                        then specialized it later.
-
-                        We can also wind up here if a friend
-                        declaration that looked like an instantiation
-                        turns out to be a specialization:
-
-                          template <class T> void foo(T);
-                          class S { friend void foo<>(int) };
-                          template <> void foo(int);  
-
-                        We transform the existing DECL in place so that
-                        any pointers to it become pointers to the
-                        updated declaration.  
-
-                        If there was a definition for the template, but
-                        not for the specialization, we want this to
-                        look as if there were no definition, and vice
-                        versa.  */
-                     DECL_INITIAL (fn) = NULL_TREE;
-                     duplicate_decls (spec, fn);
-
-                     return fn;
-                   }
+                 error ("specialization of %D after instantiation",
+                        fn);
+                 return spec;
                }
-             else if (DECL_TEMPLATE_SPECIALIZATION (fn))
+             else
                {
-                 if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
-                   /* Dup decl failed, but this is a new
-                      definition. Set the line number so any errors
-                      match this new definition.  */
-                   DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec);
+                 /* This situation should occur only if the first
+                    specialization is an implicit instantiation, the
+                    second is an explicit specialization, and the
+                    implicit instantiation has not yet been used.
+                    That situation can occur if we have implicitly
+                    instantiated a member function and then
+                    specialized it later.
+
+                    We can also wind up here if a friend declaration
+                    that looked like an instantiation turns out to be
+                    a specialization:
+
+                      template <class T> void foo(T);
+                      class S { friend void foo<>(int) };
+                      template <> void foo(int);  
+
+                    We transform the existing DECL in place so that
+                    any pointers to it become pointers to the updated
+                    declaration.
+
+                    If there was a definition for the template, but
+                    not for the specialization, we want this to look
+                    as if there were no definition, and vice
+                    versa.  */
+                 DECL_INITIAL (fn) = NULL_TREE;
+                 duplicate_decls (spec, fn);
                  
                  return fn;
                }
            }
+         else if (DECL_TEMPLATE_SPECIALIZATION (fn))
+           {
+             if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
+               /* Dup decl failed, but this is a new definition. Set
+                  the line number so any errors match this new
+                  definition.  */
+               DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec);
+             
+             return fn;
+           }
        }
-      }
+    }
+
+  /* A specialization must be declared in the same namespace as the
+     template it is specializing.  */
+  if (DECL_TEMPLATE_SPECIALIZATION (spec)
+      && !check_specialization_namespace (tmpl))
+    DECL_CONTEXT (spec) = decl_namespace_context (tmpl);
 
   DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
      = tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
@@ -1206,6 +1227,10 @@ print_candidates (tree fns)
    If NEED_MEMBER_TEMPLATE is nonzero the function is known to be a
    specialization of a member template.
 
+   The TEMPLATE_COUNT is the number of references to qualifying
+   template classes that appeared in the name of the function. See
+   check_explicit_specialization for a more accurate description.
+
    The template args (those explicitly specified and those deduced)
    are output in a newly created vector *TARGS_OUT.
 
@@ -1216,13 +1241,16 @@ static tree
 determine_specialization (tree template_id, 
                           tree decl, 
                           tree* targs_out, 
-                         int need_member_template)
+                         int need_member_template,
+                         int template_count)
 {
   tree fns;
   tree targs;
   tree explicit_targs;
   tree candidates = NULL_TREE;
   tree templates = NULL_TREE;
+  int header_count;
+  struct cp_binding_level *b;
 
   *targs_out = NULL_TREE;
 
@@ -1245,6 +1273,14 @@ determine_specialization (tree template_id,
       return error_mark_node;
     }
 
+  /* Count the number of template headers specified for this
+     specialization.  */
+  header_count = 0;
+  for (b = current_binding_level;
+       b->kind == sk_template_parms || b->kind == sk_template_spec;
+       b = b->level_chain)
+    ++header_count;
+
   for (; fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
@@ -1281,6 +1317,35 @@ determine_specialization (tree template_id,
                               TREE_VALUE (decl_arg_types)))
            continue;
 
+         /* In case of explicit specialization, we need to check if
+            the number of template headers appearing in the specialization
+            is correct. This is usually done in check_explicit_specialization,
+            but the check done there cannot be exhaustive when specializing
+            member functions. Consider the following code:
+
+            template <> void A<int>::f(int);
+            template <> template <> void A<int>::f(int);
+
+            Assuming that A<int> is not itself an explicit specialization
+            already, the first line specializes "f" which is a non-template
+            member function, whilst the second line specializes "f" which
+            is a template member function. So both lines are syntactically
+            correct, and check_explicit_specialization does not reject
+            them.
+            
+            Here, we can do better, as we are matching the specialization
+            against the declarations. We count the number of template
+            headers, and we check if they match TEMPLATE_COUNT + 1
+            (TEMPLATE_COUNT is the number of qualifying template classes,
+            plus there must be another header for the member template
+            itself).
+            
+            Notice that if header_count is zero, this is not a
+            specialization but rather a template instantiation, so there
+            is no check we can perform here.  */
+         if (header_count && header_count != template_count + 1)
+           continue;
+
          /* See whether this function might be a specialization of this
             template.  */
          targs = get_bindings (fn, decl, explicit_targs);
@@ -1645,9 +1710,16 @@ check_explicit_specialization (tree declarator,
       break;
 
     case tsk_excessive_parms:
-      error ("too many template parameter lists in declaration of `%D'", 
-               decl);
-      return error_mark_node;
+    case tsk_insufficient_parms:
+      if (tsk == tsk_excessive_parms)
+        error ("too many template parameter lists in declaration of `%D'",
+              decl);
+      else if (template_header_count)
+       error("too few template parameter lists in declaration of `%D'",
+             decl);
+      else
+       error("explicit specialization of `%D' must be introduced by "
+             "`template <>'", decl);
 
       /* Fall through.  */
     case tsk_expl_spec:
@@ -1657,32 +1729,6 @@ check_explicit_specialization (tree declarator,
       else
        specialization = 1;
       break;
-     
-    case tsk_insufficient_parms:
-      if (template_header_count)
-       {
-         error("too few template parameter lists in declaration of `%D'", 
-                  decl);
-         return decl;
-       }
-      else if (ctype != NULL_TREE
-              && !TYPE_BEING_DEFINED (ctype)
-              && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)
-              && !is_friend)
-       {
-         /* For backwards compatibility, we accept:
-
-              template <class T> struct S { void f(); };
-              void S<int>::f() {} // Missing template <>
-
-            That used to be valid C++.  */
-         if (pedantic)
-           pedwarn
-             ("explicit specialization not preceded by `template <>'");
-         specialization = 1;
-         SET_DECL_TEMPLATE_SPECIALIZATION (decl);
-       }
-      break;
 
     case tsk_template:
       if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
@@ -1691,8 +1737,8 @@ check_explicit_specialization (tree declarator,
             template <class T> void f<int>(); */
 
          if (uses_template_parms (declarator))
-           error ("partial specialization `%D' of function template",
-                     declarator);
+           error ("function template partial specialization `%D' "
+                  "is not allowed", declarator);
          else
            error ("template-id `%D' in declaration of primary template",
                      declarator);
@@ -1713,7 +1759,7 @@ check_explicit_specialization (tree declarator,
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   if (specialization || member_specialization)
@@ -1740,14 +1786,14 @@ check_explicit_specialization (tree declarator,
        {
          tree fns;
 
-         my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 0);
+         gcc_assert (TREE_CODE (declarator) == IDENTIFIER_NODE);
          if (ctype)
            fns = dname;
          else
            {
              /* If there is no class context, the explicit instantiation
                  must be at namespace scope.  */
-             my_friendly_assert (DECL_NAMESPACE_SCOPE_P (decl), 20030625);
+             gcc_assert (DECL_NAMESPACE_SCOPE_P (decl));
 
              /* Find the namespace binding, using the declaration
                  context.  */
@@ -1822,11 +1868,12 @@ check_explicit_specialization (tree declarator,
            {
              idx = lookup_fnfields_1 (ctype, name);
              if (idx >= 0)
-               fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx);
+               fns = VEC_index (tree, CLASSTYPE_METHOD_VEC (ctype), idx);
            }
          else
            {
-             tree methods;
+             VEC(tree) *methods;
+             tree ovl;
 
              /* For a type-conversion operator, we cannot do a
                 name-based lookup.  We might be looking for `operator
@@ -1838,11 +1885,10 @@ check_explicit_specialization (tree declarator,
              methods = CLASSTYPE_METHOD_VEC (ctype);
              if (methods)
                for (idx = CLASSTYPE_FIRST_CONVERSION_SLOT;
-                    idx < TREE_VEC_LENGTH (methods); ++idx) 
+                    VEC_iterate (tree, methods, idx, ovl);
+                    ++idx)
                  {
-                   tree ovl = TREE_VEC_ELT (methods, idx);
-
-                   if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl)))
+                   if (!DECL_CONV_FN_P (OVL_CURRENT (ovl)))
                      /* There are no more conversion functions.  */
                      break;
 
@@ -1873,7 +1919,8 @@ check_explicit_specialization (tree declarator,
         declaration.  */
       tmpl = determine_specialization (declarator, decl,
                                       &targs, 
-                                      member_specialization);
+                                      member_specialization,
+                                      template_count);
            
       if (!tmpl || tmpl == error_mark_node)
        /* We couldn't figure out what this declaration was
@@ -2013,7 +2060,8 @@ maybe_check_template_type (tree type)
    parameters.  These are represented in the same format used for
    DECL_TEMPLATE_PARMS.  */
 
-int comp_template_parms (tree parms1, tree parms2)
+int
+comp_template_parms (tree parms1, tree parms2)
 {
   tree p1;
   tree p2;
@@ -2029,8 +2077,8 @@ int comp_template_parms (tree parms1, tree parms2)
       tree t2 = TREE_VALUE (p2);
       int i;
 
-      my_friendly_assert (TREE_CODE (t1) == TREE_VEC, 0);
-      my_friendly_assert (TREE_CODE (t2) == TREE_VEC, 0);
+      gcc_assert (TREE_CODE (t1) == TREE_VEC);
+      gcc_assert (TREE_CODE (t2) == TREE_VEC);
 
       if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
        return 0;
@@ -2076,7 +2124,7 @@ check_template_shadow (tree decl)
   /* Figure out what we're shadowing.  */
   if (TREE_CODE (decl) == OVERLOAD)
     decl = OVL_CURRENT (decl);
-  olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));
+  olddecl = innermost_non_namespace_value (DECL_NAME (decl));
 
   /* If there's no previous binding for this name, we're not shadowing
      anything, let alone a template parameter.  */
@@ -2161,21 +2209,20 @@ reduce_template_parm_level (tree index, tree type, int levels)
 }
 
 /* Process information from new template parameter NEXT and append it to the
-   LIST being built.  */
+   LIST being built.  This new parameter is a non-type parameter iff
+   IS_NON_TYPE is true.  */
 
 tree
-process_template_parm (tree list, tree next)
+process_template_parm (tree list, tree next, bool is_non_type)
 {
   tree parm;
   tree decl = 0;
   tree defval;
-  int is_type, idx;
+  int idx;
 
   parm = next;
-  my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
+  gcc_assert (TREE_CODE (parm) == TREE_LIST);
   defval = TREE_PURPOSE (parm);
-  parm = TREE_VALUE (parm);
-  is_type = TREE_PURPOSE (parm) == class_type_node;
 
   if (list)
     {
@@ -2190,12 +2237,10 @@ process_template_parm (tree list, tree next)
   else
     idx = 0;
 
-  if (!is_type)
+  if (is_non_type)
     {
-      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);
+      parm = TREE_VALUE (parm);
+
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       /* [temp.param]
@@ -2222,7 +2267,7 @@ process_template_parm (tree list, tree next)
   else
     {
       tree t;
-      parm = TREE_VALUE (parm);
+      parm = TREE_VALUE (TREE_VALUE (parm));
       
       if (parm && TREE_CODE (parm) == TEMPLATE_DECL)
        {
@@ -2528,7 +2573,7 @@ process_partial_specialization (tree decl)
      The type of a template parameter corresponding to a specialized
      non-type argument shall not be dependent on a parameter of the
      specialization.  */
-  my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0);
+  gcc_assert (nargs == DECL_NTPARMS (maintmpl));
   tpd2.parms = 0;
   for (i = 0; i < nargs; ++i)
     {
@@ -2827,19 +2872,35 @@ push_template_decl_real (tree decl, int is_friend)
       else if (TREE_CODE (decl) == TYPE_DECL 
               && ANON_AGGRNAME_P (DECL_NAME (decl))) 
        error ("template class without a name");
-      else if (TREE_CODE (decl) == FUNCTION_DECL
-              && DECL_DESTRUCTOR_P (decl))
+      else if (TREE_CODE (decl) == FUNCTION_DECL)
        {
-         /* [temp.mem]
-            
-             A destructor shall not be a member template.  */
-         error ("destructor `%D' declared as member template", decl);
-         return error_mark_node;
+         if (DECL_DESTRUCTOR_P (decl))
+           {
+             /* [temp.mem]
+                
+                A destructor shall not be a member template.  */
+             error ("destructor `%D' declared as member template", decl);
+             return error_mark_node;
+           }
+         if (NEW_DELETE_OPNAME_P (DECL_NAME (decl))
+             && (!TYPE_ARG_TYPES (TREE_TYPE (decl))
+                 || TYPE_ARG_TYPES (TREE_TYPE (decl)) == void_list_node
+                 || !TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+                 || (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl))))
+                     == void_list_node)))
+           {
+             /* [basic.stc.dynamic.allocation] 
+
+                An allocation function can be a function
+                template. ... Template allocation functions shall
+                have two or more parameters.  */
+             error ("invalid template declaration of `%D'", decl);
+             return decl;
+           }
        }
       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)
+              || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)))
        /* OK */;
       else
        {
@@ -3093,7 +3154,11 @@ redeclare_class_template (tree type, tree parms)
       tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
       tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
 
-      if (TREE_CODE (tmpl_parm) != TREE_CODE (parm))
+      /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
+        TEMPLATE_DECL.  */
+      if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+         || (TREE_CODE (tmpl_parm) != TYPE_DECL
+             && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
        {
          cp_error_at ("template parameter `%#D'", tmpl_parm);
          error ("redeclared here as `%#D'", parm);
@@ -3211,9 +3276,7 @@ convert_nontype_argument (tree type, tree expr)
           will not return the initializer.  Handle that special case
           here.  */
        if (expr == const_expr
-           && TREE_CODE (expr) == VAR_DECL
-           && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (expr)
-           && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (expr))
+           && DECL_INTEGRAL_CONSTANT_VAR_P (expr)
            /* DECL_INITIAL can be NULL if we are processing a
               variable initialized to an expression involving itself.
               We know it is initialized to a constant -- but not what
@@ -3327,7 +3390,14 @@ convert_nontype_argument (tree type, tree expr)
          conversions (_conv.integral_) are applied.  */
       if (!INTEGRAL_TYPE_P (expr_type))
        return error_mark_node;
-      
+
+      /* [conv.integral] does not allow conversions between two different
+        enumeration types.  */
+      if (TREE_CODE (type) == ENUMERAL_TYPE
+         && TREE_CODE (expr_type) == ENUMERAL_TYPE
+         && !same_type_ignoring_top_level_qualifiers_p (type, expr_type))
+         return error_mark_node;
+
       /* It's safe to call digest_init in this case; we know we're
         just converting one integral constant expression to another.  */
       expr = digest_init (type, expr, (tree*) 0);
@@ -3395,8 +3465,7 @@ convert_nontype_argument (tree type, tree expr)
 
            expr = build_unary_op (ADDR_EXPR, fn, 0);
 
-           my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 
-                               0);
+           gcc_assert (same_type_p (type, TREE_TYPE (expr)));
            return expr;
          }
        else 
@@ -3434,7 +3503,7 @@ convert_nontype_argument (tree type, tree expr)
            if (TREE_CODE (expr) == NOP_EXPR
                && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
              STRIP_NOPS (expr);
-           my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
+           gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
            expr = TREE_OPERAND (expr, 0);
            expr_type = TREE_TYPE (expr);
          }
@@ -3464,10 +3533,7 @@ convert_nontype_argument (tree type, tree expr)
                  goto bad_argument;
              }
 
-           my_friendly_assert (same_type_p (type_referred_to, 
-                                            TREE_TYPE (fn)),
-                               0);
-
+           gcc_assert (same_type_p (type_referred_to, TREE_TYPE (fn)));
            expr = fn;
          }
        else
@@ -3493,7 +3559,7 @@ convert_nontype_argument (tree type, tree expr)
 
     case RECORD_TYPE:
       {
-       my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 20010112);
+       gcc_assert (TYPE_PTRMEMFUNC_P (type));
 
        /* For a non-type template-parameter of type pointer to member
           function, no conversions apply.  If the template-argument
@@ -3531,8 +3597,7 @@ convert_nontype_argument (tree type, tree expr)
 
     default:
       /* All non-type parameters must have one of these types.  */
-      abort ();
-      break;
+      gcc_unreachable ();
     }
 
   return error_mark_node;
@@ -3565,8 +3630,8 @@ coerce_template_template_parms (tree parm_parms,
   int nparms, nargs, i;
   tree parm, arg;
 
-  my_friendly_assert (TREE_CODE (parm_parms) == TREE_VEC, 0);
-  my_friendly_assert (TREE_CODE (arg_parms) == TREE_VEC, 0);
+  gcc_assert (TREE_CODE (parm_parms) == TREE_VEC);
+  gcc_assert (TREE_CODE (arg_parms) == TREE_VEC);
 
   nparms = TREE_VEC_LENGTH (parm_parms);
   nargs = TREE_VEC_LENGTH (arg_parms);
@@ -3610,16 +3675,21 @@ coerce_template_template_parms (tree parm_parms,
 
        case PARM_DECL:
          /* The tsubst call is used to handle cases such as
-              template <class T, template <T> class TT> class D;  
+
+              template <int> class C {};
+              template <class T, template <T> class TT> class D {};
+              D<int, C> d;
+
             i.e. the parameter list of TT depends on earlier parameters.  */
-         if (!same_type_p
-             (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
-              TREE_TYPE (arg)))
+         if (!dependent_type_p (TREE_TYPE (arg))
+             && !same_type_p
+                   (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
+                            TREE_TYPE (arg)))
            return 0;
          break;
          
        default:
-         abort ();
+         gcc_unreachable ();
        }
     }
   return 1;
@@ -3757,7 +3827,7 @@ convert_template_argument (tree parm,
            }
        }
       else
-       val = groktypename (arg);
+       val = arg;
     }
   else
     {
@@ -3854,7 +3924,7 @@ coerce_template_parms (tree parms,
       else
        break;
       
-      my_friendly_assert (arg, 20030727);
+      gcc_assert (arg);
       if (arg == error_mark_node)
        error ("template argument %d is invalid", i + 1);
       else 
@@ -3937,7 +4007,7 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
   ccat ('<');
   nparms = TREE_VEC_LENGTH (parms);
   arglist = INNERMOST_TEMPLATE_ARGS (arglist);
-  my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
+  gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
   for (i = 0; i < nparms; i++)
     {
       tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
@@ -3962,11 +4032,11 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
                 {
                   /* The template may be defined in a namespace, or
                      may be a member template.  */
-                  my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL
-                                      || CLASS_TYPE_P (context), 
-                                      980422);
-                 cat(decl_as_string (DECL_CONTEXT (arg), TFF_PLAIN_IDENTIFIER));
-                 cat("::");
+                  gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
+                             || CLASS_TYPE_P (context));
+                 cat (decl_as_string (DECL_CONTEXT (arg),
+                                     TFF_PLAIN_IDENTIFIER));
+                 cat ("::");
                }
              cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
            }
@@ -3976,7 +4046,7 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
          continue;
        }
       else
-       my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
+       gcc_assert (TREE_CODE (parm) == PARM_DECL);
 
       /* No need to check arglist against parmlist here; we did that
         in coerce_template_parms, called from lookup_template_class.  */
@@ -4073,7 +4143,7 @@ lookup_template_function (tree fns, tree arglist)
   if (fns == error_mark_node || arglist == error_mark_node)
     return error_mark_node;
 
-  my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
+  gcc_assert (!arglist || TREE_CODE (arglist) == TREE_VEC);
   if (fns == NULL_TREE 
       || TREE_CODE (fns) == FUNCTION_DECL)
     {
@@ -4081,18 +4151,17 @@ lookup_template_function (tree fns, tree arglist)
       return error_mark_node;
     }
 
-  my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
-                     || TREE_CODE (fns) == OVERLOAD
-                     || BASELINK_P (fns)
-                     || TREE_CODE (fns) == IDENTIFIER_NODE,
-                     20020730);
+  gcc_assert (TREE_CODE (fns) == TEMPLATE_DECL
+             || TREE_CODE (fns) == OVERLOAD
+             || BASELINK_P (fns)
+             || TREE_CODE (fns) == IDENTIFIER_NODE);
 
   if (BASELINK_P (fns))
     {
-      BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR,
-                                       unknown_type_node,
-                                       BASELINK_FUNCTIONS (fns),
-                                       arglist);
+      BASELINK_FUNCTIONS (fns) = build2 (TEMPLATE_ID_EXPR,
+                                        unknown_type_node,
+                                        BASELINK_FUNCTIONS (fns),
+                                        arglist);
       return fns;
     }
 
@@ -4100,7 +4169,7 @@ lookup_template_function (tree fns, tree arglist)
   if (TREE_CODE (fns) == OVERLOAD || !type)
     type = unknown_type_node;
   
-  return build (TEMPLATE_ID_EXPR, type, fns, arglist);
+  return build2 (TEMPLATE_ID_EXPR, type, fns, arglist);
 }
 
 /* Within the scope of a template class S<T>, the name S gets bound
@@ -4153,9 +4222,9 @@ lookup_template_class (tree d1,
   
   if (TREE_CODE (d1) == IDENTIFIER_NODE)
     {
-      if (IDENTIFIER_VALUE (d1) 
-         && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1)))
-       template = IDENTIFIER_VALUE (d1);
+      tree value = innermost_non_namespace_value (d1);
+      if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
+       template = value;
       else
        {
          if (context)
@@ -4197,11 +4266,7 @@ lookup_template_class (tree d1,
       context = DECL_CONTEXT (template);
     }
 
-  /* With something like `template <class T> class X class X { ... };'
-     we could end up with D1 having nothing but an IDENTIFIER_VALUE.
-     We don't want to do that, but we have to deal with the situation,
-     so let's give them some syntax errors to chew on instead of a
-     crash. Alternatively D1 might not be a template type at all.  */
+  /* Issue an error message if we didn't find a template.  */
   if (! template)
     {
       if (complain & tf_error)
@@ -4302,7 +4367,7 @@ lookup_template_class (tree d1,
        }
 
       /* Now we should have enough arguments.  */
-      my_friendly_assert (parm_depth == arg_depth, 0);
+      gcc_assert (parm_depth == arg_depth);
       
       /* From here on, we're only interested in the most general
         template.  */
@@ -4591,7 +4656,7 @@ struct pair_fn_data
 /* Called from for_each_template_parm via walk_tree.  */
 
 static tree
-for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d)
+for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
 {
   tree t = *tp;
   struct pair_fn_data *pfd = (struct pair_fn_data *) d;
@@ -4824,10 +4889,12 @@ uses_template_parms (tree t)
           || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
     dependent_p = (type_dependent_expression_p (t)
                   || value_dependent_expression_p (t));
-  else if (t == error_mark_node)
-    dependent_p = false;
-  else 
-    abort ();
+  else
+    {
+      gcc_assert (t == error_mark_node);
+      dependent_p = false;
+    }
+  
   processing_template_decl = saved_processing_template_decl;
 
   return dependent_p;
@@ -4874,9 +4941,7 @@ push_tinst_level (tree d)
       return 0;
     }
 
-  new = make_node (TINST_LEVEL);
-  annotate_with_locus (new, input_location);
-  TINST_DECL (new) = d;
+  new = make_tinst_level (d, input_location);
   TREE_CHAIN (new) = current_tinst_level;
   current_tinst_level = new;
 
@@ -4900,7 +4965,7 @@ pop_tinst_level (void)
 
   /* Restore the filename and line number stashed away when we started
      this instantiation.  */
-  input_location = *EXPR_LOCUS (old);
+  input_location = TINST_LOCATION (old);
   extract_interface_info ();
   
   current_tinst_level = TREE_CHAIN (old);
@@ -4983,7 +5048,8 @@ tsubst_friend_function (tree decl, tree args)
       new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
       tmpl = determine_specialization (template_id, new_friend,
                                       &new_args, 
-                                      /*need_member_template=*/0);
+                                      /*need_member_template=*/0,
+                                      TREE_VEC_LENGTH (args));
       new_friend = instantiate_template (tmpl, new_args, tf_error);
       goto done;
     }
@@ -5283,6 +5349,7 @@ instantiate_class_template (tree type)
   tree template, args, pattern, t, member;
   tree typedecl;
   tree pbinfo;
+  tree base_list;
   
   if (type == error_mark_node)
     return error_mark_node;
@@ -5294,7 +5361,7 @@ instantiate_class_template (tree type)
 
   /* Figure out which template is being instantiated.  */
   template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
-  my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
+  gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
 
   /* Figure out which arguments are being used to do the
      instantiation.  */
@@ -5385,7 +5452,6 @@ instantiate_class_template (tree type)
   TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (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);
   TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern);
   TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern);
   TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern);
@@ -5405,22 +5471,18 @@ instantiate_class_template (tree type)
 
   pbinfo = TYPE_BINFO (pattern);
 
-#ifdef ENABLE_CHECKING
-  if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern))
-      && ! COMPLETE_TYPE_P (TYPE_CONTEXT (type))
-      && ! TYPE_BEING_DEFINED (TYPE_CONTEXT (type)))
-    /* We should never instantiate a nested class before its enclosing
-       class; we need to look up the nested class by name before we can
-       instantiate it, and that lookup should instantiate the enclosing
-       class.  */
-    abort ();
-#endif
+  /* We should never instantiate a nested class before its enclosing
+     class; we need to look up the nested class by name before we can
+     instantiate it, and that lookup should instantiate the enclosing
+     class.  */
+  gcc_assert (!DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern))
+             || COMPLETE_TYPE_P (TYPE_CONTEXT (type))
+             || TYPE_BEING_DEFINED (TYPE_CONTEXT (type)));
 
-  if (BINFO_BASETYPES (pbinfo))
+  base_list = NULL_TREE;
+  if (BINFO_N_BASE_BINFOS (pbinfo))
     {
-      tree base_list = NULL_TREE;
-      tree pbases = BINFO_BASETYPES (pbinfo);
-      tree paccesses = BINFO_BASEACCESSES (pbinfo);
+      tree pbase_binfo;
       tree context = TYPE_CONTEXT (type);
       bool pop_p;
       int i;
@@ -5432,34 +5494,31 @@ instantiate_class_template (tree type)
   
       /* Substitute into each of the bases to determine the actual
         basetypes.  */
-      for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i)
+      for (i = 0; BINFO_BASE_ITERATE (pbinfo, i, pbase_binfo); i++)
        {
          tree base;
-         tree access;
-         tree pbase;
-
-         pbase = TREE_VEC_ELT (pbases, i);
-         access = TREE_VEC_ELT (paccesses, i);
+         tree access = BINFO_BASE_ACCESS (pbinfo, i);
 
          /* Substitute to figure out the base class.  */
-         base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE);
+         base = tsubst (BINFO_TYPE (pbase_binfo), args, tf_error, NULL_TREE);
          if (base == error_mark_node)
            continue;
          
          base_list = tree_cons (access, base, base_list);
-         TREE_VIA_VIRTUAL (base_list) = TREE_VIA_VIRTUAL (pbase);
+         if (BINFO_VIRTUAL_P (pbase_binfo))
+           TREE_TYPE (base_list) = integer_type_node;
        }
 
       /* The list is now in reverse order; correct that.  */
       base_list = nreverse (base_list);
 
-      /* Now call xref_basetypes to set up all the base-class
-        information.  */
-      xref_basetypes (type, base_list);
-
       if (pop_p)
        pop_scope (context ? context : global_namespace);
     }
+  /* Now call xref_basetypes to set up all the base-class
+     information.  */
+  xref_basetypes (type, base_list);
+
 
   /* Now that our base classes are set up, enter the scope of the
      class, so that name lookups into base classes, etc. will work
@@ -5643,11 +5702,18 @@ instantiate_class_template (tree type)
              tree r;
 
              if (TREE_CODE (t) == TEMPLATE_DECL)
-               ++processing_template_decl;
+               {
+                 ++processing_template_decl;
+                 push_deferring_access_checks (dk_no_check);
+               }
+             
              r = tsubst_friend_function (t, args);
-             if (TREE_CODE (t) == TEMPLATE_DECL)
-               --processing_template_decl;
              add_friend (type, r, /*complain=*/false);
+             if (TREE_CODE (t) == TEMPLATE_DECL)
+               {
+                 pop_deferring_access_checks ();
+                 --processing_template_decl;
+               }
            }
        }
     }
@@ -5661,10 +5727,7 @@ instantiate_class_template (tree type)
 
   unreverse_member_declarations (type);
   finish_struct_1 (type);
-
-  /* Clear this now so repo_template_used is happy.  */
   TYPE_BEING_DEFINED (type) = 0;
-  repo_template_used (type);
 
   /* Now that the class is complete, instantiate default arguments for
      any member functions.  We don't do this earlier because the
@@ -5683,7 +5746,11 @@ instantiate_class_template (tree type)
   pop_deferring_access_checks ();
   pop_tinst_level ();
 
-  if (TYPE_CONTAINS_VPTR_P (type))
+  /* The vtable for a template class can be emitted in any translation
+     unit in which the class is instantiated.  When there is no key
+     method, however, finish_struct_1 will already have added TYPE to
+     the keyed_classes list.  */
+  if (TYPE_CONTAINS_VPTR_P (type) && CLASSTYPE_KEY_METHOD (type))
     keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);
 
   return type;
@@ -5885,6 +5952,9 @@ tsubst_aggr_type (tree t,
 tree
 tsubst_default_argument (tree fn, tree type, tree arg)
 {
+  tree saved_class_ptr = NULL_TREE;
+  tree saved_class_ref = NULL_TREE;
+
   /* This default argument came from a template.  Instantiate the
      default argument here, not in tsubst.  In the case of
      something like: 
@@ -5902,12 +5972,27 @@ tsubst_default_argument (tree fn, tree type, tree arg)
      within the scope of FN.  Since push_access_scope sets
      current_function_decl, we must explicitly clear it here.  */
   current_function_decl = NULL_TREE;
+  /* The "this" pointer is not valid in a default argument.  */
+  if (cfun)
+    {
+      saved_class_ptr = current_class_ptr;
+      cp_function_chain->x_current_class_ptr = NULL_TREE;
+      saved_class_ref = current_class_ref;
+      cp_function_chain->x_current_class_ref = NULL_TREE;
+    }
 
   push_deferring_access_checks(dk_no_deferred);
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
                     tf_error | tf_warning, NULL_TREE);
   pop_deferring_access_checks();
 
+  /* Restore the "this" pointer.  */
+  if (cfun)
+    {
+      cp_function_chain->x_current_class_ptr = saved_class_ptr;
+      cp_function_chain->x_current_class_ref = saved_class_ref;
+    }
+
   pop_access_scope (fn);
 
   /* Make sure the default argument is reasonable.  */
@@ -5983,7 +6068,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
            /* tsubst_template_args doesn't copy the vector if
               nothing changed.  But, *something* should have
               changed.  */
-           my_friendly_assert (full_args != tmpl_args, 0);
+           gcc_assert (full_args != tmpl_args);
 
            spec = retrieve_specialization (t, full_args);
            if (spec != NULL_TREE)
@@ -5999,7 +6084,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
           like the old one, but points to this new template, rather
           than the old one.  */
        r = copy_decl (t);
-       my_friendly_assert (DECL_LANG_SPECIFIC (r) != 0, 0);
+       gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
        TREE_CHAIN (r) = NULL_TREE;
 
        if (is_template_template_parm)
@@ -6071,7 +6156,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
        int parms_depth;
 
        /* Nobody should be tsubst'ing into non-template functions.  */
-       my_friendly_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE, 0);
+       gcc_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE);
 
        if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
          {
@@ -6203,7 +6288,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
        TREE_STATIC (r) = 0;
        TREE_PUBLIC (r) = TREE_PUBLIC (t);
        DECL_EXTERNAL (r) = 1;
-       DECL_INTERFACE_KNOWN (r) = 0;
+       /* If this is an instantiation of a function with internal
+          linkage, we already know what object file linkage will be
+          assigned to the instantiation.  */
+       DECL_INTERFACE_KNOWN (r) = !TREE_PUBLIC (r);
        DECL_DEFER_OUTPUT (r) = 0;
        TREE_CHAIN (r) = NULL_TREE;
        DECL_PENDING_INLINE_INFO (r) = 0;
@@ -6445,7 +6533,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     } 
 
   /* Restore the file and line information.  */
@@ -6527,7 +6615,7 @@ tsubst_function_type (tree t,
   tree fntype;
 
   /* The TYPE_CONTEXT is not used for function/method types.  */
-  my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0);
+  gcc_assert (TYPE_CONTEXT (t) == NULL_TREE);
 
   /* Substitute the return type.  */
   return_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
@@ -6600,9 +6688,6 @@ tsubst_call_declarator_parms (tree parms,
      doesn't check TREE_PARMLIST.  */
   new_parms = tree_cons (defarg, type, new_parms);
 
-  /* And note that these are parameters.  */
-  TREE_PARMLIST (new_parms) = 1;
-  
   return new_parms;
 }
 
@@ -6631,6 +6716,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       || t == integer_type_node
       || t == void_type_node
       || t == char_type_node
+      || t == unknown_type_node
       || TREE_CODE (t) == NAMESPACE_DECL)
     return t;
 
@@ -6639,7 +6725,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   else
     type = TREE_TYPE (t);
 
-  my_friendly_assert (type != unknown_type_node, 20030716);
+  gcc_assert (type != unknown_type_node);
 
   if (type && TREE_CODE (t) != FUNCTION_DECL
       && TREE_CODE (t) != TYPENAME_TYPE
@@ -6725,9 +6811,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        int idx;
        int level;
        int levels;
+       tree arg = NULL_TREE;
 
        r = NULL_TREE;
 
+       gcc_assert (TREE_VEC_LENGTH (args) > 0);
        if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
            || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
            || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
@@ -6741,57 +6829,50 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            level = TEMPLATE_PARM_LEVEL (t);
          }
 
-       if (TREE_VEC_LENGTH (args) > 0)
-         {
-           tree arg = NULL_TREE;
+       levels = TMPL_ARGS_DEPTH (args);
+       if (level <= levels)
+         arg = TMPL_ARG (args, level, idx);
 
-           levels = TMPL_ARGS_DEPTH (args);
-           if (level <= levels)
-             arg = TMPL_ARG (args, level, idx);
-
-           if (arg == error_mark_node)
-             return error_mark_node;
-           else if (arg != NULL_TREE)
+       if (arg == error_mark_node)
+         return error_mark_node;
+       else if (arg != NULL_TREE)
+         {
+           if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
              {
-               if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-                 {
-                   my_friendly_assert (TYPE_P (arg), 0);
-                   return cp_build_qualified_type_real
-                     (arg, cp_type_quals (arg) | cp_type_quals (t),
-                      complain | tf_ignore_bad_quals);
-                 }
-               else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
-                 {
-                   /* We are processing a type constructed from
-                      a template template parameter.  */
-                   tree argvec = tsubst (TYPE_TI_ARGS (t),
-                                         args, complain, in_decl);
-                   if (argvec == error_mark_node)
-                     return error_mark_node;
+               gcc_assert (TYPE_P (arg));
+               return cp_build_qualified_type_real
+                 (arg, cp_type_quals (arg) | cp_type_quals (t),
+                  complain | tf_ignore_bad_quals);
+             }
+           else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
+             {
+               /* We are processing a type constructed from a
+                  template template parameter.  */
+               tree argvec = tsubst (TYPE_TI_ARGS (t),
+                                     args, complain, in_decl);
+               if (argvec == error_mark_node)
+                 return error_mark_node;
                        
-                   /* We can get a TEMPLATE_TEMPLATE_PARM here when 
-                      we are resolving nested-types in the signature of 
-                      a member function templates.
-                      Otherwise ARG is a TEMPLATE_DECL and is the real 
-                      template to be instantiated.  */
-                   if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
-                     arg = TYPE_NAME (arg);
-
-                   r = lookup_template_class (arg, 
-                                              argvec, in_decl, 
-                                              DECL_CONTEXT (arg),
-                                              /*entering_scope=*/0,
-                                              complain);
-                   return cp_build_qualified_type_real
-                     (r, TYPE_QUALS (t), complain);
-                 }
-               else
-                 /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
-                 return arg;
+               /* We can get a TEMPLATE_TEMPLATE_PARM here when we
+                  are resolving nested-types in the signature of a
+                  member function templates.  Otherwise ARG is a
+                  TEMPLATE_DECL and is the real template to be
+                  instantiated.  */
+               if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+                 arg = TYPE_NAME (arg);
+               
+               r = lookup_template_class (arg, 
+                                          argvec, in_decl, 
+                                          DECL_CONTEXT (arg),
+                                           /*entering_scope=*/0,
+                                          complain);
+               return cp_build_qualified_type_real
+                 (r, TYPE_QUALS (t), complain);
              }
+           else
+             /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
+             return arg;
          }
-       else
-         abort ();
 
        if (level == 1)
          /* This can happen during the attempted tsubst'ing in
@@ -6844,7 +6925,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            break;
           
          default:
-           abort ();
+           gcc_unreachable ();
          }
 
        return r;
@@ -6852,7 +6933,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case TREE_LIST:
       {
-       tree purpose, value, chain, result;
+       tree purpose, value, chain;
 
        if (t == void_list_node)
          return t;
@@ -6882,38 +6963,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            && value == TREE_VALUE (t)
            && chain == TREE_CHAIN (t))
          return t;
-       if (TREE_PARMLIST (t))
-         {
-           result = tree_cons (purpose, value, chain);
-           TREE_PARMLIST (result) = 1;
-         }
-       else
-         result = hash_tree_cons (purpose, value, chain);
-       return result;
+       return hash_tree_cons (purpose, value, chain);
       }
-    case TREE_VEC:
-      if (type != NULL_TREE)
-       {
-         /* A binfo node.  We always need to make a copy, of the node
-            itself and of its BINFO_BASETYPES.  */
-
-         t = copy_node (t);
-
-         /* Make sure type isn't a typedef copy.  */
-         type = BINFO_TYPE (TYPE_BINFO (type));
-
-         TREE_TYPE (t) = complete_type (type);
-         if (IS_AGGR_TYPE (type))
-           {
-             BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type);
-             BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type);
-             if (TYPE_BINFO_BASETYPES (type) != NULL_TREE)
-               BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type));
-           }
-         return t;
-       }
+      
+    case TREE_BINFO:
+      /* We should never be tsubsting a binfo.  */
+      gcc_unreachable ();
 
-      /* Otherwise, a vector of template arguments.  */
+    case TREE_VEC:
+      /* A vector of template arguments.  */
+      gcc_assert (!type);
       return tsubst_template_args (t, args, complain, in_decl);
 
     case POINTER_TYPE:
@@ -6944,8 +7003,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               message to avoid spewing a ton of messages during a
               single bad template instantiation.  */
            if (complain & tf_error
+#ifdef USE_MAPPED_LOCATION
+               && last_loc != input_location)
+#else
                && (last_loc.line != input_line
                    || last_loc.file != input_filename))
+#endif
              {
                if (TREE_CODE (type) == VOID_TYPE)
                  error ("forming reference to void");
@@ -6997,7 +7060,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            
            return error_mark_node;
          }
-       my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231);
+       gcc_assert (TREE_CODE (type) != METHOD_TYPE);
        if (TREE_CODE (type) == FUNCTION_TYPE)
          {
            /* This is really a method type. The cv qualifiers of the
@@ -7103,7 +7166,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return fold (build (TREE_CODE (t), TREE_TYPE (t), e1, e2));
+       return fold (build2 (TREE_CODE (t), TREE_TYPE (t), e1, e2));
       }
 
     case NEGATE_EXPR:
@@ -7113,7 +7176,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e == error_mark_node)
          return error_mark_node;
 
-       return fold (build (TREE_CODE (t), TREE_TYPE (t), e));
+       return fold (build1 (TREE_CODE (t), TREE_TYPE (t), e));
       }
 
     case TYPENAME_TYPE:
@@ -7179,20 +7242,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       }
 
     case INDIRECT_REF:
-      {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       if (e == error_mark_node)
-         return error_mark_node;
-       return make_pointer_declarator (type, e);
-      }
-
     case ADDR_EXPR:
-      {
-       tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       if (e == error_mark_node)
-         return error_mark_node;
-       return make_reference_declarator (type, e);
-      }
+    case CALL_EXPR:
+      gcc_unreachable ();
 
     case ARRAY_REF:
       {
@@ -7201,22 +7253,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return build_nt (ARRAY_REF, e1, e2);
-      }
-
-    case CALL_EXPR:
-      {
-       tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
-       tree e2 = (tsubst_call_declarator_parms
-                  (CALL_DECLARATOR_PARMS (t), args, complain, in_decl));
-       tree e3 = tsubst (CALL_DECLARATOR_EXCEPTION_SPEC (t), args,
-                         complain, in_decl);
-
-       if (e1 == error_mark_node || e2 == error_mark_node 
-           || e3 == error_mark_node)
-         return error_mark_node;
-
-       return make_call_declarator (e1, e2, CALL_DECLARATOR_QUALS (t), e3);
+       return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE);
       }
 
     case SCOPE_REF:
@@ -7312,7 +7349,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
   bool is_template;
   tree template_args;
 
-  my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706);
+  gcc_assert (TREE_CODE (qualified_id) == SCOPE_REF);
 
   /* Figure out what name to look up.  */
   name = TREE_OPERAND (qualified_id, 1);
@@ -7364,18 +7401,28 @@ tsubst_qualified_id (tree qualified_id, tree args,
     }
   
   if (DECL_P (expr))
-    check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
-                                        scope);
-  
-  /* Remember that there was a reference to this entity.  */
-  if (DECL_P (expr))
-    mark_used (expr);
+    {
+      check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
+                                          scope);
+      /* Remember that there was a reference to this entity.  */
+      mark_used (expr);
+    }
+
+  if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST)
+    {
+      if (complain & tf_error)
+       qualified_name_lookup_error (scope, 
+                                    TREE_OPERAND (qualified_id, 1),
+                                    expr);
+      return error_mark_node;
+    }
 
   if (is_template)
     expr = lookup_template_function (expr, template_args);
 
   if (expr == error_mark_node && complain & tf_error)
-    qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1));
+    qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
+                                expr);
   else if (TYPE_P (scope))
     {
       expr = (adjust_result_of_qualified_name_lookup 
@@ -7405,7 +7452,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     {
     case PARM_DECL:
       r = retrieve_local_specialization (t);
-      my_friendly_assert (r != NULL, 20020903);
+      gcc_assert (r != NULL);
       mark_used (r);
       return r;
 
@@ -7447,7 +7494,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          /* We didn't find the name.  That should never happen; if
             name-lookup found it during preliminary parsing, we
             should find it again here during instantiation.  */
-       abort ();
+       gcc_unreachable ();
       }
       return t;
 
@@ -7461,6 +7508,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          if (ctx != DECL_CONTEXT (t))
            return lookup_field (ctx, DECL_NAME (t), 0, false);
        }
+      
       return t;
 
     case VAR_DECL:
@@ -7563,7 +7611,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                  in_decl);
        else
          name = tsubst_copy (name, args, complain, in_decl);
-       return build_nt (COMPONENT_REF, object, name);
+       return build_nt (COMPONENT_REF, object, name, NULL_TREE);
       }
 
     case PLUS_EXPR:
@@ -7624,6 +7672,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
           tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
           tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
+       TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
        return r;
       }
 
@@ -7726,6 +7775,12 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                          in_decl),
                             tsubst (TREE_TYPE (t), args, complain, in_decl));
 
+    case CLEANUP_POINT_EXPR:
+      /* We shouldn't have built any of these during initial template
+        generation.  Instead, they should be built during instantiation
+        in response to the saved STMT_IS_FULL_EXPR_P setting.  */
+      gcc_unreachable ();
+
     default:
       return t;
     }
@@ -7747,6 +7802,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   if (t == NULL_TREE || t == error_mark_node)
     return t;
 
+  if (EXPR_HAS_LOCATION (t))
+    input_location = EXPR_LOCATION (t);
+  if (STATEMENT_CODE_P (TREE_CODE (t)))
+    current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
+
   switch (TREE_CODE (t))
     {
     case STATEMENT_LIST:
@@ -7758,14 +7818,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       }
 
     case CTOR_INITIALIZER:
-      prep_stmt (t);
       finish_mem_initializers (tsubst_initializer_list 
                               (TREE_OPERAND (t, 0), args));
       break;
 
-    case RETURN_STMT:
-      prep_stmt (t);
-      finish_return_stmt (tsubst_expr (RETURN_STMT_EXPR (t),
+    case RETURN_EXPR:
+      finish_return_stmt (tsubst_expr (TREE_OPERAND (t, 0),
                                       args, complain, in_decl));
       break;
 
@@ -7783,32 +7841,24 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       }
 
     case EXPR_STMT:
-      {
-       tree r;
-       
-       prep_stmt (t);
-
-       r = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
-       if (EXPR_STMT_STMT_EXPR_RESULT (t))
-         finish_stmt_expr_expr (r, cur_stmt_expr);
-       else
-         finish_expr_stmt (r);
-       break;
-      }
+      tmp = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
+      if (EXPR_STMT_STMT_EXPR_RESULT (t))
+       finish_stmt_expr_expr (tmp, cur_stmt_expr);
+      else
+       finish_expr_stmt (tmp);
+      break;
 
     case USING_STMT:
-      prep_stmt (t);
       do_using_directive (tsubst_expr (USING_STMT_NAMESPACE (t),
                                       args, complain, in_decl));
       break;
       
-    case DECL_STMT:
+    case DECL_EXPR:
       {
        tree decl;
        tree init;
 
-       prep_stmt (t);
-       decl = DECL_STMT_DECL (t);
+       decl = DECL_EXPR_DECL (t);
        if (TREE_CODE (decl) == LABEL_DECL)
          finish_label_decl (DECL_NAME (decl));
        else if (TREE_CODE (decl) == USING_DECL)
@@ -7821,8 +7871,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            decl = lookup_qualified_name (scope, name,
                                          /*is_type_p=*/false,
                                          /*complain=*/false);
-           if (decl == error_mark_node)
-             qualified_name_lookup_error (scope, name);
+           if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
+             qualified_name_lookup_error (scope, name, decl);
            else
              do_local_using_decl (decl, scope, name);
          }
@@ -7864,128 +7914,98 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
              }
          }
 
-       /* A DECL_STMT can also be used as an expression, in the condition
+       /* A DECL_EXPR can also be used as an expression, in the condition
           clause of an if/for/while construct.  */
        return decl;
       }
 
     case FOR_STMT:
-      {
-       prep_stmt (t);
-
-       stmt = begin_for_stmt ();
-       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),
-                        stmt);
-       tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
-       finish_for_expr (tmp, stmt);
-       tsubst_expr (FOR_BODY (t), args, complain, in_decl);
-       finish_for_stmt (stmt);
-      }
+      stmt = begin_for_stmt ();
+      tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl);
+      finish_for_init_stmt (stmt);
+      tmp = tsubst_expr (FOR_COND (t), args, complain, in_decl);
+      finish_for_cond (tmp, stmt);
+      tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
+      finish_for_expr (tmp, stmt);
+      tsubst_expr (FOR_BODY (t), args, complain, in_decl);
+      finish_for_stmt (stmt);
       break;
 
     case WHILE_STMT:
-      {
-       prep_stmt (t);
-       stmt = begin_while_stmt ();
-       finish_while_stmt_cond (tsubst_expr (WHILE_COND (t),
-                                            args, complain, in_decl),
-                               stmt);
-       tsubst_expr (WHILE_BODY (t), args, complain, in_decl);
-       finish_while_stmt (stmt);
-      }
+      stmt = begin_while_stmt ();
+      tmp = tsubst_expr (WHILE_COND (t), args, complain, in_decl);
+      finish_while_stmt_cond (tmp, stmt);
+      tsubst_expr (WHILE_BODY (t), args, complain, in_decl);
+      finish_while_stmt (stmt);
       break;
 
     case DO_STMT:
-      {
-       prep_stmt (t);
-       stmt = begin_do_stmt ();
-       tsubst_expr (DO_BODY (t), args, complain, in_decl);
-       finish_do_body (stmt);
-       finish_do_stmt (tsubst_expr (DO_COND (t),
-                                    args, complain, in_decl),
-                       stmt);
-      }
+      stmt = begin_do_stmt ();
+      tsubst_expr (DO_BODY (t), args, complain, in_decl);
+      finish_do_body (stmt);
+      tmp = tsubst_expr (DO_COND (t), args, complain, in_decl);
+      finish_do_stmt (tmp, stmt);
       break;
 
     case IF_STMT:
-      {
-       prep_stmt (t);
-       stmt = begin_if_stmt ();
-       finish_if_stmt_cond (tsubst_expr (IF_COND (t),
-                                         args, complain, in_decl),
-                            stmt);
-       tsubst_expr (THEN_CLAUSE (t), args, complain, in_decl);
-       finish_then_clause (stmt);
-
-       if (ELSE_CLAUSE (t))
-         {
-           begin_else_clause (stmt);
-           tsubst_expr (ELSE_CLAUSE (t), args, complain, in_decl);
-           finish_else_clause (stmt);
-         }
+      stmt = begin_if_stmt ();
+      tmp = tsubst_expr (IF_COND (t), args, complain, in_decl);
+      finish_if_stmt_cond (tmp, stmt);
+      tsubst_expr (THEN_CLAUSE (t), args, complain, in_decl);
+      finish_then_clause (stmt);
 
-       finish_if_stmt (stmt);
-      }
+      if (ELSE_CLAUSE (t))
+       {
+         begin_else_clause (stmt);
+         tsubst_expr (ELSE_CLAUSE (t), args, complain, in_decl);
+         finish_else_clause (stmt);
+       }
+
+      finish_if_stmt (stmt);
       break;
 
-    case COMPOUND_STMT:
-      {
-       prep_stmt (t);
-       if (COMPOUND_STMT_BODY_BLOCK (t))
-         stmt = begin_function_body ();
-       else
-         stmt = begin_compound_stmt (COMPOUND_STMT_TRY_BLOCK (t)
-                                     ? BCS_TRY_BLOCK : 0);
+    case BIND_EXPR:
+      if (BIND_EXPR_BODY_BLOCK (t))
+       stmt = begin_function_body ();
+      else
+       stmt = begin_compound_stmt (BIND_EXPR_TRY_BLOCK (t)
+                                   ? BCS_TRY_BLOCK : 0);
 
-       tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+      tsubst_expr (BIND_EXPR_BODY (t), args, complain, in_decl);
 
-       if (COMPOUND_STMT_BODY_BLOCK (t))
-         finish_function_body (stmt);
-       else
-         finish_compound_stmt (stmt);
-      }
+      if (BIND_EXPR_BODY_BLOCK (t))
+       finish_function_body (stmt);
+      else
+       finish_compound_stmt (stmt);
       break;
 
     case BREAK_STMT:
-      prep_stmt (t);
       finish_break_stmt ();
       break;
 
     case CONTINUE_STMT:
-      prep_stmt (t);
       finish_continue_stmt ();
       break;
 
     case SWITCH_STMT:
-      {
-       tree val;
-
-       prep_stmt (t);
-       stmt = begin_switch_stmt ();
-       val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
-       finish_switch_cond (val, stmt);
-       tsubst_expr (SWITCH_BODY (t), args, complain, in_decl);
-       finish_switch_stmt (stmt);
-      }
+      stmt = begin_switch_stmt ();
+      tmp = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
+      finish_switch_cond (tmp, stmt);
+      tsubst_expr (SWITCH_BODY (t), args, complain, in_decl);
+      finish_switch_stmt (stmt);
       break;
 
     case CASE_LABEL_EXPR:
-      prep_stmt (t);
       finish_case_label (tsubst_expr (CASE_LOW (t), args, complain, in_decl),
                         tsubst_expr (CASE_HIGH (t), args, complain,
                                      in_decl));
       break;
 
     case LABEL_EXPR:
-      prep_stmt (t);
       finish_label_stmt (DECL_NAME (LABEL_EXPR_LABEL (t)));
       break;
 
     case GOTO_EXPR:
-      prep_stmt (t);
       tmp = GOTO_DESTINATION (t);
       if (TREE_CODE (tmp) != LABEL_DECL)
        /* Computed goto's must be tsubst'd into.  On the other hand,
@@ -7998,7 +8018,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case ASM_EXPR:
-      prep_stmt (t);
       tmp = finish_asm_stmt
        (ASM_VOLATILE_P (t),
         tsubst_expr (ASM_STRING (t), args, complain, in_decl),
@@ -8009,7 +8028,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case TRY_BLOCK:
-      prep_stmt (t);
       if (CLEANUP_P (t))
        {
          stmt = begin_try_block ();
@@ -8045,7 +8063,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree decl;
 
-       prep_stmt (t);
        stmt = begin_handler ();
        if (HANDLER_PARMS (t))
          {
@@ -8065,15 +8082,19 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       break;
 
     case TAG_DEFN:
-      prep_stmt (t);
       tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
       break;
 
+    case OFFSETOF_EXPR:
+      t = tsubst_copy_and_build (TREE_OPERAND (t, 0), args, complain,
+                                in_decl, false);
+      return fold_offsetof (t);
+
     default:
-      if (!STATEMENT_CODE_P (TREE_CODE (t)))
-       return tsubst_copy_and_build (t, args, complain, in_decl,
-                                     /*function_p=*/false);
-      abort ();
+      gcc_assert (!STATEMENT_CODE_P (TREE_CODE (t)));
+      
+      return tsubst_copy_and_build (t, args, complain, in_decl,
+                                   /*function_p=*/false);
     }
 
   return NULL_TREE;
@@ -8175,8 +8196,8 @@ tsubst_copy_and_build (tree t,
        template = lookup_template_function (template, targs);
        
        if (object)
-         return build (COMPONENT_REF, TREE_TYPE (template), 
-                       object, template);
+         return build3 (COMPONENT_REF, TREE_TYPE (template), 
+                        object, template, NULL_TREE);
        else
          return template;
       }
@@ -8288,7 +8309,8 @@ tsubst_copy_and_build (tree t,
       if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl)
          == NULL_TREE)
        /* new-type-id */
-       return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)));
+       return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)),
+                        NULL_TREE, NULL_TREE);
 
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
                                                args, complain, in_decl);
@@ -8320,10 +8342,21 @@ tsubst_copy_and_build (tree t,
        return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
 
     case MODOP_EXPR:
-      return build_x_modify_expr
-       (RECUR (TREE_OPERAND (t, 0)),
-        TREE_CODE (TREE_OPERAND (t, 1)),
-        RECUR (TREE_OPERAND (t, 2)));
+      {
+       tree r = build_x_modify_expr
+         (RECUR (TREE_OPERAND (t, 0)),
+          TREE_CODE (TREE_OPERAND (t, 1)),
+          RECUR (TREE_OPERAND (t, 2)));
+       /* TREE_NO_WARNING must be set if either the expression was
+          parenthesized or it uses an operator such as >>= rather
+          than plain assignment.  In the former case, it was already
+          set and must be copied.  In the latter case,
+          build_x_modify_expr sets it and it must not be reset
+          here.  */
+       if (TREE_NO_WARNING (t))
+         TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
+       return r;
+      }
 
     case ARROW_EXPR:
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
@@ -8338,6 +8371,7 @@ tsubst_copy_and_build (tree t,
        (RECUR (TREE_OPERAND (t, 0)),
         RECUR (TREE_OPERAND (t, 1)),
         RECUR (TREE_OPERAND (t, 2)),
+        RECUR (TREE_OPERAND (t, 3)),
         NEW_EXPR_USE_GLOBAL (t));
 
     case DELETE_EXPR:
@@ -8508,10 +8542,26 @@ tsubst_copy_and_build (tree t,
                            args);
            else
              {
-               qualified_name_lookup_error (TREE_TYPE (object), tmpl);
+               qualified_name_lookup_error (TREE_TYPE (object), tmpl,
+                                            member);
                return error_mark_node;
              }
          }
+       else if (TREE_CODE (member) == SCOPE_REF
+                && !CLASS_TYPE_P (TREE_OPERAND (member, 0))
+                && TREE_CODE (TREE_OPERAND (member, 0)) != NAMESPACE_DECL)
+         {
+           if (complain & tf_error)
+             {
+               if (TYPE_P (TREE_OPERAND (member, 0)))
+                 error ("`%T' is not a class or namespace", 
+                        TREE_OPERAND (member, 0));
+               else
+                 error ("`%D' is not a class or namespace", 
+                        TREE_OPERAND (member, 0));
+             }
+           return error_mark_node;
+         }
        else if (TREE_CODE (member) == FIELD_DECL)
          return finish_non_static_data_member (member, object, NULL_TREE);
 
@@ -8609,7 +8659,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
             shall not be used to declare an entity with linkage.
             This implies that names with no linkage cannot be used as
             template arguments.  */
-         tree nt = no_linkage_check (t);
+         tree nt = no_linkage_check (t, /*relaxed_p=*/false);
 
          if (nt)
            {
@@ -8623,7 +8673,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
            }
          /* In order to avoid all sorts of complications, we do not
             allow variably-modified types as template arguments.  */
-         else if (variably_modified_type_p (t))
+         else if (variably_modified_type_p (t, NULL_TREE))
            {
              if (complain & tf_error)
                error ("`%T' is a variably modified type", t);
@@ -8659,7 +8709,7 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
   if (tmpl == error_mark_node)
     return error_mark_node;
 
-  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);
+  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
 
   /* If this function is a clone, handle it specially.  */
   if (DECL_CLONED_FUNCTION_P (tmpl))
@@ -8673,13 +8723,11 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
        return error_mark_node;
 
       /* Look for the clone.  */
-      for (clone = TREE_CHAIN (spec);
-          clone && DECL_CLONED_FUNCTION_P (clone);
-          clone = TREE_CHAIN (clone))
+      FOR_EACH_CLONE (clone, spec)
        if (DECL_NAME (clone) == DECL_NAME (tmpl))
          return clone;
       /* We should always have found the clone by now.  */
-      abort ();
+      gcc_unreachable ();
       return NULL_TREE;
     }
   
@@ -8793,7 +8841,7 @@ fn_type_unification (tree fn,
   tree fntype;
   int result;
 
-  my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0);
+  gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
 
   fntype = TREE_TYPE (fn);
   if (explicit_targs)
@@ -8941,7 +8989,7 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
         }
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   if (TREE_CODE (*parm) != REFERENCE_TYPE)
@@ -9015,11 +9063,10 @@ type_unification_real (tree tparms,
   tree parms, args;
   int len;
 
-  my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
-  my_friendly_assert (xparms == NULL_TREE 
-                     || TREE_CODE (xparms) == TREE_LIST, 290);
-  my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291);
-  my_friendly_assert (ntparms > 0, 292);
+  gcc_assert (TREE_CODE (tparms) == TREE_VEC);
+  gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
+  gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST);
+  gcc_assert (ntparms > 0);
 
   switch (strict)
     {
@@ -9041,7 +9088,7 @@ type_unification_real (tree tparms,
       break;
       
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   if (xlen == 0)
@@ -9098,7 +9145,7 @@ type_unification_real (tree tparms,
        
       if (!TYPE_P (arg))
        {
-         my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
+         gcc_assert (TREE_TYPE (arg) != NULL_TREE);
          if (type_unknown_p (arg))
            {
              /* [temp.deduct.type] A template-argument can be deduced from
@@ -9229,16 +9276,16 @@ resolve_overloaded_unification (tree tparms,
            }
        }
     }
-  else if (TREE_CODE (arg) == OVERLOAD
-          || TREE_CODE (arg) == FUNCTION_DECL)
+  else
     {
+      gcc_assert (TREE_CODE (arg) == OVERLOAD
+                 || TREE_CODE (arg) == FUNCTION_DECL);
+  
       for (; arg; arg = OVL_NEXT (arg))
        good += try_one_overload (tparms, targs, tempargs, parm,
                                  TREE_TYPE (OVL_CURRENT (arg)),
                                  strict, sub_strict, addr_p);
     }
-  else
-    abort ();
 
   /* [temp.deduct.type] A template-argument can be deduced from a pointer
      to function or pointer to member function argument if the set of
@@ -9437,8 +9484,8 @@ get_template_base_recursive (tree tparms,
                              tree rval, 
                              int flags)
 {
-  tree binfos;
-  int i, n_baselinks;
+  tree base_binfo;
+  int i;
   tree arg = BINFO_TYPE (arg_binfo);
 
   if (!(flags & GTB_IGNORE_TYPE))
@@ -9460,13 +9507,9 @@ get_template_base_recursive (tree tparms,
        rval = r;
     }
 
-  binfos = BINFO_BASETYPES (arg_binfo);
-  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
   /* Process base types.  */
-  for (i = 0; i < n_baselinks; i++)
+  for (i = 0; BINFO_BASE_ITERATE (arg_binfo, i, base_binfo); i++)
     {
-      tree base_binfo = TREE_VEC_ELT (binfos, i);
       int this_virtual;
 
       /* Skip this base, if we've already seen it.  */
@@ -9474,7 +9517,7 @@ get_template_base_recursive (tree tparms,
        continue;
 
       this_virtual = 
-       (flags & GTB_VIA_VIRTUAL) || TREE_VIA_VIRTUAL (base_binfo);
+       (flags & GTB_VIA_VIRTUAL) || BINFO_VIRTUAL_P (base_binfo);
       
       /* When searching for a non-virtual, we cannot mark virtually
         found binfos.  */
@@ -9509,9 +9552,13 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
   tree rval;
   tree arg_binfo;
 
-  my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)), 92);
+  gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
   
   arg_binfo = TYPE_BINFO (complete_type (arg));
+  if (!arg_binfo)
+    /* The type could not be completed.  */
+    return NULL_TREE;
+  
   rval = get_template_base_recursive (tparms, targs,
                                      parm, arg_binfo, 
                                      NULL_TREE,
@@ -9539,9 +9586,9 @@ template_decl_level (tree decl)
       return TEMPLATE_PARM_LEVEL (DECL_INITIAL (decl));
 
     default:
-      abort ();
-      return 0;
+      gcc_unreachable ();
     }
+  return 0;
 }
 
 /* Decide whether ARG can be unified with PARM, considering only the
@@ -9615,14 +9662,7 @@ check_cv_quals_for_unify (int strict, tree arg, tree 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.
-     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.  */
+       qualified at this point.  */
 
 static int
 unify (tree tparms, tree targs, tree parm, tree arg, int strict)
@@ -9676,7 +9716,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
   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))
     {
@@ -9721,7 +9760,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          {
            tree parmtmpl = TYPE_TI_TEMPLATE (parm);
            tree parmvec = TYPE_TI_ARGS (parm);
-           tree argvec = TYPE_TI_ARGS (arg);
+           tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
            tree argtmplvec
              = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg));
            int i;
@@ -9744,9 +9783,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
            for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
              {
-               tree t = TREE_VEC_ELT (parmvec, i);
-
-               if (unify (tparms, targs, t, 
+               if (unify (tparms, targs, 
+                          TREE_VEC_ELT (parmvec, i), 
                           TREE_VEC_ELT (argvec, i), 
                           UNIFY_ALLOW_NONE))
                  return 1;
@@ -9798,7 +9836,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
             the bound of the array will not be computable in an
             instantiation.  Besides, such types are not allowed in
             ISO C++, so we can do as we please here.  */
-         if (variably_modified_type_p (arg))
+         if (variably_modified_type_p (arg, NULL_TREE))
            return 1;
        }
 
@@ -9839,7 +9877,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       else if ((strict & UNIFY_ALLOW_INTEGER)
               && (TREE_CODE (tparm) == INTEGER_TYPE
                   || TREE_CODE (tparm) == BOOLEAN_TYPE))
-       /* OK */;
+       /* Convert the ARG to the type of PARM; the deduced non-type
+          template argument must exactly match the types of the
+          corresponding parameter.  */
+       arg = fold (build_nop (TREE_TYPE (parm), arg));
       else if (uses_template_parms (tparm))
        /* We haven't deduced the type of this parameter yet.  Try again
           later.  */
@@ -9907,10 +9948,29 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       if ((TYPE_DOMAIN (parm) == NULL_TREE)
          != (TYPE_DOMAIN (arg) == NULL_TREE))
        return 1;
-      if (TYPE_DOMAIN (parm) != NULL_TREE
-         && unify (tparms, targs, TYPE_DOMAIN (parm),
-                   TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE) != 0)
-       return 1;
+      if (TYPE_DOMAIN (parm) != NULL_TREE)
+       {
+         tree parm_max;
+         tree arg_max;
+
+         parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
+         arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
+
+         /* Our representation of array types uses "N - 1" as the
+            TYPE_MAX_VALUE for an array with "N" elements, if "N" is
+            not an integer constant.  */
+         if (TREE_CODE (parm_max) == MINUS_EXPR)
+           {
+             arg_max = fold (build2 (PLUS_EXPR, 
+                                     integer_type_node,
+                                     arg_max,
+                                     TREE_OPERAND (parm_max, 1)));
+             parm_max = TREE_OPERAND (parm_max, 0);
+           }
+
+         if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER))
+           return 1;
+       }
       return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
                    strict & UNIFY_ALLOW_MORE_CV_QUAL);
 
@@ -9922,23 +9982,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
     case VOID_TYPE:
       if (TREE_CODE (arg) != TREE_CODE (parm))
        return 1;
-
-      if (TREE_CODE (parm) == INTEGER_TYPE
-         && TREE_CODE (TYPE_MAX_VALUE (parm)) != INTEGER_CST)
-       {
-         if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
-             && unify (tparms, targs, TYPE_MIN_VALUE (parm),
-                       TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER))
-           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 | UNIFY_ALLOW_MAX_CORRECTION))
-           return 1;
-       }
+      
       /* We have already checked cv-qualification at the top of the
         function.  */
-      else if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))
+      if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))
        return 1;
 
       /* As far as unification is concerned, this wins.         Later checks
@@ -10064,27 +10111,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       /* Matched cases are handled by the ARG == PARM test above.  */
       return 1;
 
-    case MINUS_EXPR:
-      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:
-
-            template <int N> void f(int (&x)[N]);
-
-            Here, we are trying to unify the range type, which
-            looks like [0 ... (N - 1)].  */
-         tree t, t1, t2;
-         t1 = TREE_OPERAND (parm, 0);
-         t2 = TREE_OPERAND (parm, 1);
-
-         t = fold (build (PLUS_EXPR, integer_type_node, arg, t2));
-
-         return unify (tparms, targs, t1, t, strict);
-       }
-      /* Else fall through.  */
-
     default:
       if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))
        {
@@ -10122,9 +10148,20 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
     }
 }
 \f
+/* Note that DECL can be defined in this translation unit, if
+   required.  */
+
+static void
+mark_definable (tree decl)
+{
+  tree clone;
+  DECL_NOT_REALLY_EXTERN (decl) = 1;
+  FOR_EACH_CLONE (clone, decl)
+    DECL_NOT_REALLY_EXTERN (clone) = 1;
+}
+
 /* Called if RESULT is explicitly instantiated, or is a member of an
-   explicitly instantiated class, or if using -frepo and the
-   instantiation of RESULT has been assigned to this file.  */
+   explicitly instantiated class.  */
 
 void
 mark_decl_instantiated (tree result, int extern_p)
@@ -10144,11 +10181,11 @@ mark_decl_instantiated (tree result, int extern_p)
   /* This might have been set by an earlier implicit instantiation.  */
   DECL_COMDAT (result) = 0;
 
-  if (! extern_p)
+  if (extern_p)
+    DECL_NOT_REALLY_EXTERN (result) = 0;
+  else
     {
-      DECL_INTERFACE_KNOWN (result) = 1;
-      DECL_NOT_REALLY_EXTERN (result) = 1;
-
+      mark_definable (result);
       /* Always make artificials weak.  */
       if (DECL_ARTIFICIAL (result) && flag_weak)
        comdat_linkage (result);
@@ -10157,11 +10194,13 @@ mark_decl_instantiated (tree result, int extern_p)
       else if (TREE_PUBLIC (result))
        maybe_make_one_only (result);
     }
-
-  if (TREE_CODE (result) == FUNCTION_DECL 
-      && (DECL_ARTIFICIAL (result) 
-         || (DECL_DECLARED_INLINE_P (result) && TREE_USED (result))))
-    defer_fn (result);
+  
+  /* If EXTERN_P, then this function will not be emitted -- unless
+     followed by an explicit instantiation, at which point its linkage
+     will be adjusted.  If !EXTERN_P, then this function will be
+     emitted here.  In neither circumstance do we want
+     import_export_decl to adjust the linkage.  */
+  DECL_INTERFACE_KNOWN (result) = 1; 
 }
 
 /* Given two function templates PAT1 and PAT2, return:
@@ -10599,15 +10638,14 @@ do_decl_instantiation (tree decl, tree storage)
         No program shall explicitly instantiate any template more
         than once.  
 
-        We check DECL_INTERFACE_KNOWN so as not to complain when the first
-        instantiation was `extern' and the second is not, and EXTERN_P for
-        the opposite case.  If -frepo, chances are we already got marked
-        as an explicit instantiation because of the repo file.  */
-      if (DECL_INTERFACE_KNOWN (result) && !extern_p && !flag_use_repository)
+        We check DECL_NOT_REALLY_EXTERN so as not to complain when
+        the first instantiation was `extern' and the second is not,
+        and EXTERN_P for the opposite case.  */
+      if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
        pedwarn ("duplicate explicit instantiation of `%#D'", result);
-
-      /* If we've already instantiated the template, just return now.  */
-      if (DECL_INTERFACE_KNOWN (result))
+      /* If an "extern" explicit instantiation follows an ordinary
+        explicit instantiation, the template is instantiated.  */
+      if (extern_p)
        return;
     }
   else if (!DECL_IMPLICIT_INSTANTIATION (result))
@@ -10634,7 +10672,6 @@ do_decl_instantiation (tree decl, tree storage)
              storage);
 
   mark_decl_instantiated (result, extern_p);
-  repo_template_instantiated (result, extern_p);
   if (! extern_p)
     instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0);
 }
@@ -10672,7 +10709,6 @@ static void
 instantiate_class_member (tree decl, int extern_p)
 {
   mark_decl_instantiated (decl, extern_p);
-  repo_template_instantiated (decl, extern_p);
   if (! extern_p)
     instantiate_decl (decl, /*defer_ok=*/1, /* undefined_ok=*/1);
 }
@@ -10752,14 +10788,10 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
 
          If PREVIOUS_INSTANTIATION_EXTERN_P, 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
-        instantiation because of the repo file.  All these cases are
-        OK.  */
-
+        These cases are OK.  */
       previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
 
       if (!previous_instantiation_extern_p && !extern_p
-         && !flag_use_repository
          && (complain & tf_error))
        pedwarn ("duplicate explicit instantiation of `%#T'", t);
       
@@ -10769,7 +10801,6 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
     }
 
   mark_class_instantiated (t, extern_p);
-  repo_template_instantiated (t, extern_p);
 
   if (nomem_p)
     return;
@@ -10857,7 +10888,7 @@ regenerate_decl_from_template (tree decl, tree tmpl)
   /* If the DECL was not unregistered then something peculiar is
      happening: we created a specialization but did not call
      register_specialization for it.  */
-  my_friendly_assert (unregistered, 0);
+  gcc_assert (unregistered);
 
   /* Make sure that we can see identifiers, and compute access
      correctly.  */
@@ -10952,9 +10983,8 @@ template_for_substitution (tree decl)
         cannot restructure the loop to just keep going until we find
         a template with a definition, since that might go too far if
         a specialization was declared, but not defined.  */
-      my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL
-                           && !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl))), 
-                         0); 
+      gcc_assert (TREE_CODE (decl) != VAR_DECL
+                 || DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl)));
       
       /* Fetch the more general template.  */
       tmpl = DECL_TI_TEMPLATE (tmpl);
@@ -10989,8 +11019,8 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
   
   /* This function should only be used to instantiate templates for
      functions and static member variables.  */
-  my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
-                     || TREE_CODE (d) == VAR_DECL, 0);
+  gcc_assert (TREE_CODE (d) == FUNCTION_DECL
+             || TREE_CODE (d) == VAR_DECL);
 
   /* Variables are never deferred; if instantiation is required, they
      are instantiated right away.  That allows for better code in the
@@ -11052,38 +11082,22 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
     pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE);
   else
     pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
+  /* Unless an explicit instantiation directive has already determined
+     the linkage of D, remember that a definition is available for
+     this entity.  */
+  if (pattern_defined 
+      && !DECL_INTERFACE_KNOWN (d)
+      && !DECL_NOT_REALLY_EXTERN (d))
+    mark_definable (d);
 
   input_location = DECL_SOURCE_LOCATION (d);
 
-  if (pattern_defined)
+  if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
     {
-      /* 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 (at_eof)
-       import_export_decl (d);
+      DECL_NOT_REALLY_EXTERN (d) = 0;
+      SET_DECL_IMPLICIT_INSTANTIATION (d);
     }
 
-  if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
-    SET_DECL_IMPLICIT_INSTANTIATION (d);
-
   if (!defer_ok)
     {
       /* Recheck the substitutions to obtain any warning messages
@@ -11112,15 +11126,18 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
       pop_access_scope (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)))
+  /* We should have set up DECL_INITIAL in instantiate_class_template
+     for in-class definitions of static data members.  */
+  gcc_assert (!(TREE_CODE (d) == VAR_DECL 
+               && DECL_INITIALIZED_IN_CLASS_P (d)
+               && DECL_INITIAL (d) == NULL_TREE));
+
+  /* Do not instantiate templates that we know will be defined
+     elsewhere.  */
+  if (DECL_INTERFACE_KNOWN (d)
+      && DECL_REALLY_EXTERN (d)
+      && ! (TREE_CODE (d) == FUNCTION_DECL 
+           && DECL_INLINE (d)))
     goto out;
   /* Defer all other templates, unless we have been explicitly
      forbidden from doing so.  We restore the source position here
@@ -11144,6 +11161,24 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
       add_pending_template (d);
       goto out;
     }
+  /* Tell the repository that D is available in this translation unit
+     -- and see if it is supposed to be instantiated here.  */
+  if (TREE_PUBLIC (d) && !DECL_REALLY_EXTERN (d) && !repo_emit_p (d))
+    {
+      /* In a PCH file, despite the fact that the repository hasn't
+        requested instantiation in the PCH it is still possible that
+        an instantiation will be required in a file that includes the
+        PCH.  */
+      if (pch_file)
+       add_pending_template (d);
+      /* Instantiate inline functions so that the inliner can do its
+        job, even though we'll not be emitting a copy of this
+        function.  */
+      if (!(TREE_CODE (d) == FUNCTION_DECL
+           && flag_inline_trees 
+           && DECL_DECLARED_INLINE_P (d)))
+       goto out;
+    }
 
   need_push = !cfun || !global_bindings_p ();
   if (need_push)
@@ -11156,7 +11191,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
   /* Regenerate the declaration in case the template has been modified
      by a subsequent redeclaration.  */
   regenerate_decl_from_template (d, td);
-  
+
   /* We already set the file and line above.  Reset them now in case
      they changed as a result of calling regenerate_decl_from_template.  */
   input_location = DECL_SOURCE_LOCATION (d);
@@ -11166,51 +11201,20 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
       /* Clear out DECL_RTL; whatever was there before may not be right
         since we've reset the type of the declaration.  */
       SET_DECL_RTL (d, NULL_RTX);
-
       DECL_IN_AGGR_P (d) = 0;
-      import_export_decl (d);
-      DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d);
 
-      if (DECL_EXTERNAL (d))
-       {
-         /* The fact that this code is executing indicates that:
-            
-            (1) D is a template static data member, for which a
-                definition is available.
-
-            (2) An implicit or explicit instantiation has occurred.
-
-            (3) We are not going to emit a definition of the static
-                data member at this time.
-
-            This situation is peculiar, but it occurs on platforms
-            without weak symbols when performing an implicit
-            instantiation.  There, we cannot implicitly instantiate a
-            defined static data member in more than one translation
-            unit, so import_export_decl marks the declaration as
-            external; we must rely on explicit instantiation.
+      /* Clear DECL_EXTERNAL so that cp_finish_decl will process the
+        initializer.  That function will defer actual emission until
+        we have a chance to determine linkage.  */
+      DECL_EXTERNAL (d) = 0;
 
-             Reset instantiated marker to make sure that later
-             explicit instantiation will be processed.  */
-          DECL_TEMPLATE_INSTANTIATED (d) = 0;
-       }
-      else
-       {
-         /* This is done in analogous to `start_decl'.  It is
-            required for correct access checking.  */
-         push_nested_class (DECL_CONTEXT (d));
-         cp_finish_decl (d, 
-                         (!DECL_INITIALIZED_IN_CLASS_P (d) 
-                          ? DECL_INITIAL (d) : NULL_TREE),
-                         NULL_TREE, 0);
-         /* Normally, pop_nested_class is called by cp_finish_decl
-            above.  But when instantiate_decl is triggered during
-            instantiate_class_template processing, its DECL_CONTEXT
-            is still not completed yet, and pop_nested_class isn't
-            called.  */
-         if (!COMPLETE_TYPE_P (DECL_CONTEXT (d)))
-           pop_nested_class ();
-       }
+      /* Enter the scope of D so that access-checking works correctly.  */
+      push_nested_class (DECL_CONTEXT (d));
+      cp_finish_decl (d, 
+                     (!DECL_INITIALIZED_IN_CLASS_P (d) 
+                      ? DECL_INITIAL (d) : NULL_TREE),
+                     NULL_TREE, 0);
+      pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
     {
@@ -11219,10 +11223,6 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
       tree tmpl_parm;
       tree spec_parm;
 
-      /* Mark D as instantiated so that recursive calls to
-        instantiate_decl do not try to instantiate it again.  */
-      DECL_TEMPLATE_INSTANTIATED (d) = 1;
-
       /* Save away the current list, in case we are instantiating one
         template from within the body of another.  */
       saved_local_specializations = local_specializations;
@@ -11234,8 +11234,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
                                           NULL);
 
       /* Set up context.  */
-      import_export_decl (d);
-      start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
+      start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
 
       /* Create substitution entries for the parameters.  */
       subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d));
@@ -11253,7 +11252,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
          tmpl_parm = TREE_CHAIN (tmpl_parm);
          spec_parm = TREE_CHAIN (spec_parm);
        }
-      my_friendly_assert (!spec_parm, 20020813);
+      gcc_assert (!spec_parm);
 
       /* Substitute into the body of the function.  */
       tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
@@ -11285,17 +11284,30 @@ out:
 }
 
 /* Run through the list of templates that we wish we could
-   instantiate, and instantiate any we can.  */
+   instantiate, and instantiate any we can.  RETRIES is the
+   number of times we retry pending template instantiation.  */
 
-int
-instantiate_pending_templates (void)
+void
+instantiate_pending_templates (int retries)
 {
   tree *t;
   tree last = NULL_TREE;
-  int instantiated_something = 0;
   int reconsider;
   location_t saved_loc = input_location;
-  
+
+  /* Instantiating templates may trigger vtable generation.  This in turn
+     may require further template instantiations.  We place a limit here
+     to avoid infinite loop.  */
+  if (pending_templates && retries >= max_tinst_depth)
+    {
+      cp_error_at ("template instantiation depth exceeds maximum of %d"
+                  " (use -ftemplate-depth-NN to increase the maximum)"
+                  " instantiating `%+D', possibly from virtual table"
+                  " generation",
+                  max_tinst_depth, TREE_VALUE (pending_templates));
+      return;
+    }
+
   do 
     {
       reconsider = 0;
@@ -11319,12 +11331,10 @@ instantiate_pending_templates (void)
                         fn;
                         fn = TREE_CHAIN (fn))
                      if (! DECL_ARTIFICIAL (fn))
-                       instantiate_decl (fn, /*defer_ok=*/0, /*undefined_ok=*/0);
+                       instantiate_decl (fn, /*defer_ok=*/0,
+                                         /*undefined_ok=*/0);
                  if (COMPLETE_TYPE_P (instantiation))
-                   {
-                     instantiated_something = 1;
-                     reconsider = 1;
-                   }
+                   reconsider = 1;
                }
 
              if (COMPLETE_TYPE_P (instantiation))
@@ -11346,10 +11356,7 @@ instantiate_pending_templates (void)
                                                    /*defer_ok=*/0,
                                                    /*undefined_ok=*/0);
                  if (DECL_TEMPLATE_INSTANTIATED (instantiation))
-                   {
-                     instantiated_something = 1;
-                     reconsider = 1;
-                   }
+                   reconsider = 1;
                }
 
              if (DECL_TEMPLATE_SPECIALIZATION (instantiation)
@@ -11371,7 +11378,6 @@ instantiate_pending_templates (void)
   while (reconsider);
 
   input_location = saved_loc;
-  return instantiated_something;
 }
 
 /* Substitute ARGVEC into T, which is a list of initializers for
@@ -11485,7 +11491,7 @@ get_mostly_instantiated_function_type (tree decl)
 
   /* There should be as many levels of arguments as there are levels
      of parameters.  */
-  my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0);
+  gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs));
 
   fn_type = TREE_TYPE (tmpl);
 
@@ -11717,7 +11723,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree))
   tree scope;
   tree name;
 
-  my_friendly_assert (TREE_CODE (expression) == SCOPE_REF, 20030714);
+  gcc_assert (TREE_CODE (expression) == SCOPE_REF);
 
   if (!TYPE_P (TREE_OPERAND (expression, 0)))
     return true;
@@ -11788,8 +11794,7 @@ value_dependent_expression_p (tree expression)
          /* If there are no operands, it must be an expression such
             as "int()". This should not happen for aggregate types
             because it would form non-constant expressions.  */
-         my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type), 
-                             20040318);
+         gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
 
          return false;
        }
@@ -11941,9 +11946,13 @@ type_dependent_expression_p (tree expression)
          if (TREE_CODE (expression) == IDENTIFIER_NODE)
            return false;
        }
+      /* SCOPE_REF with non-null TREE_TYPE is always non-dependent.  */
+      if (TREE_CODE (expression) == SCOPE_REF)
+       return false;
       
       if (TREE_CODE (expression) == BASELINK)
        expression = BASELINK_FUNCTIONS (expression);
+      
       if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
        {
          if (any_dependent_template_arguments_p
@@ -11951,17 +11960,15 @@ type_dependent_expression_p (tree expression)
            return true;
          expression = TREE_OPERAND (expression, 0);
        }
-      if (TREE_CODE (expression) == OVERLOAD)
+      gcc_assert (TREE_CODE (expression) == OVERLOAD);
+      
+      while (expression)
        {
-         while (expression)
-           {
-             if (type_dependent_expression_p (OVL_CURRENT (expression)))
-               return true;
-             expression = OVL_NEXT (expression);
-           }
-         return false;
+         if (type_dependent_expression_p (OVL_CURRENT (expression)))
+           return true;
+         expression = OVL_NEXT (expression);
        }
-      abort ();
+      return false;
     }
   
   return (dependent_type_p (TREE_TYPE (expression)));
@@ -12045,8 +12052,9 @@ dependent_template_p (tree tmpl)
   if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
       || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
     return true;
-  /* So are qualified names that have not been looked up.  */
-  if (TREE_CODE (tmpl) == SCOPE_REF)
+  /* So are names that have not been looked up.  */
+  if (TREE_CODE (tmpl) == SCOPE_REF
+      || TREE_CODE (tmpl) == IDENTIFIER_NODE)
     return true;
   /* So are member templates of dependent classes.  */
   if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
@@ -12078,8 +12086,7 @@ resolve_typename_type (tree type, bool only_current_p)
   int quals;
   bool pop_p;
 
-  my_friendly_assert (TREE_CODE (type) == TYPENAME_TYPE,
-                     20010702);
+  gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
 
   scope = TYPE_CONTEXT (type);
   name = TYPE_IDENTIFIER (type);
@@ -12182,19 +12189,19 @@ build_non_dependent_expr (tree expr)
     return expr;
 
   if (TREE_CODE (expr) == COND_EXPR)
-    return build (COND_EXPR,
-                 TREE_TYPE (expr),
-                 TREE_OPERAND (expr, 0),
-                 (TREE_OPERAND (expr, 1) 
-                  ? build_non_dependent_expr (TREE_OPERAND (expr, 1))
-                  : build_non_dependent_expr (TREE_OPERAND (expr, 0))),
-                 build_non_dependent_expr (TREE_OPERAND (expr, 2)));
+    return build3 (COND_EXPR,
+                  TREE_TYPE (expr),
+                  TREE_OPERAND (expr, 0),
+                  (TREE_OPERAND (expr, 1) 
+                   ? build_non_dependent_expr (TREE_OPERAND (expr, 1))
+                   : build_non_dependent_expr (TREE_OPERAND (expr, 0))),
+                  build_non_dependent_expr (TREE_OPERAND (expr, 2)));
   if (TREE_CODE (expr) == COMPOUND_EXPR
       && !COMPOUND_EXPR_OVERLOADED (expr))
-    return build (COMPOUND_EXPR,
-                 TREE_TYPE (expr),
-                 TREE_OPERAND (expr, 0),
-                 build_non_dependent_expr (TREE_OPERAND (expr, 1)));
+    return build2 (COMPOUND_EXPR,
+                  TREE_TYPE (expr),
+                  TREE_OPERAND (expr, 0),
+                  build_non_dependent_expr (TREE_OPERAND (expr, 1)));
       
   /* Otherwise, build a NON_DEPENDENT_EXPR.