OSDN Git Service

PR c++/24277
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index 8a8e1fc..a5a7c1e 100644 (file)
@@ -18,8 +18,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /* Known bugs or deficiencies include:
 
@@ -350,7 +350,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
   TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
 
   begin_scope (TREE_VEC_LENGTH (parms) ? sk_template_parms : sk_template_spec,
-               NULL);
+              NULL);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
       tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
@@ -542,7 +542,7 @@ begin_template_parm_list (void)
      e.g.:
 
        template <class T> struct S1 {
-         template <class T> struct S2 {};
+        template <class T> struct S2 {};
        };
 
      pushtag contains special code to call pushdecl_with_scope on the
@@ -642,7 +642,7 @@ end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
-/* A explicit specialization or partial specialization TMPL is being
+/* An 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.  */
@@ -667,11 +667,28 @@ check_specialization_namespace (tree tmpl)
   else
     {
       pedwarn ("specialization of %qD in different namespace", tmpl);
-      cp_pedwarn_at ("  from definition of %q#D", tmpl);
+      pedwarn ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
 
+/* SPEC is an explicit instantiation.  Check that it is valid to
+   perform this explicit instantiation in the current namespace.  */
+
+static void
+check_explicit_instantiation_namespace (tree spec)
+{
+  tree ns;
+
+  /* DR 275: An explicit instantiation shall appear in an enclosing
+     namespace of its template.  */ 
+  ns = decl_namespace_context (spec);
+  if (!is_ancestor (current_namespace, ns))
+    pedwarn ("explicit instantiation of %qD in namespace %qD "
+            "(which does not enclose namespace %qD)",
+            spec, current_namespace, ns);
+}
+
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
@@ -736,8 +753,8 @@ maybe_process_partial_specialization (tree type)
              != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
            {
              pedwarn ("specializing %q#T in different namespace", type);
-             cp_pedwarn_at ("  from definition of %q#D",
-                            CLASSTYPE_TI_TEMPLATE (type));
+             pedwarn ("  from definition of %q+#D",
+                      CLASSTYPE_TI_TEMPLATE (type));
            }
 
          /* Check for invalid specialization after instantiation:
@@ -1114,11 +1131,12 @@ is_specialization_of_friend (tree decl, tree friend)
 }
 
 /* Register the specialization SPEC as a specialization of TMPL with
-   the indicated ARGS.  Returns SPEC, or an equivalent prior
-   declaration, if available.  */
+   the indicated ARGS.  IS_FRIEND indicates whether the specialization
+   is actually just a friend declaration.  Returns SPEC, or an
+   equivalent prior declaration, if available.  */
 
 static tree
-register_specialization (tree spec, tree tmpl, tree args)
+register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
 {
   tree fn;
 
@@ -1133,17 +1151,12 @@ register_specialization (tree spec, tree tmpl, tree args)
        with default function arguments.  In particular, given
        something like this:
 
-          template <class T> void f(T t1, T t = T())
+         template <class T> void f(T t1, T t = T())
 
        the default argument expression is not substituted for in an
        instantiation unless and until it is actually needed.  */
     return spec;
 
-  /* There should be as many levels of arguments as there are
-     levels of parameters.  */
-  gcc_assert (TMPL_ARGS_DEPTH (args)
-             == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)));
-
   fn = retrieve_specialization (tmpl, args,
                                /*class_specializations_p=*/false);
   /* We can sometimes try to re-register a specialization that we've
@@ -1190,14 +1203,15 @@ register_specialization (tree spec, tree tmpl, tree args)
                 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);
+             duplicate_decls (spec, fn, is_friend);
+             check_specialization_namespace (fn);
 
              return fn;
            }
        }
       else if (DECL_TEMPLATE_SPECIALIZATION (fn))
        {
-         if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
+         if (!duplicate_decls (spec, fn, is_friend) && DECL_INITIAL (spec))
            /* Dup decl failed, but this is a new definition. Set the
               line number so any errors match this new
               definition.  */
@@ -1289,7 +1303,7 @@ print_candidates (tree fns)
       tree f;
 
       for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f))
-       cp_error_at ("%s %+#D", str, OVL_CURRENT (f));
+       error ("%s %+#D", str, OVL_CURRENT (f));
       str = "               ";
     }
 }
@@ -1315,8 +1329,8 @@ print_candidates (tree fns)
 
 static tree
 determine_specialization (tree template_id,
-                          tree decl,
-                          tree* targs_out,
+                         tree decl,
+                         tree* targs_out,
                          int need_member_template,
                          int template_count)
 {
@@ -1518,7 +1532,7 @@ determine_specialization (tree template_id,
           the function template to which a function template
           specialization refers:
 
-           -- when an explicit specialization refers to a function
+          -- when an explicit specialization refers to a function
              template.
 
         So, we do use the partial ordering rules, at least for now.
@@ -1538,17 +1552,16 @@ determine_specialization (tree template_id,
 
   if (templates == NULL_TREE && candidates == NULL_TREE)
     {
-      cp_error_at ("template-id %qD for %q+D does not match any template "
-                   "declaration",
-                  template_id, decl);
+      error ("template-id %qD for %q+D does not match any template "
+            "declaration", template_id, decl);
       return error_mark_node;
     }
   else if ((templates && TREE_CHAIN (templates))
           || (candidates && TREE_CHAIN (candidates))
           || (templates && candidates))
     {
-      cp_error_at ("ambiguous template specialization %qD for %q+D",
-                  template_id, decl);
+      error ("ambiguous template specialization %qD for %q+D",
+            template_id, decl);
       chainon (candidates, templates);
       print_candidates (candidates);
       return error_mark_node;
@@ -1644,16 +1657,16 @@ copy_default_args_to_explicit_spec (tree decl)
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
     {
       /* Remove the this pointer, but remember the object's type for
-         CV quals.  */
+        CV quals.  */
       object_type = TREE_TYPE (TREE_VALUE (spec_types));
       spec_types = TREE_CHAIN (spec_types);
       tmpl_types = TREE_CHAIN (tmpl_types);
 
       if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-        {
-          /* DECL may contain more parameters than TMPL due to the extra
-             in-charge parameter in constructors and destructors.  */
-          in_charge = spec_types;
+       {
+         /* DECL may contain more parameters than TMPL due to the extra
+            in-charge parameter in constructors and destructors.  */
+         in_charge = spec_types;
          spec_types = TREE_CHAIN (spec_types);
        }
       if (DECL_HAS_VTT_PARM_P (decl))
@@ -1671,15 +1684,15 @@ copy_default_args_to_explicit_spec (tree decl)
   if (object_type)
     {
       if (vtt)
-        new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
-                                        TREE_VALUE (vtt),
-                                        new_spec_types);
+       new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
+                                        TREE_VALUE (vtt),
+                                        new_spec_types);
 
       if (in_charge)
-        /* Put the in-charge parameter back.  */
-        new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
-                                        TREE_VALUE (in_charge),
-                                        new_spec_types);
+       /* Put the in-charge parameter back.  */
+       new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
+                                        TREE_VALUE (in_charge),
+                                        new_spec_types);
 
       new_type = build_method_type_directly (object_type,
                                             TREE_TYPE (old_type),
@@ -1734,9 +1747,9 @@ copy_default_args_to_explicit_spec (tree decl)
 
 tree
 check_explicit_specialization (tree declarator,
-                               tree decl,
-                               int template_count,
-                               int flags)
+                              tree decl,
+                              int template_count,
+                              int flags)
 {
   int have_def = flags & 2;
   int is_friend = flags & 4;
@@ -1779,7 +1792,7 @@ check_explicit_specialization (tree declarator,
                 template <class T> void f<int>(); */
 
              error ("template-id %qD in declaration of primary template",
-                     declarator);
+                    declarator);
              return decl;
            }
        }
@@ -1805,7 +1818,7 @@ check_explicit_specialization (tree declarator,
     case tsk_excessive_parms:
     case tsk_insufficient_parms:
       if (tsk == tsk_excessive_parms)
-        error ("too many template parameter lists in declaration of %qD",
+       error ("too many template parameter lists in declaration of %qD",
               decl);
       else if (template_header_count)
        error("too few template parameter lists in declaration of %qD", decl);
@@ -1833,7 +1846,7 @@ check_explicit_specialization (tree declarator,
                   "is not allowed", declarator);
          else
            error ("template-id %qD in declaration of primary template",
-                   declarator);
+                  declarator);
          return decl;
        }
 
@@ -1843,7 +1856,7 @@ check_explicit_specialization (tree declarator,
 
             template <class T> struct S {
               template <class U> void f (U);
-             };
+            };
             template <> template <class U> void S<int>::f(U) {}
 
           That's a specialization -- but of the entire template.  */
@@ -1884,11 +1897,11 @@ check_explicit_specialization (tree declarator,
          else
            {
              /* If there is no class context, the explicit instantiation
-                 must be at namespace scope.  */
+                must be at namespace scope.  */
              gcc_assert (DECL_NAMESPACE_SCOPE_P (decl));
 
              /* Find the namespace binding, using the declaration
-                 context.  */
+                context.  */
              fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
              if (!fns || !is_overloaded_fn (fns))
                {
@@ -1915,7 +1928,7 @@ check_explicit_specialization (tree declarator,
              /* It's not valid to write an explicit instantiation in
                 class scope, e.g.:
 
-                  class C { template void f(); }
+                  class C { template void f(); }
 
                   This case is caught by the parser.  However, on
                   something like:
@@ -2092,6 +2105,26 @@ check_explicit_specialization (tree declarator,
             template it specializes.  */
          TREE_PRIVATE (decl) = TREE_PRIVATE (gen_tmpl);
          TREE_PROTECTED (decl) = TREE_PROTECTED (gen_tmpl);
+         /* The specialization has the same visibility as the
+            template it specializes.  */
+         if (DECL_VISIBILITY_SPECIFIED (gen_tmpl))
+           {
+             DECL_VISIBILITY_SPECIFIED (decl) = 1;
+             DECL_VISIBILITY (decl) = DECL_VISIBILITY (gen_tmpl);
+           }
+         /* If DECL is a friend declaration, declared using an
+            unqualified name, the namespace associated with DECL may
+            have been set incorrectly.  For example, in:
+            
+              template <typename T> void f(T); 
+               namespace N {
+                struct S { friend void f<int>(int); }
+               }
+
+             we will have set the DECL_CONTEXT for the friend
+             declaration to N, rather than to the global namespace.  */
+         if (DECL_NAMESPACE_SCOPE_P (decl))
+           DECL_CONTEXT (decl) = DECL_CONTEXT (tmpl);
 
          if (is_friend && !have_def)
            /* This is not really a declaration of a specialization.
@@ -2106,7 +2139,7 @@ check_explicit_specialization (tree declarator,
 
          /* Register this specialization so that we can find it
             again.  */
-         decl = register_specialization (decl, gen_tmpl, targs);
+         decl = register_specialization (decl, gen_tmpl, targs, is_friend);
        }
     }
 
@@ -2202,8 +2235,8 @@ check_template_shadow (tree decl)
       || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
     return;
 
-  cp_error_at ("declaration of %q#D", decl);
-  cp_error_at (" shadows template parm %q#D", olddecl);
+  error ("declaration of %q+#D", decl);
+  error (" shadows template parm %q+#D", olddecl);
 }
 
 /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
@@ -2211,10 +2244,10 @@ check_template_shadow (tree decl)
 
 static tree
 build_template_parm_index (int index,
-                           int level,
-                           int orig_level,
-                           tree decl,
-                           tree type)
+                          int level,
+                          int orig_level,
+                          tree decl,
+                          tree type)
 {
   tree t = make_node (TEMPLATE_PARM_INDEX);
   TEMPLATE_PARM_IDX (t) = index;
@@ -2257,9 +2290,10 @@ reduce_template_parm_level (tree index, tree type, int levels)
                                     decl, type);
       TEMPLATE_PARM_DESCENDANTS (index) = t;
 
-      /* Template template parameters need this.  */
-      DECL_TEMPLATE_PARMS (decl)
-       = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
+       /* Template template parameters need this.  */
+      if (TREE_CODE (decl) != CONST_DECL)
+       DECL_TEMPLATE_PARMS (decl)
+         = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
     }
 
   return TEMPLATE_PARM_DESCENDANTS (index);
@@ -2311,7 +2345,7 @@ process_template_parm (tree list, tree next, bool is_non_type)
       TREE_INVARIANT (parm) = 1;
       TREE_READONLY (parm) = 1;
       if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-        TREE_TYPE (parm) = void_type_node;
+       TREE_TYPE (parm) = void_type_node;
       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
       TREE_CONSTANT (decl) = 1;
       TREE_INVARIANT (decl) = 1;
@@ -2690,9 +2724,9 @@ process_partial_specialization (tree decl)
                        && tpd.arg_uses_template_parms [j])
                      {
                        error ("type %qT of template argument %qE depends "
-                               "on template parameter(s)",
-                               type,
-                               arg);
+                              "on template parameter(s)",
+                              type,
+                              arg);
                        break;
                      }
                }
@@ -2787,7 +2821,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
   if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary)
     /* For an ordinary class template, default template arguments are
        allowed at the innermost level, e.g.:
-         template <class T = int>
+        template <class T = int>
         struct S {};
        but, in a partial specialization, they're not allowed even
        there, as we have in [temp.class.spec]:
@@ -2817,8 +2851,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
        examine the parameters to the class itself.  On the one
        hand, they will be checked when the class is defined, and,
        on the other, default arguments are valid in things like:
-         template <class T = double>
-         struct S { template <class U> void f(U); };
+        template <class T = double>
+        struct S { template <class U> void f(U); };
        Here the default argument for `S' has no bearing on the
        declaration of `f'.  */
     last_level_to_check = template_class_depth (current_class_type) + 1;
@@ -2879,10 +2913,10 @@ template_parm_this_level_p (tree t, void* data)
    previously existing one, if appropriate.  Returns the DECL, or an
    equivalent one, if it is replaced via a call to duplicate_decls.
 
-   If IS_FRIEND is nonzero, DECL is a friend declaration.  */
+   If IS_FRIEND is true, DECL is a friend declaration.  */
 
 tree
-push_template_decl_real (tree decl, int is_friend)
+push_template_decl_real (tree decl, bool is_friend)
 {
   tree tmpl;
   tree args;
@@ -2903,7 +2937,8 @@ push_template_decl_real (tree decl, int is_friend)
                && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE
                && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)));
 
-  is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl));
+  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl))
+    is_friend = true;
 
   if (is_friend)
     /* For a friend, we want the context of the friend function, not
@@ -2943,7 +2978,7 @@ push_template_decl_real (tree decl, int is_friend)
            {
              /* [temp.mem]
 
-                A destructor shall not be a member template.  */
+                A destructor shall not be a member template.  */
              error ("destructor %qD declared as member template", decl);
              return error_mark_node;
            }
@@ -2956,7 +2991,7 @@ push_template_decl_real (tree decl, int is_friend)
            {
              /* [basic.stc.dynamic.allocation]
 
-                An allocation function can be a function
+                An allocation function can be a function
                 template. ... Template allocation functions shall
                 have two or more parameters.  */
              error ("invalid template declaration of %qD", decl);
@@ -3078,7 +3113,8 @@ push_template_decl_real (tree decl, int is_friend)
 
          register_specialization (new_tmpl,
                                   most_general_template (tmpl),
-                                  args);
+                                  args,
+                                  is_friend);
          return decl;
        }
 
@@ -3089,7 +3125,7 @@ push_template_decl_real (tree decl, int is_friend)
       if (TMPL_ARGS_DEPTH (args) != i)
        {
          error ("expected %d levels of template parms for %q#D, got %d",
-                 i, decl, TMPL_ARGS_DEPTH (args));
+                i, decl, TMPL_ARGS_DEPTH (args));
        }
       else
        for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
@@ -3101,15 +3137,16 @@ push_template_decl_real (tree decl, int is_friend)
              {
                if (current == decl)
                  error ("got %d template parameters for %q#D",
-                         TREE_VEC_LENGTH (a), decl);
+                        TREE_VEC_LENGTH (a), decl);
                else
                  error ("got %d template parameters for %q#T",
-                         TREE_VEC_LENGTH (a), current);
+                        TREE_VEC_LENGTH (a), current);
                error ("  but %d required", TREE_VEC_LENGTH (t));
+               return error_mark_node;
              }
 
            /* Perhaps we should also check that the parms are used in the
-               appropriate qualifying scopes in the declarator?  */
+              appropriate qualifying scopes in the declarator?  */
 
            if (current == decl)
              current = ctx;
@@ -3128,7 +3165,7 @@ push_template_decl_real (tree decl, int is_friend)
   if (new_template_p && !ctx
       && !(is_friend && template_class_depth (current_class_type) > 0))
     {
-      tmpl = pushdecl_namespace_level (tmpl);
+      tmpl = pushdecl_namespace_level (tmpl, is_friend);
       if (tmpl == error_mark_node)
        return error_mark_node;
 
@@ -3183,7 +3220,7 @@ push_template_decl_real (tree decl, int is_friend)
 tree
 push_template_decl (tree decl)
 {
-  return push_template_decl_real (decl, 0);
+  return push_template_decl_real (decl, false);
 }
 
 /* Called when a class template TYPE is redeclared with the indicated
@@ -3224,7 +3261,7 @@ redeclare_class_template (tree type, tree parms)
 
   if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
     {
-      cp_error_at ("previous declaration %qD", tmpl);
+      error ("previous declaration %q+D", tmpl);
       error ("used %d template parameter(s) instead of %d",
             TREE_VEC_LENGTH (tmpl_parms),
             TREE_VEC_LENGTH (parms));
@@ -3244,7 +3281,7 @@ redeclare_class_template (tree type, tree parms)
          || (TREE_CODE (tmpl_parm) != TYPE_DECL
              && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
        {
-         cp_error_at ("template parameter %q#D", tmpl_parm);
+         error ("template parameter %q+#D", tmpl_parm);
          error ("redeclared here as %q#D", parm);
          return;
        }
@@ -3546,7 +3583,7 @@ convert_nontype_argument (tree type, tree expr)
       if (!real_lvalue_p (expr))
        {
          error ("%qE is not a valid template argument for type %qT "
-                "because it is not a lvalue", expr, type);
+                "because it is not a lvalue", expr, type);
          return NULL_TREE;
        }
 
@@ -3576,9 +3613,7 @@ convert_nontype_argument (tree type, tree expr)
   else if (TYPE_PTRFN_P (type))
     {
       /* If the argument is a template-id, we might not have enough
-         context information to decay the pointer.
-        ??? Why static5.C requires decay and subst1.C works fine
-        even without it?  */
+        context information to decay the pointer.  */
       if (!type_unknown_p (expr_type))
        {
          expr = decay_conversion (expr);
@@ -3684,10 +3719,10 @@ convert_nontype_argument (tree type, tree expr)
 
 static int
 coerce_template_template_parms (tree parm_parms,
-                                tree arg_parms,
-                                tsubst_flags_t complain,
+                               tree arg_parms,
+                               tsubst_flags_t complain,
                                tree in_decl,
-                                tree outer_args)
+                               tree outer_args)
 {
   int nparms, nargs, i;
   tree parm, arg;
@@ -3710,11 +3745,11 @@ coerce_template_template_parms (tree parm_parms,
       arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
 
       if (arg == NULL_TREE || arg == error_mark_node
-          || parm == NULL_TREE || parm == error_mark_node)
+         || parm == NULL_TREE || parm == error_mark_node)
        return 0;
 
       if (TREE_CODE (arg) != TREE_CODE (parm))
-        return 0;
+       return 0;
 
       switch (TREE_CODE (parm))
        {
@@ -3766,11 +3801,11 @@ coerce_template_template_parms (tree parm_parms,
 
 static tree
 convert_template_argument (tree parm,
-                           tree arg,
-                           tree args,
-                           tsubst_flags_t complain,
-                           int i,
-                           tree in_decl)
+                          tree arg,
+                          tree args,
+                          tsubst_flags_t complain,
+                          int i,
+                          tree in_decl)
 {
   tree val;
   tree inner_args;
@@ -3810,7 +3845,7 @@ convert_template_argument (tree parm,
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
       pedwarn ("to refer to a type member of a template parameter, "
-               "use %<typename %E%>", arg);
+              "use %<typename %E%>", arg);
 
       arg = make_typename_type (TREE_OPERAND (arg, 0),
                                TREE_OPERAND (arg, 1),
@@ -3825,12 +3860,12 @@ convert_template_argument (tree parm,
          if (complain & tf_error)
            {
              error ("type/value mismatch at argument %d in template "
-                     "parameter list for %qD",
-                     i + 1, in_decl);
+                    "parameter list for %qD",
+                    i + 1, in_decl);
              if (is_type)
                error ("  expected a constant of type %qT, got %qT",
-                       TREE_TYPE (parm),
-                       (is_tmpl_type ? DECL_NAME (arg) : arg));
+                      TREE_TYPE (parm),
+                      (is_tmpl_type ? DECL_NAME (arg) : arg));
              else if (requires_tmpl_type)
                error ("  expected a class template, got %qE", arg);
              else
@@ -3844,8 +3879,8 @@ convert_template_argument (tree parm,
       if (in_decl && (complain & tf_error))
        {
          error ("type/value mismatch at argument %d in template "
-                 "parameter list for %qD",
-                 i + 1, in_decl);
+                "parameter list for %qD",
+                i + 1, in_decl);
          if (is_tmpl_type)
            error ("  expected a type, got %qT", DECL_NAME (arg));
          else
@@ -3884,10 +3919,10 @@ convert_template_argument (tree parm,
                  if (in_decl && (complain & tf_error))
                    {
                      error ("type/value mismatch at argument %d in "
-                             "template parameter list for %qD",
-                             i + 1, in_decl);
+                            "template parameter list for %qD",
+                            i + 1, in_decl);
                      error ("  expected a template of type %qD, got %qD",
-                             parm, arg);
+                            parm, arg);
                    }
 
                  val = error_mark_node;
@@ -3902,7 +3937,7 @@ convert_template_argument (tree parm,
       tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
 
       if (invalid_nontype_parm_type_p (t, complain))
-        return error_mark_node;
+       return error_mark_node;
 
       if (!uses_template_parms (arg) && !uses_template_parms (t))
        /* We used to call digest_init here.  However, digest_init
@@ -3940,8 +3975,8 @@ convert_template_argument (tree parm,
 
 static tree
 coerce_template_parms (tree parms,
-                       tree args,
-                       tree in_decl,
+                      tree args,
+                      tree in_decl,
                       tsubst_flags_t complain,
                       int require_all_arguments)
 {
@@ -3962,10 +3997,10 @@ coerce_template_parms (tree parms,
       if (complain & tf_error)
        {
          error ("wrong number of template arguments (%d, should be %d)",
-                 nargs, nparms);
+                nargs, nparms);
 
          if (in_decl)
-           cp_error_at ("provided for %qD", in_decl);
+           error ("provided for %q+D", in_decl);
        }
 
       return error_mark_node;
@@ -4097,12 +4132,12 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
            {
              /* Already substituted with real template.  Just output
                 the template name here */
-              tree context = DECL_CONTEXT (arg);
-              if (context)
-                {
-                  /* The template may be defined in a namespace, or
-                     may be a member template.  */
-                  gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
+             tree context = DECL_CONTEXT (arg);
+             if (context)
+               {
+                 /* The template may be defined in a namespace, or
+                    may be a member template.  */
+                 gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
                              || CLASS_TYPE_P (context));
                  cat (decl_as_string (DECL_CONTEXT (arg),
                                      TFF_PLAIN_IDENTIFIER));
@@ -4277,11 +4312,11 @@ maybe_get_template_decl_from_type_decl (tree decl)
 
 tree
 lookup_template_class (tree d1,
-                       tree arglist,
-                       tree in_decl,
-                       tree context,
-                       int entering_scope,
-                       tsubst_flags_t complain)
+                      tree arglist,
+                      tree in_decl,
+                      tree context,
+                      int entering_scope,
+                      tsubst_flags_t complain)
 {
   tree template = NULL_TREE, parmlist;
   tree t;
@@ -4338,21 +4373,21 @@ lookup_template_class (tree d1,
   if (! template)
     {
       if (complain & tf_error)
-        error ("%qT is not a template", d1);
+       error ("%qT is not a template", d1);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
     }
 
   if (TREE_CODE (template) != TEMPLATE_DECL
-         /* Make sure it's a user visible template, if it was named by
+        /* Make sure it's a user visible template, if it was named by
            the user.  */
       || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
          && !PRIMARY_TEMPLATE_P (template)))
     {
       if (complain & tf_error)
-        {
-          error ("non-template type %qT used as a template", d1);
-          if (in_decl)
-           cp_error_at ("for template declaration %qD", in_decl);
+       {
+         error ("non-template type %qT used as a template", d1);
+         if (in_decl)
+           error ("for template declaration %q+D", in_decl);
        }
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
     }
@@ -4362,7 +4397,7 @@ lookup_template_class (tree d1,
   if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
     {
       /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
-         template arguments */
+        template arguments */
 
       tree parm;
       tree arglist2;
@@ -4389,11 +4424,11 @@ lookup_template_class (tree d1,
        arglist = add_to_template_args (current_template_args (), arglist);
 
       arglist2 = coerce_template_parms (parmlist, arglist, template,
-                                        complain, /*require_all_args=*/1);
+                                       complain, /*require_all_args=*/1);
       if (arglist2 == error_mark_node
          || (!uses_template_parms (arglist2)
              && check_instantiated_args (template, arglist2, complain)))
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
 
       parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
@@ -4419,9 +4454,9 @@ lookup_template_class (tree d1,
             For example, given:
 
               template <class T> struct S1 {
-                template <class U> struct S2 {};
+                template <class U> struct S2 {};
                 template <class U> struct S2<U*> {};
-               };
+               };
 
             we will be called with an ARGLIST of `U*', but the
             TEMPLATE will be `template <class T> template
@@ -4458,7 +4493,7 @@ lookup_template_class (tree d1,
            {
              tree a = coerce_template_parms (TREE_VALUE (t),
                                              arglist, template,
-                                             complain, /*require_all_args=*/1);
+                                             complain, /*require_all_args=*/1);
 
              /* Don't process further if one of the levels fails.  */
              if (a == error_mark_node)
@@ -4487,7 +4522,7 @@ lookup_template_class (tree d1,
          = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
                                   INNERMOST_TEMPLATE_ARGS (arglist),
                                   template,
-                                  complain, /*require_all_args=*/1);
+                                  complain, /*require_all_args=*/1);
 
       if (arglist == error_mark_node)
        /* We were unable to bind the arguments.  */
@@ -4525,7 +4560,7 @@ lookup_template_class (tree d1,
            }
        }
       if (found)
-        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
+       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
 
       /* If we already have this specialization, return it.  */
       found = retrieve_specialization (template, arglist,
@@ -4611,6 +4646,11 @@ lookup_template_class (tree d1,
        = TREE_PROTECTED (TYPE_STUB_DECL (template_type));
       DECL_IN_SYSTEM_HEADER (type_decl)
        = DECL_IN_SYSTEM_HEADER (template);
+      if (CLASSTYPE_VISIBILITY_SPECIFIED (template_type))
+       {
+         DECL_VISIBILITY_SPECIFIED (type_decl) = 1;
+         DECL_VISIBILITY (type_decl) = CLASSTYPE_VISIBILITY (template_type);
+       }
 
       /* Set up the template information.  We have to figure out which
         template is the immediate parent if this is a full
@@ -4660,18 +4700,18 @@ lookup_template_class (tree d1,
          if (!found)
            {
              /* There was no partial instantiation. This happens
-                 where C<T> is a member template of A<T> and it's used
-                 in something like
+                where C<T> is a member template of A<T> and it's used
+                in something like
 
-                  template <typename T> struct B { A<T>::C<int> m; };
-                  B<float>;
+                 template <typename T> struct B { A<T>::C<int> m; };
+                 B<float>;
 
-                 Create the partial instantiation.
-               */
-              TREE_VEC_LENGTH (arglist)--;
-              found = tsubst (template, arglist, complain, NULL_TREE);
-              TREE_VEC_LENGTH (arglist)++;
-            }
+                Create the partial instantiation.
+              */
+             TREE_VEC_LENGTH (arglist)--;
+             found = tsubst (template, arglist, complain, NULL_TREE);
+             TREE_VEC_LENGTH (arglist)++;
+           }
        }
 
       SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
@@ -4947,6 +4987,7 @@ uses_template_parms (tree t)
           || TREE_CODE (t) == TEMPLATE_PARM_INDEX
           || TREE_CODE (t) == OVERLOAD
           || TREE_CODE (t) == BASELINK
+          || TREE_CODE (t) == IDENTIFIER_NODE
           || CONSTANT_CLASS_P (t))
     dependent_p = (type_dependent_expression_p (t)
                   || value_dependent_expression_p (t));
@@ -4989,13 +5030,13 @@ push_tinst_level (tree d)
     {
       /* If the instantiation in question still has unbound template parms,
         we don't really care if we can't instantiate it, so just return.
-         This happens with base instantiation for implicit `typename'.  */
+        This happens with base instantiation for implicit `typename'.  */
       if (uses_template_parms (d))
        return 0;
 
       last_template_error_tick = tinst_level_tick;
       error ("template instantiation depth exceeds maximum of %d (use "
-             "-ftemplate-depth-NN to increase the maximum) instantiating %qD",
+            "-ftemplate-depth-NN to increase the maximum) instantiating %qD",
             max_tinst_depth, d);
 
       print_instantiation_context ();
@@ -5082,14 +5123,14 @@ tsubst_friend_function (tree decl, tree args)
       tree ns = decl_namespace_context (TYPE_MAIN_DECL (current_class_type));
 
       /* Friend functions are looked up in the containing namespace scope.
-         We must enter that scope, to avoid finding member functions of the
-         current cless with same name.  */
+        We must enter that scope, to avoid finding member functions of the
+        current cless with same name.  */
       push_nested_namespace (ns);
       fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
-                         tf_error | tf_warning, NULL_TREE);
+                        tf_error | tf_warning, NULL_TREE);
       pop_nested_namespace (ns);
       arglist = tsubst (DECL_TI_ARGS (decl), args,
-                        tf_error | tf_warning, NULL_TREE);
+                       tf_error | tf_warning, NULL_TREE);
       template_id = lookup_template_function (fns, arglist);
 
       new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE);
@@ -5165,7 +5206,7 @@ tsubst_friend_function (tree decl, tree args)
         into the namespace of the template.  */
       ns = decl_namespace_context (new_friend);
       push_nested_namespace (ns);
-      old_decl = pushdecl_namespace_level (new_friend);
+      old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
       pop_nested_namespace (ns);
 
       if (old_decl != new_friend)
@@ -5198,8 +5239,8 @@ tsubst_friend_function (tree decl, tree args)
 
               friend void f(int);
               template <class T> class C {
-                friend void f(T) {}
-               };
+                friend void f(T) {}
+              };
 
             when `C<int>' is instantiated.  Now, `f(int)' is defined
             in the class.  */
@@ -5367,7 +5408,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
       tmpl = tsubst (friend_tmpl, args, tf_error | tf_warning, NULL_TREE);
 
       /* The new TMPL is not an instantiation of anything, so we
-        forget its origins.  We don't reset CLASSTYPE_TI_TEMPLATE for
+        forget its origins.  We don't reset CLASSTYPE_TI_TEMPLATE for
         the new type because that is supposed to be the corresponding
         template decl, i.e., TMPL.  */
       DECL_USE_TEMPLATE (tmpl) = 0;
@@ -5377,7 +5418,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
        = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)));
 
       /* Inject this template into the global scope.  */
-      friend_type = TREE_TYPE (pushdecl_top_level (tmpl));
+      friend_type = TREE_TYPE (pushdecl_top_level_maybe_friend (tmpl, true));
     }
 
   if (context)
@@ -5446,7 +5487,7 @@ instantiate_class_template (tree type)
        {
          if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args))
            {
-             cp_error_at ("%s %+#T", str, TREE_TYPE (t));
+             error ("%s %+#T", str, TREE_TYPE (t));
              str = "               ";
            }
        }
@@ -5530,6 +5571,11 @@ instantiate_class_template (tree type)
   TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
   if (ANON_AGGR_TYPE_P (pattern))
     SET_ANON_AGGR_TYPE_P (type);
+  if (CLASSTYPE_VISIBILITY_SPECIFIED (pattern))
+    {
+      CLASSTYPE_VISIBILITY_SPECIFIED (type) = 1;
+      CLASSTYPE_VISIBILITY (type) = CLASSTYPE_VISIBILITY (pattern);
+    }
 
   pbinfo = TYPE_BINFO (pattern);
 
@@ -5684,17 +5730,22 @@ instantiate_class_template (tree type)
                    --processing_template_decl;
                  if (TREE_CODE (r) == VAR_DECL)
                    {
-                     tree init;
-
-                     if (DECL_INITIALIZED_IN_CLASS_P (r))
-                       init = tsubst_expr (DECL_INITIAL (t), args,
-                                           tf_error | tf_warning, NULL_TREE);
-                     else
-                       init = NULL_TREE;
-
-                     finish_static_data_member_decl
-                       (r, init, /*asmspec_tree=*/NULL_TREE, /*flags=*/0);
-
+                     /* In [temp.inst]:
+
+                          [t]he initialization (and any associated
+                          side-effects) of a static data member does
+                          not occur unless the static data member is
+                          itself used in a way that requires the
+                          definition of the static data member to
+                          exist.  
+
+                        Therefore, we do not substitute into the
+                        initialized for the static data member here.  */
+                     finish_static_data_member_decl 
+                       (r, 
+                        /*init=*/NULL_TREE, 
+                        /*asmspec_tree=*/NULL_TREE, 
+                        /*flags=*/0);
                      if (DECL_INITIALIZED_IN_CLASS_P (r))
                        check_static_variable_definition (r, TREE_TYPE (r));
                    }
@@ -5711,7 +5762,7 @@ instantiate_class_template (tree type)
                      if (!COMPLETE_TYPE_P (rtype))
                        {
                          cxx_incomplete_type_error (r, rtype);
-                         r = error_mark_node;
+                         r = error_mark_node;
                        }
                    }
 
@@ -5726,7 +5777,7 @@ instantiate_class_template (tree type)
                      set_current_access_from_decl (r);
                      finish_member_declaration (r);
                    }
-               }
+               }
            }
        }
       else
@@ -5742,7 +5793,7 @@ instantiate_class_template (tree type)
                {
                  /* template <class T> friend class C;  */
                  friend_type = tsubst_friend_class (friend_type, args);
-                 adjust_processing_template_decl = true;
+                 adjust_processing_template_decl = true;
                }
              else if (TREE_CODE (friend_type) == UNBOUND_CLASS_TEMPLATE)
                {
@@ -5751,7 +5802,7 @@ instantiate_class_template (tree type)
                                        tf_error | tf_warning, NULL_TREE);
                  if (TREE_CODE (friend_type) == TEMPLATE_DECL)
                    friend_type = TREE_TYPE (friend_type);
-                 adjust_processing_template_decl = true;
+                 adjust_processing_template_decl = true;
                }
              else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
                {
@@ -5803,7 +5854,7 @@ instantiate_class_template (tree type)
 
                   friend class C<int>;
 
-                We don't have to do anything in these cases.  */
+                We don't have to do anything in these cases.  */
 
              if (adjust_processing_template_decl)
                /* Trick make_friend_class into realizing that the friend
@@ -5814,7 +5865,7 @@ instantiate_class_template (tree type)
                ++processing_template_decl;
 
              if (friend_type != error_mark_node)
-               make_friend_class (type, friend_type, /*complain=*/false);
+               make_friend_class (type, friend_type, /*complain=*/false);
 
              if (adjust_processing_template_decl)
                --processing_template_decl;
@@ -5896,32 +5947,7 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   else
     {
       r = tsubst_expr (t, args, complain, in_decl);
-
-      if (!uses_template_parms (r))
-       {
-         /* Sometimes, one of the args was an expression involving a
-            template constant parameter, like N - 1.  Now that we've
-            tsubst'd, we might have something like 2 - 1.  This will
-            confuse lookup_template_class, so we do constant folding
-            here.  We have to unset processing_template_decl, to fool
-            tsubst_copy_and_build() into building an actual tree.  */
-
-        /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
-           as simple as it's going to get, and trying to reprocess
-           the trees will break.  Once tsubst_expr et al DTRT for
-           non-dependent exprs, this code can go away, as the type
-           will always be set.  */
-         if (!TREE_TYPE (r))
-           {
-             int saved_processing_template_decl = processing_template_decl;
-             processing_template_decl = 0;
-             r = tsubst_copy_and_build (r, /*args=*/NULL_TREE,
-                                        tf_error, /*in_decl=*/NULL_TREE,
-                                        /*function_p=*/false);
-             processing_template_decl = saved_processing_template_decl;
-           }
-         r = fold (r);
-       }
+      r = fold_non_dependent_expr (r);
     }
   return r;
 }
@@ -5992,6 +6018,9 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
          tree parm_decl = TREE_VALUE (tuple);
 
          parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
+         if (TREE_CODE (parm_decl) == PARM_DECL
+             && invalid_nontype_parm_type_p (TREE_TYPE (parm_decl), complain))
+           parm_decl = error_mark_node;
          default_value = tsubst_template_arg (default_value, args,
                                               complain, NULL_TREE);
 
@@ -6016,10 +6045,10 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
 
 static tree
 tsubst_aggr_type (tree t,
-                  tree args,
-                  tsubst_flags_t complain,
-                  tree in_decl,
-                  int entering_scope)
+                 tree args,
+                 tsubst_flags_t complain,
+                 tree in_decl,
+                 int entering_scope)
 {
   if (t == NULL_TREE)
     return NULL_TREE;
@@ -6038,6 +6067,11 @@ tsubst_aggr_type (tree t,
          tree argvec;
          tree context;
          tree r;
+         bool saved_skip_evaluation;
+
+         /* In "sizeof(X<I>)" we need to evaluate "I".  */
+         saved_skip_evaluation = skip_evaluation;
+         skip_evaluation = false;
 
          /* First, determine the context for the type we are looking
             up.  */
@@ -6058,12 +6092,17 @@ tsubst_aggr_type (tree t,
          argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
                                         complain, in_decl);
          if (argvec == error_mark_node)
-           return error_mark_node;
-
-         r = lookup_template_class (t, argvec, in_decl, context,
-                                    entering_scope, complain);
+           r = error_mark_node;
+         else
+           {
+             r = lookup_template_class (t, argvec, in_decl, context,
+                                        entering_scope, complain);
+             r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
+           }
+         
+         skip_evaluation = saved_skip_evaluation;
 
-         return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
+         return r;
        }
       else
        /* This is not a template type, so there's nothing to do.  */
@@ -6096,10 +6135,6 @@ tsubst_default_argument (tree fn, tree type, tree arg)
      we must be careful to do name lookup in the scope of S<T>,
      rather than in the current class.  */
   push_access_scope (fn);
-  /* The default argument expression should not be considered to be
-     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)
     {
@@ -6208,6 +6243,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
        full_args = tsubst_template_args (tmpl_args, args,
                                          complain, in_decl);
+       if (full_args == error_mark_node)
+         return error_mark_node;
 
        /* tsubst_template_args doesn't copy the vector if
           nothing changed.  But, *something* should have
@@ -6277,7 +6314,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        if (TREE_CODE (decl) != TYPE_DECL)
          /* Record this non-type partial instantiation.  */
          register_specialization (r, t,
-                                  DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
+                                  DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)),
+                                  false);
       }
       break;
 
@@ -6332,7 +6370,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               there was a specialization of a member template, like
               this:
 
-                template <class T> struct S { template <class U> void f(); }
+                template <class T> struct S { template <class U> void f(); }
                 template <> template <class U> void S<int>::f(U);
 
               Here, we'll be substituting into the specialization,
@@ -6371,7 +6409,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          {
            /* This special case arises when we have something like this:
 
-                template <class T> struct S {
+                template <class T> struct S {
                   friend void f<int>(int, double);
                 };
 
@@ -6402,9 +6440,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
          return error_mark_node;
 
        /* We do NOT check for matching decls pushed separately at this
-           point, as they may not represent instantiations of this
-           template, and in any case are considered separate under the
-           discrete model.  */
+          point, as they may not represent instantiations of this
+          template, and in any case are considered separate under the
+          discrete model.  */
        r = copy_decl (t);
        DECL_USE_TEMPLATE (r) = 0;
        TREE_TYPE (r) = type;
@@ -6452,14 +6490,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_TEMPLATE_INFO (r)
              = tree_cons (gen_tmpl, argvec, NULL_TREE);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
-           register_specialization (r, gen_tmpl, argvec);
+           register_specialization (r, gen_tmpl, argvec, false);
 
            /* We're not supposed to instantiate default arguments
               until they are called, for a template.  But, for a
               declaration like:
 
-                template <class T> void f ()
-                 { extern void g(int i = T()); }
+                template <class T> void f ()
+                { extern void g(int i = T()); }
 
               we should do the substitution when the template is
               instantiated.  We handle the member function case in
@@ -6470,6 +6508,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                && !uses_template_parms (argvec))
              tsubst_default_arguments (r);
          }
+       else
+         DECL_TEMPLATE_INFO (r) = NULL_TREE;
 
        /* Copy the list of befriending classes.  */
        for (friends = &DECL_BEFRIENDING_CLASSES (r);
@@ -6552,7 +6592,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
                                        complain, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
        if (VOID_TYPE_P (type))
-         cp_error_at ("instantiation of %qD as type %qT", r, type);
+         error ("instantiation of %q+D as type %qT", r, type);
       }
       break;
 
@@ -6637,6 +6677,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        r = copy_decl (t);
        if (TREE_CODE (r) == VAR_DECL)
          {
+           /* Even if the original location is out of scope, the
+              newly substituted one is not.  */
+           DECL_DEAD_FOR_LOCAL (r) = 0;
+           DECL_INITIALIZED_P (r) = 0;
+           DECL_TEMPLATE_INSTANTIATED (r) = 0;
            type = tsubst (TREE_TYPE (t), args, complain, in_decl);
            if (type == error_mark_node)
              return error_mark_node;
@@ -6644,6 +6689,13 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
              = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
            type = check_var_type (DECL_NAME (r), type);
+
+           if (DECL_HAS_VALUE_EXPR_P (t))
+             {
+               tree ve = DECL_VALUE_EXPR (t);
+               ve = tsubst_expr (ve, args, complain, in_decl);
+               SET_DECL_VALUE_EXPR (r, ve);
+             }
          }
        else if (DECL_SELF_REFERENCE_P (t))
          SET_DECL_SELF_REFERENCE_P (r);
@@ -6652,22 +6704,15 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        DECL_CONTEXT (r) = ctx;
        /* Clear out the mangled name and RTL for the instantiation.  */
        SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
-       SET_DECL_RTL (r, NULL_RTX);
-
-       /* Don't try to expand the initializer until someone tries to use
-          this variable; otherwise we run into circular dependencies.  */
+       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
+         SET_DECL_RTL (r, NULL_RTX);
+       /* The initializer must not be expanded until it is required;
+          see [temp.inst].  */
        DECL_INITIAL (r) = NULL_TREE;
-       SET_DECL_RTL (r, NULL_RTX);
+       if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL))
+         SET_DECL_RTL (r, NULL_RTX);
        DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0;
 
-       /* Even if the original location is out of scope, the newly
-          substituted one is not.  */
-       if (TREE_CODE (r) == VAR_DECL)
-         {
-           DECL_DEAD_FOR_LOCAL (r) = 0;
-           DECL_INITIALIZED_P (r) = 0;
-         }
-
        if (!local_p)
          {
            /* A static data member declaration is always marked
@@ -6676,7 +6721,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               processing here.  */
            DECL_EXTERNAL (r) = 1;
 
-           register_specialization (r, gen_tmpl, argvec);
+           register_specialization (r, gen_tmpl, argvec, false);
            DECL_TEMPLATE_INFO (r) = tree_cons (tmpl, argvec, NULL_TREE);
            SET_DECL_IMPLICIT_INSTANTIATION (r);
          }
@@ -6702,9 +6747,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 
 static tree
 tsubst_arg_types (tree arg_types,
-                  tree args,
-                  tsubst_flags_t complain,
-                  tree in_decl)
+                 tree args,
+                 tsubst_flags_t complain,
+                 tree in_decl)
 {
   tree remaining_arg_types;
   tree type;
@@ -6725,11 +6770,11 @@ tsubst_arg_types (tree arg_types,
   if (VOID_TYPE_P (type))
     {
       if (complain & tf_error)
-        {
-          error ("invalid parameter type %qT", type);
-          if (in_decl)
-            cp_error_at ("in declaration %qD", in_decl);
-        }
+       {
+         error ("invalid parameter type %qT", type);
+         if (in_decl)
+           error ("in declaration %q+D", in_decl);
+       }
       return error_mark_node;
     }
 
@@ -6745,9 +6790,9 @@ tsubst_arg_types (tree arg_types,
   if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
     {
       /* We've instantiated a template before its default arguments
-        have been parsed.  This can happen for a nested template
-        class, and is not an error unless we require the default
-        argument in a call of this function.  */
+        have been parsed.  This can happen for a nested template
+        class, and is not an error unless we require the default
+        argument in a call of this function.  */
       result = tree_cons (default_arg, type, remaining_arg_types);
       VEC_safe_push (tree, gc, DEFARG_INSTANTIATIONS (default_arg), result);
     }
@@ -6776,9 +6821,9 @@ tsubst_arg_types (tree arg_types,
 
 static tree
 tsubst_function_type (tree t,
-                      tree args,
-                      tsubst_flags_t complain,
-                      tree in_decl)
+                     tree args,
+                     tsubst_flags_t complain,
+                     tree in_decl)
 {
   tree return_type;
   tree arg_types;
@@ -6881,9 +6926,9 @@ tsubst_exception_specification (tree fntype,
 
 static tree
 tsubst_call_declarator_parms (tree parms,
-                              tree args,
-                              tsubst_flags_t complain,
-                              tree in_decl)
+                             tree args,
+                             tsubst_flags_t complain,
+                             tree in_decl)
 {
   tree new_parms;
   tree type;
@@ -7108,8 +7153,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            if (cp_type_quals (t))
              {
                r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
-               r = cp_build_qualified_type_real
-                 (r, cp_type_quals (t),
+               r = cp_build_qualified_type_real
+                 (r, cp_type_quals (t),
                   complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM
                               ? tf_ignore_bad_quals : 0));
              }
@@ -7232,8 +7277,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                  error ("forming reference to void");
                else
                  error ("forming %s to reference type %qT",
-                         (code == POINTER_TYPE) ? "pointer" : "reference",
-                         type);
+                        (code == POINTER_TYPE) ? "pointer" : "reference",
+                        type);
                last_loc = input_location;
              }
 
@@ -7266,7 +7311,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               reasons:
 
               -- Attempting to create "pointer to member of T" when T
-                 is not a class type.  */
+                 is not a class type.  */
            if (complain & tf_error)
              error ("creating pointer to member of non-class type %qT", r);
            return error_mark_node;
@@ -7286,18 +7331,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        gcc_assert (TREE_CODE (type) != METHOD_TYPE);
        if (TREE_CODE (type) == FUNCTION_TYPE)
          {
-            /* The type of the implicit object parameter gets its
-               cv-qualifiers from the FUNCTION_TYPE. */
+           /* The type of the implicit object parameter gets its
+              cv-qualifiers from the FUNCTION_TYPE. */
            tree method_type;
-            tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
-                                                      cp_type_quals (type));
-            tree memptr;
-            method_type = build_method_type_directly (this_type,
+           tree this_type = cp_build_qualified_type (TYPE_MAIN_VARIANT (r),
+                                                     cp_type_quals (type));
+           tree memptr;
+           method_type = build_method_type_directly (this_type,
                                                      TREE_TYPE (type),
                                                      TYPE_ARG_TYPES (type));
-            memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
-            return cp_build_qualified_type_real (memptr, cp_type_quals (t),
-                                                 complain);
+           memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
+           return cp_build_qualified_type_real (memptr, cp_type_quals (t),
+                                                complain);
          }
        else
          return cp_build_qualified_type_real (build_ptrmem_type (r, type),
@@ -7316,6 +7361,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        /* Substitute the exception specification.  */
        specs = tsubst_exception_specification (t, args, complain,
                                                in_decl);
+       if (specs == error_mark_node)
+         return error_mark_node;
        if (specs)
          fntype = build_exception_variant (fntype, specs);
        return fntype;
@@ -7403,7 +7450,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            /* Normally, make_typename_type does not require that the CTX
               have complete type in order to allow things like:
 
-                template <class T> struct S { typename S<T>::X Y; };
+                template <class T> struct S { typename S<T>::X Y; };
 
               But, such constructs have already been resolved by this
               point, so here CTX really should have complete type, unless
@@ -7421,11 +7468,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                (complain & tf_error) | tf_keep_type_decl);
        if (f == error_mark_node)
          return f;
-       if (TREE_CODE (f) == TYPE_DECL)
-         {
+       if (TREE_CODE (f) == TYPE_DECL)
+         {
            complain |= tf_ignore_bad_quals;
-           f = TREE_TYPE (f);
-         }
+           f = TREE_TYPE (f);
+         }
 
        if (TREE_CODE (f) != TYPENAME_TYPE)
          {
@@ -7437,8 +7484,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                     t, f);
          }
 
-       return cp_build_qualified_type_real
-         (f, cp_type_quals (f) | cp_type_quals (t), complain);
+       return cp_build_qualified_type_real
+         (f, cp_type_quals (f) | cp_type_quals (t), complain);
       }
 
     case UNBOUND_CLASS_TEMPLATE:
@@ -7657,7 +7704,8 @@ tsubst_qualified_id (tree qualified_id, tree args,
       expr = finish_qualified_id_expr (scope, expr, done, address_p);
     }
 
-  expr = convert_from_reference (expr);
+  if (TREE_CODE (expr) != SCOPE_REF)
+    expr = convert_from_reference (expr);
 
   return expr;
 }
@@ -7775,7 +7823,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               template <template <class> class TT> struct C {};
               template <class T> struct D {
                 template <class U> struct E {};
-                C<E> c;                                // #1
+                C<E> c;                                // #1
               };
               D<int> d;                                // #2
 
@@ -7942,7 +7990,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case TEMPLATE_ID_EXPR:
       {
-        /* Substituted template arguments */
+       /* Substituted template arguments */
        tree fn = TREE_OPERAND (t, 0);
        tree targs = TREE_OPERAND (t, 1);
 
@@ -8006,13 +8054,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        return t;
 
     case CONSTRUCTOR:
-      {
-       r = build_constructor
-         (tsubst (TREE_TYPE (t), args, complain, in_decl),
-          tsubst_copy (CONSTRUCTOR_ELTS (t), args, complain, in_decl));
-       TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
-       return r;
-      }
+      /* This is handled by tsubst_copy_and_build.  */
+      gcc_unreachable ();
 
     case VA_ARG_EXPR:
       return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
@@ -8108,15 +8151,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            decl = tsubst (decl, args, complain, in_decl);
            if (decl != error_mark_node)
              {
-               if (init)
-                 DECL_INITIAL (decl) = error_mark_node;
-               /* By marking the declaration as instantiated, we avoid
-                  trying to instantiate it.  Since instantiate_decl can't
-                  handle local variables, and since we've already done
-                  all that needs to be done, that's the right thing to
-                  do.  */
-               if (TREE_CODE (decl) == VAR_DECL)
-                 DECL_TEMPLATE_INSTANTIATED (decl) = 1;
+               if (init)
+                 DECL_INITIAL (decl) = error_mark_node;
+               /* By marking the declaration as instantiated, we avoid
+                  trying to instantiate it.  Since instantiate_decl can't
+                  handle local variables, and since we've already done
+                  all that needs to be done, that's the right thing to
+                  do.  */
+               if (TREE_CODE (decl) == VAR_DECL)
+                 DECL_TEMPLATE_INSTANTIATED (decl) = 1;
                if (TREE_CODE (decl) == VAR_DECL
                    && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
                  /* Anonymous aggregates are a special case.  */
@@ -8349,9 +8392,9 @@ tsubst_non_call_postfix_expression (tree t, tree args,
 
 tree
 tsubst_copy_and_build (tree t,
-                       tree args,
-                       tsubst_flags_t complain,
-                       tree in_decl,
+                      tree args,
+                      tsubst_flags_t complain,
+                      tree in_decl,
                       bool function_p)
 {
 #define RECUR(NODE) \
@@ -8814,38 +8857,35 @@ tsubst_copy_and_build (tree t,
 
     case CONSTRUCTOR:
       {
+       VEC(constructor_elt,gc) *n;
+       constructor_elt *ce;
+       unsigned HOST_WIDE_INT idx;
        tree r;
-       tree elts;
        tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-       bool purpose_p;
+       bool process_index_p;
 
        /* digest_init will do the wrong thing if we let it.  */
        if (type && TYPE_PTRMEMFUNC_P (type))
          return t;
 
-       r = NULL_TREE;
-       /* We do not want to process the purpose of aggregate
+       /* We do not want to process the index of aggregate
           initializers as they are identifier nodes which will be
           looked up by digest_init.  */
-       purpose_p = !(type && IS_AGGR_TYPE (type));
-       for (elts = CONSTRUCTOR_ELTS (t);
-            elts;
-            elts = TREE_CHAIN (elts))
-         {
-           tree purpose = TREE_PURPOSE (elts);
-           tree value = TREE_VALUE (elts);
+       process_index_p = !(type && IS_AGGR_TYPE (type));
 
-           if (purpose && purpose_p)
-             purpose = RECUR (purpose);
-           value = RECUR (value);
-           r = tree_cons (purpose, value, r);
+       n = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t));
+       for (idx = 0; VEC_iterate (constructor_elt, n, idx, ce); idx++)
+         {
+           if (ce->index && process_index_p)
+             ce->index = RECUR (ce->index);
+           ce->value = RECUR (ce->value);
          }
 
-       r = build_constructor (NULL_TREE, nreverse (r));
+       r = build_constructor (NULL_TREE, n);
        TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
 
        if (type)
-         return digest_init (type, r, 0);
+         return digest_init (type, r);
        return r;
       }
 
@@ -8927,7 +8967,6 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
 {
   int ix, len = DECL_NTPARMS (tmpl);
   bool result = false;
-  bool error_p = complain & tf_error;
 
   for (ix = 0; ix != len; ix++)
     {
@@ -8944,12 +8983,16 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
 
          if (nt)
            {
-             if (TYPE_ANONYMOUS_P (nt))
-               error ("%qT is/uses anonymous type", t);
-             else
-               error ("%qT uses local type %qT", t, nt);
+             /* DR 488 makes use of a type with no linkage causes
+                type deduction to fail.  */ 
+             if (complain & tf_error)
+               {
+                 if (TYPE_ANONYMOUS_P (nt))
+                   error ("%qT is/uses anonymous type", t);
+                 else
+                   error ("%qT uses local type %qT", t, nt);
+               }
              result = true;
-             error_p = true;
            }
          /* In order to avoid all sorts of complications, we do not
             allow variably-modified types as template arguments.  */
@@ -8971,7 +9014,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
          result = true;
        }
     }
-  if (result && error_p)
+  if (result && (complain & tf_error))
     error ("  trying to instantiate %qD", tmpl);
   return result;
 }
@@ -9101,11 +9144,12 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
 
 int
 fn_type_unification (tree fn,
-                     tree explicit_targs,
-                     tree targs,
-                     tree args,
-                     tree return_type,
-                    unification_kind_t strict)
+                    tree explicit_targs,
+                    tree targs,
+                    tree args,
+                    tree return_type,
+                    unification_kind_t strict,
+                    int flags)
 {
   tree parms;
   tree fntype;
@@ -9148,11 +9192,11 @@ fn_type_unification (tree fn,
        return 1;
 
       /* Substitute the explicit args into the function type.  This is
-         necessary so that, for instance, explicitly declared function
-         arguments can match null pointed constants.  If we were given
-         an incomplete set of explicit args, we must not do semantic
-         processing during substitution as we could create partial
-         instantiations.  */
+        necessary so that, for instance, explicitly declared function
+        arguments can match null pointed constants.  If we were given
+        an incomplete set of explicit args, we must not do semantic
+        processing during substitution as we could create partial
+        instantiations.  */
       incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
       processing_template_decl += incomplete;
       fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
@@ -9173,7 +9217,6 @@ fn_type_unification (tree fn,
 
   if (return_type)
     {
-      /* We've been given a return type to match, prepend it.  */
       parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
       args = tree_cons (NULL_TREE, return_type, args);
     }
@@ -9184,7 +9227,7 @@ fn_type_unification (tree fn,
      event.  */
   result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
                                  targs, parms, args, /*subr=*/0,
-                                 strict, /*allow_incomplete*/1);
+                                 strict, flags);
 
   if (result == 0)
     /* All is well so far.  Now, check:
@@ -9212,8 +9255,8 @@ fn_type_unification (tree fn,
 
 static int
 maybe_adjust_types_for_deduction (unification_kind_t strict,
-                                  tree* parm,
-                                  tree* arg)
+                                 tree* parm,
+                                 tree* arg)
 {
   int result = 0;
 
@@ -9292,16 +9335,16 @@ maybe_adjust_types_for_deduction (unification_kind_t strict,
 
    If SUBR is 1, we're being called recursively (to unify the
    arguments of a function or method parameter of a function
-   template).  */
+   template). */
 
 static int
 type_unification_real (tree tparms,
-                       tree targs,
-                       tree xparms,
-                       tree xargs,
-                       int subr,
+                      tree targs,
+                      tree xparms,
+                      tree xargs,
+                      int subr,
                       unification_kind_t strict,
-                       int allow_incomplete)
+                      int flags)
 {
   tree parm, arg;
   int i;
@@ -9319,7 +9362,7 @@ type_unification_real (tree tparms,
     {
     case DEDUCE_CALL:
       sub_strict = (UNIFY_ALLOW_OUTER_LEVEL | UNIFY_ALLOW_MORE_CV_QUAL
-                    | UNIFY_ALLOW_DERIVED);
+                   | UNIFY_ALLOW_DERIVED);
       break;
 
     case DEDUCE_CONV:
@@ -9366,17 +9409,13 @@ type_unification_real (tree tparms,
          else
            type = arg;
 
-         if (strict == DEDUCE_EXACT)
-           {
-             if (same_type_p (parm, type))
-               continue;
-           }
-         else
-           /* It might work; we shouldn't check now, because we might
-              get into infinite recursion.  Overload resolution will
-              handle it.  */
+         if (same_type_p (parm, type))
            continue;
-
+         if (strict != DEDUCE_EXACT
+             && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg, 
+                                 flags))
+           continue;
+         
          return 1;
        }
 
@@ -9403,13 +9442,13 @@ type_unification_real (tree tparms,
        }
 
       {
-        int arg_strict = sub_strict;
+       int arg_strict = sub_strict;
 
-        if (!subr)
+       if (!subr)
          arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
 
-        if (unify (tparms, targs, parm, arg, arg_strict))
-          return 1;
+       if (unify (tparms, targs, parm, arg, arg_strict))
+         return 1;
       }
     }
 
@@ -9437,8 +9476,6 @@ type_unification_real (tree tparms,
              && !saw_undeduced++)
            goto again;
 
-         if (!allow_incomplete)
-           error ("incomplete type unification");
          return 2;
        }
 
@@ -9452,10 +9489,10 @@ type_unification_real (tree tparms,
 
 static int
 resolve_overloaded_unification (tree tparms,
-                                tree targs,
-                                tree parm,
-                                tree arg,
-                                unification_kind_t strict,
+                               tree targs,
+                               tree parm,
+                               tree arg,
+                               unification_kind_t strict,
                                int sub_strict)
 {
   tree tempargs = copy_node (targs);
@@ -9551,11 +9588,11 @@ resolve_overloaded_unification (tree tparms,
 
 static int
 try_one_overload (tree tparms,
-                  tree orig_targs,
-                  tree targs,
-                  tree parm,
-                  tree arg,
-                  unification_kind_t strict,
+                 tree orig_targs,
+                 tree targs,
+                 tree parm,
+                 tree arg,
+                 unification_kind_t strict,
                  int sub_strict,
                  bool addr_p)
 {
@@ -9640,7 +9677,7 @@ static int
 verify_class_unification (tree targs, tree parms, tree args)
 {
   parms = tsubst (parms, add_outermost_template_args (args, targs),
-                 tf_none, NULL_TREE);
+                 tf_none, NULL_TREE);
   if (parms == error_mark_node)
     return 1;
 
@@ -9680,10 +9717,10 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg)
        void f(S<I, J, K>, S<I, I, I>);
 
        void g() {
-         S<0, 0, 0> s0;
-         S<0, 1, 2> s2;
+        S<0, 0, 0> s0;
+        S<0, 1, 2> s2;
 
-         f(s0, s2);
+        f(s0, s2);
        }
 
      Now, by the time we consider the unification involving `s2', we
@@ -9782,11 +9819,11 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
       && !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
     {
       /*  Although a CVR qualifier is ignored when being applied to a
-          substituted template parameter ([8.3.2]/1 for example), that
-          does not apply during deduction [14.8.2.4]/1, (even though
-          that is not explicitly mentioned, [14.8.2.4]/9 indicates
-          this).  Except when we're allowing additional CV qualifiers
-          at the outer level [14.8.2.1]/3,1st bullet.  */
+         substituted template parameter ([8.3.2]/1 for example), that
+         does not apply during deduction [14.8.2.4]/1, (even though
+         that is not explicitly mentioned, [14.8.2.4]/9 indicates
+         this).  Except when we're allowing additional CV qualifiers
+         at the outer level [14.8.2.1]/3,1st bullet.  */
       if ((TREE_CODE (arg) == REFERENCE_TYPE
           || TREE_CODE (arg) == FUNCTION_TYPE
           || TREE_CODE (arg) == METHOD_TYPE)
@@ -9875,8 +9912,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
   if (TREE_CODE (arg) == TREE_CODE (parm)
       && TYPE_P (arg)
       /* It is the elements of the array which hold the cv quals of an array
-         type, and the elements might be template type parms. We'll check
-         when we recurse.  */
+        type, and the elements might be template type parms. We'll check
+        when we recurse.  */
       && TREE_CODE (arg) != ARRAY_TYPE
       /* We check the cv-qualifiers when unifying with template type
         parameters below.  We want to allow ARG `const T' to unify with
@@ -9950,7 +9987,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
               class vector.  */
 
            if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
-               == error_mark_node)
+               == error_mark_node)
              return 1;
 
            /* Deduce arguments T, i from TT<T> or TT<i>.
@@ -9960,7 +9997,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
            for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
              {
-               if (unify (tparms, targs,
+               if (unify (tparms, targs,
                           TREE_VEC_ELT (parmvec, i),
                           TREE_VEC_ELT (argvec, i),
                           UNIFY_ALLOW_NONE))
@@ -10070,23 +10107,23 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 
     case PTRMEM_CST:
      {
-        /* A pointer-to-member constant can be unified only with
-         another constant.  */
+       /* A pointer-to-member constant can be unified only with
+        another constant.  */
       if (TREE_CODE (arg) != PTRMEM_CST)
-        return 1;
+       return 1;
 
       /* Just unify the class member. It would be useless (and possibly
-         wrong, depending on the strict flags) to unify also
-         PTRMEM_CST_CLASS, because we want to be sure that both parm and
-         arg refer to the same variable, even if through different
-         classes. For instance:
+        wrong, depending on the strict flags) to unify also
+        PTRMEM_CST_CLASS, because we want to be sure that both parm and
+        arg refer to the same variable, even if through different
+        classes. For instance:
 
-         struct A { int x; };
-         struct B : A { };
+        struct A { int x; };
+        struct B : A { };
 
-         Unification of &A::x and &B::x must succeed.  */
+        Unification of &A::x and &B::x must succeed.  */
       return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
-                    PTRMEM_CST_MEMBER (arg), strict);
+                   PTRMEM_CST_MEMBER (arg), strict);
      }
 
     case POINTER_TYPE:
@@ -10260,44 +10297,55 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       if (TREE_CODE (arg) != TREE_CODE (parm))
        return 1;
 
+      /* CV qualifications for methods can never be deduced, they must
+        match exactly.  We need to check them explicitly here,
+        because type_unification_real treats them as any other
+        cvqualified parameter.  */
+      if (TREE_CODE (parm) == METHOD_TYPE
+         && (!check_cv_quals_for_unify
+             (UNIFY_ALLOW_NONE,
+              TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
+              TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
+       return 1;
+
       if (unify (tparms, targs, TREE_TYPE (parm),
                 TREE_TYPE (arg), UNIFY_ALLOW_NONE))
        return 1;
       return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
-                                   TYPE_ARG_TYPES (arg), 1,
-                                   DEDUCE_EXACT, 0);
+                                   TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
+                                   LOOKUP_NORMAL);
 
     case OFFSET_TYPE:
       /* Unify a pointer to member with a pointer to member function, which
-         deduces the type of the member as a function type. */
+        deduces the type of the member as a function type. */
       if (TYPE_PTRMEMFUNC_P (arg))
-        {
-          tree method_type;
-          tree fntype;
-          cp_cv_quals cv_quals;
-
-          /* Check top-level cv qualifiers */
-          if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
-            return 1;
-
-          if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
-                     TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE))
-            return 1;
-
-          /* Determine the type of the function we are unifying against. */
-          method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
-          fntype =
-            build_function_type (TREE_TYPE (method_type),
-                                 TREE_CHAIN (TYPE_ARG_TYPES (method_type)));
-
-          /* Extract the cv-qualifiers of the member function from the
-             implicit object parameter and place them on the function
-             type to be restored later. */
-          cv_quals =
-            cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type))));
-          fntype = build_qualified_type (fntype, cv_quals);
-          return unify (tparms, targs, TREE_TYPE (parm), fntype, strict);
-        }
+       {
+         tree method_type;
+         tree fntype;
+         cp_cv_quals cv_quals;
+
+         /* Check top-level cv qualifiers */
+         if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
+           return 1;
+
+         if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+                    TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE))
+           return 1;
+
+         /* Determine the type of the function we are unifying against. */
+         method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
+         fntype =
+           build_function_type (TREE_TYPE (method_type),
+                                TREE_CHAIN (TYPE_ARG_TYPES (method_type)));
+
+         /* Extract the cv-qualifiers of the member function from the
+            implicit object parameter and place them on the function
+            type to be restored later. */
+         cv_quals =
+           cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type))));
+         fntype = build_qualified_type (fntype, cv_quals);
+         return unify (tparms, targs, TREE_TYPE (parm), fntype, strict);
+       }
 
       if (TREE_CODE (arg) != OFFSET_TYPE)
        return 1;
@@ -10443,17 +10491,30 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2));
   int better1 = 0;
   int better2 = 0;
-
-  /* If only one is a member function, they are unordered.  */
-  if (DECL_FUNCTION_MEMBER_P (decl1) != DECL_FUNCTION_MEMBER_P (decl2))
-    return 0;
-
-  /* Don't consider 'this' parameter.  */
+  
+  /* Remove the this parameter from non-static member functions.  If
+     one is a non-static member function and the other is not a static
+     member function, remove the first parameter from that function
+     also.  This situation occurs for operator functions where we
+     locate both a member function (with this pointer) and non-member
+     operator (with explicit first operand).  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1))
-    args1 = TREE_CHAIN (args1);
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2))
-    args2 = TREE_CHAIN (args2);
-
+    {
+      len--; /* LEN is the number of significant arguments for DECL1 */
+      args1 = TREE_CHAIN (args1);
+      if (!DECL_STATIC_FUNCTION_P (decl2))
+       args2 = TREE_CHAIN (args2);
+    }
+  else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2))
+    {
+      args2 = TREE_CHAIN (args2);
+      if (!DECL_STATIC_FUNCTION_P (decl1))
+       {
+         len--;
+         args1 = TREE_CHAIN (args1);
+       }
+    }
+    
   /* If only one is a conversion operator, they are unordered.  */
   if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2))
     return 0;
@@ -10649,8 +10710,8 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
   if (fn_type_unification (fn, explicit_args, targs,
                           decl_arg_types,
                           (check_rettype || DECL_CONV_FN_P (fn)
-                           ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT))
+                           ? TREE_TYPE (decl_type) : NULL_TREE),
+                          DEDUCE_EXACT, LOOKUP_NORMAL))
     return NULL_TREE;
 
   return targs;
@@ -10678,7 +10739,7 @@ get_class_bindings (tree tparms, tree parms, tree args)
   tree vec = make_tree_vec (ntparms);
 
   if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args),
-            UNIFY_ALLOW_NONE))
+            UNIFY_ALLOW_NONE))
     return NULL_TREE;
 
   for (i =  0; i < ntparms; ++i)
@@ -10988,15 +11049,17 @@ do_decl_instantiation (tree decl, tree storage)
     {
       if (pedantic && !in_system_header)
        pedwarn ("ISO C++ forbids the use of %<extern%> on explicit "
-                 "instantiations");
+                "instantiations");
       extern_p = 1;
     }
   else
     error ("storage class %qD applied to template instantiation", storage);
-
+  
+  check_explicit_instantiation_namespace (result);
   mark_decl_instantiated (result, extern_p);
   if (! extern_p)
-    instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0);
+    instantiate_decl (result, /*defer_ok=*/1, 
+                     /*expl_inst_class_mem_p=*/false);
 }
 
 void
@@ -11033,7 +11096,8 @@ instantiate_class_member (tree decl, int extern_p)
 {
   mark_decl_instantiated (decl, extern_p);
   if (! extern_p)
-    instantiate_decl (decl, /*defer_ok=*/1, /* undefined_ok=*/1);
+    instantiate_decl (decl, /*defer_ok=*/1, 
+                     /*expl_inst_class_mem_p=*/true);
 }
 
 /* Perform an explicit instantiation of template class T.  STORAGE, if
@@ -11064,7 +11128,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
     {
       if (complain & tf_error)
        error ("explicit instantiation of %q#T before definition of template",
-               t);
+              t);
       return;
     }
 
@@ -11072,7 +11136,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
     {
       if (pedantic && !in_system_header)
        pedwarn("ISO C++ forbids the use of %qE on explicit instantiations",
-                storage);
+               storage);
 
       if (storage == ridpointers[(int) RID_INLINE])
        nomem_p = 1;
@@ -11083,7 +11147,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
       else
        {
          error ("storage class %qD applied to template instantiation",
-                 storage);
+                storage);
          extern_p = 0;
        }
     }
@@ -11109,7 +11173,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
         No program shall explicitly instantiate any template more
         than once.
 
-         If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
+        If PREVIOUS_INSTANTIATION_EXTERN_P, then the first explicit
         instantiation was `extern'.  If EXTERN_P then the second is.
         These cases are OK.  */
       previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
@@ -11123,6 +11187,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
        return;
     }
 
+  check_explicit_instantiation_namespace (TYPE_NAME (t));
   mark_class_instantiated (t, extern_p);
 
   if (nomem_p)
@@ -11135,7 +11200,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
        declarations, and not the definitions, of members are
        instantiated, we have here:
 
-         [temp.explicit]
+        [temp.explicit]
 
         The explicit instantiation of a class template specialization
         implies the instantiation of all of its members not
@@ -11160,7 +11225,7 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
 
     if (CLASSTYPE_NESTED_UTDS (t))
       binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
-                             bt_instantiate_type_proc, &storage);
+                            bt_instantiate_type_proc, &storage);
   }
 }
 
@@ -11254,13 +11319,9 @@ regenerate_decl_from_template (tree decl, tree tmpl)
        DECL_INLINE (decl) = 1;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
-    {
-      if (!DECL_INITIALIZED_IN_CLASS_P (decl)
-         && DECL_INITIAL (code_pattern))
-       DECL_INITIAL (decl) =
-         tsubst_expr (DECL_INITIAL (code_pattern), args,
-                      tf_error, DECL_TI_TEMPLATE (decl));
-    }
+    DECL_INITIAL (decl) =
+      tsubst_expr (DECL_INITIAL (code_pattern), args,
+                  tf_error, DECL_TI_TEMPLATE (decl));
   else
     gcc_unreachable ();
 
@@ -11279,9 +11340,9 @@ template_for_substitution (tree decl)
      for the instantiation.  This is not always the most general
      template.  Consider, for example:
 
-        template <class T>
+       template <class T>
        struct S { template <class U> void f();
-                  template <> void f<int>(); };
+                  template <> void f<int>(); };
 
      and an instantiation of S<double>::f<int>.  We want TD to be the
      specialization S<T>::f<int>, not the more general S<T>::f<U>.  */
@@ -11329,14 +11390,12 @@ template_for_substitution (tree decl)
    DEFER_OK is nonzero, then we don't have to actually do the
    instantiation now; we just have to do it sometime.  Normally it is
    an error if this is an explicit instantiation but D is undefined.
-   If UNDEFINED_OK is nonzero, then instead we treat it as an implicit
-   instantiation.  UNDEFINED_OK is nonzero only if we are being used
-   to instantiate the members of an explicitly instantiated class
-   template.  */
-
+   EXPL_INST_CLASS_MEM_P is true iff D is a member of an
+   explicitly instantiated class template.  */
 
 tree
-instantiate_decl (tree d, int defer_ok, int undefined_ok)
+instantiate_decl (tree d, int defer_ok, 
+                 bool expl_inst_class_mem_p)
 {
   tree tmpl = DECL_TI_TEMPLATE (d);
   tree gen_args;
@@ -11345,9 +11404,10 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
   tree code_pattern;
   tree spec;
   tree gen_tmpl;
-  int pattern_defined;
+  bool pattern_defined;
   int need_push;
   location_t saved_loc = input_location;
+  bool external_p;
 
   /* This function should only be used to instantiate templates for
      functions and static member variables.  */
@@ -11393,9 +11453,6 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
   timevar_push (TV_PARSE);
 
-  /* We may be in the middle of deferred access check.  Disable it now.  */
-  push_deferring_access_checks (dk_no_deferred);
-
   /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
      for the instantiation.  */
   td = template_for_substitution (d);
@@ -11415,6 +11472,10 @@ 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);
+
+  /* We may be in the middle of deferred access check.  Disable it now.  */
+  push_deferring_access_checks (dk_no_deferred);
+
   /* Unless an explicit instantiation directive has already determined
      the linkage of D, remember that a definition is available for
      this entity.  */
@@ -11425,9 +11486,14 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
   input_location = DECL_SOURCE_LOCATION (d);
 
-  if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
+  /* If D is a member of an explicitly instantiated class template,
+     and no definition is available, treat it like an implicit
+     instantiation.  */ 
+  if (!pattern_defined && expl_inst_class_mem_p 
+      && DECL_EXPLICIT_INSTANTIATION (d)) 
     {
       DECL_NOT_REALLY_EXTERN (d) = 0;
+      DECL_INTERFACE_KNOWN (d) = 0;
       SET_DECL_IMPLICIT_INSTANTIATION (d);
     }
 
@@ -11459,24 +11525,58 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
       pop_access_scope (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)))
+  /* Check to see whether we know that this template will be
+     instantiated in some other file, as with "extern template"
+     extension.  */
+  external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
+  /* In general, we do not instantiate such templates...  */
+  if (external_p
+      /* ... but we instantiate inline functions so that we can inline
+        them and ... */
+      && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+      /* ... we instantiate static data members whose values are
+        needed in integral constant expressions.  */
+      && ! (TREE_CODE (d) == VAR_DECL 
+           && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d)))
     goto out;
   /* Defer all other templates, unless we have been explicitly
-     forbidden from doing so.  We restore the source position here
-     because it's used by add_pending_template.  */
-  else if (! pattern_defined || defer_ok)
-    {
+     forbidden from doing so.  */
+  if (/* If there is no definition, we cannot instantiate the
+        template.  */
+      ! pattern_defined 
+      /* If it's OK to postpone instantiation, do so.  */
+      || defer_ok
+      /* If this is a static data member that will be defined
+        elsewhere, we don't want to instantiate the entire data
+        member, but we do want to instantiate the initializer so that
+        we can substitute that elsewhere.  */
+      || (external_p && TREE_CODE (d) == VAR_DECL))
+    {
+      /* The definition of the static data member is now required so
+        we must substitute the initializer.  */
+      if (TREE_CODE (d) == VAR_DECL
+         && !DECL_INITIAL (d) 
+         && DECL_INITIAL (code_pattern))
+       {
+         tree ns;
+         tree init;
+
+         ns = decl_namespace_context (d);
+         push_nested_namespace (ns);
+         push_nested_class (DECL_CONTEXT (d));
+         init = tsubst_expr (DECL_INITIAL (code_pattern), 
+                             args,
+                             tf_error | tf_warning, NULL_TREE);
+         DECL_INITIAL (d) = NULL_TREE;
+         finish_static_data_member_decl (d, init, 
+                                         /*asmspec_tree=*/NULL_TREE,
+                                         LOOKUP_ONLYCONVERTING);
+         pop_nested_class ();
+         pop_nested_namespace (ns);
+       }
+
+      /* We restore the source position here because it's used by
+        add_pending_template.  */
       input_location = saved_loc;
 
       if (at_eof && !pattern_defined
@@ -11491,7 +11591,10 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
        pedwarn
          ("explicit instantiation of %qD but no definition available", d);
 
-      add_pending_template (d);
+      /* ??? Historically, we have instantiated inline functions, even
+        when marked as "extern template".  */
+      if (!(external_p && TREE_CODE (d) == VAR_DECL))
+       add_pending_template (d);
       goto out;
     }
   /* Tell the repository that D is available in this translation unit
@@ -11543,10 +11646,7 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
 
       /* 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);
+      cp_finish_decl (d, DECL_INITIAL (d), NULL_TREE, 0);
       pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
@@ -11634,11 +11734,10 @@ instantiate_pending_templates (int retries)
      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 %q+D, possibly from virtual table"
-                  " generation",
-                  max_tinst_depth, TREE_VALUE (pending_templates));
+      error ("template instantiation depth exceeds maximum of %d"
+           " instantiating %q+D, possibly from virtual table generation"
+           " (use -ftemplate-depth-NN to increase the maximum)",
+           max_tinst_depth, TREE_VALUE (pending_templates));
       return;
     }
 
@@ -11665,8 +11764,9 @@ instantiate_pending_templates (int retries)
                         fn;
                         fn = TREE_CHAIN (fn))
                      if (! DECL_ARTIFICIAL (fn))
-                       instantiate_decl (fn, /*defer_ok=*/0,
-                                         /*undefined_ok=*/0);
+                       instantiate_decl (fn, 
+                                         /*defer_ok=*/0,
+                                         /*expl_inst_class_mem_p=*/false);
                  if (COMPLETE_TYPE_P (instantiation))
                    reconsider = 1;
                }
@@ -11686,9 +11786,10 @@ instantiate_pending_templates (int retries)
              if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
                  && !DECL_TEMPLATE_INSTANTIATED (instantiation))
                {
-                 instantiation = instantiate_decl (instantiation,
-                                                   /*defer_ok=*/0,
-                                                   /*undefined_ok=*/0);
+                 instantiation 
+                   = instantiate_decl (instantiation,
+                                       /*defer_ok=*/0,
+                                       /*expl_inst_class_mem_p=*/false);
                  if (DECL_TEMPLATE_INSTANTIATED (instantiation))
                    reconsider = 1;
                }
@@ -11926,12 +12027,12 @@ dependent_type_p_r (tree type)
       || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
     return true;
   /* -- a qualified-id with a nested-name-specifier which contains a
-        class-name that names a dependent type or whose unqualified-id
+       class-name that names a dependent type or whose unqualified-id
        names a dependent type.  */
   if (TREE_CODE (type) == TYPENAME_TYPE)
     return true;
   /* -- a cv-qualified type where the cv-unqualified type is
-        dependent.  */
+       dependent.  */
   type = TYPE_MAIN_VARIANT (type);
   /* -- a compound type constructed from any dependent type.  */
   if (TYPE_PTR_TO_MEMBER_P (type))
@@ -11956,7 +12057,7 @@ dependent_type_p_r (tree type)
       return false;
     }
   /* -- an array type constructed from any dependent type or whose
-        size is specified by a constant expression that is
+       size is specified by a constant expression that is
        value-dependent.  */
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -11991,7 +12092,7 @@ dependent_type_p_r (tree type)
      considered dependent too.  For example:
 
        template <int I> void f() {
-         enum E { a = I };
+        enum E { a = I };
         S<sizeof (E)> s;
        }
 
@@ -12103,7 +12204,7 @@ value_dependent_expression_p (tree expression)
 
     case VAR_DECL:
        /* A constant with integral or enumeration type and is initialized
-         with an expression that is value-dependent.  */
+         with an expression that is value-dependent.  */
       if (DECL_INITIAL (expression)
          && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression))
          && value_dependent_expression_p (DECL_INITIAL (expression)))
@@ -12116,8 +12217,8 @@ value_dependent_expression_p (tree expression)
     case REINTERPRET_CAST_EXPR:
     case CAST_EXPR:
       /* These expressions are value-dependent if the type to which
-        the cast occurs is dependent or the expression being casted
-        is value-dependent.  */
+        the cast occurs is dependent or the expression being casted
+        is value-dependent.  */
       {
        tree type = TREE_TYPE (expression);
 
@@ -12150,7 +12251,7 @@ value_dependent_expression_p (tree expression)
     case SIZEOF_EXPR:
     case ALIGNOF_EXPR:
       /* A `sizeof' expression is value-dependent if the operand is
-        type-dependent.  */
+        type-dependent.  */
       expression = TREE_OPERAND (expression, 0);
       if (TYPE_P (expression))
        return dependent_type_p (expression);
@@ -12165,11 +12266,11 @@ value_dependent_expression_p (tree expression)
 
     case CALL_EXPR:
       /* A CALL_EXPR is value-dependent if any argument is
-        value-dependent.  Why do we have to handle CALL_EXPRs in this
-        function at all?  First, some function calls, those for which
-        value_dependent_expression_p is true, man appear in constant
-        expressions.  Second, there appear to be bugs which result in
-        other CALL_EXPRs reaching this point. */
+        value-dependent.  Why do we have to handle CALL_EXPRs in this
+        function at all?  First, some function calls, those for which
+        value_dependent_expression_p is true, man appear in constant
+        expressions.  Second, there appear to be bugs which result in
+        other CALL_EXPRs reaching this point. */
       {
        tree function = TREE_OPERAND (expression, 0);
        tree args = TREE_OPERAND (expression, 1);
@@ -12193,7 +12294,7 @@ value_dependent_expression_p (tree expression)
 
     default:
       /* A constant expression is value-dependent if any subexpression is
-        value-dependent.  */
+        value-dependent.  */
       switch (TREE_CODE_CLASS (TREE_CODE (expression)))
        {
        case tcc_reference:
@@ -12329,7 +12430,8 @@ type_dependent_expression_p (tree expression)
            return true;
          expression = TREE_OPERAND (expression, 0);
        }
-      gcc_assert (TREE_CODE (expression) == OVERLOAD);
+      gcc_assert (TREE_CODE (expression) == OVERLOAD
+                 || TREE_CODE (expression) == FUNCTION_DECL);
 
       while (expression)
        {