]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/pt.c
re PR c++/25342 (internal compiler error: in lookup_member, at cp/search.c:1209)
[gcc.git] / gcc / cp / pt.c
index 6724cf49b2e6d74a5cb74cb1093eaf94aaea3f4f..63277e59964aa769da2741ed01ce693b19d4664b 100644 (file)
@@ -135,9 +135,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
 static void regenerate_decl_from_template (tree, tree);
-static tree most_specialized (tree, tree, tree);
 static tree most_specialized_class (tree, tree);
-static int template_class_depth_real (tree, int);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
 static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
@@ -145,9 +143,7 @@ static void check_specialization_scope (void);
 static tree process_partial_specialization (tree);
 static void set_current_access_from_decl (tree);
 static void check_default_tmpl_args (tree, tree, int, int);
-static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
 static tree get_template_base (tree, tree, tree, tree);
-static int verify_class_unification (tree, tree, tree);
 static tree try_class_unification (tree, tree, tree, tree);
 static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
                                           tree, tree);
@@ -266,15 +262,14 @@ finish_member_template_decl (tree decl)
 
    A<T>::B<U> has depth two, while A<T> has depth one.
    Both A<T>::B<int> and A<int>::B<U> have depth one, if
-   COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not
-   specializations.
+   they are instantiations, not specializations.
 
    This function is guaranteed to return 0 if passed NULL_TREE so
    that, for example, `template_class_depth (current_class_type)' is
    always safe.  */
 
-static int
-template_class_depth_real (tree type, int count_specializations)
+int
+template_class_depth (tree type)
 {
   int depth;
 
@@ -287,18 +282,14 @@ template_class_depth_real (tree type, int count_specializations)
        {
          if (CLASSTYPE_TEMPLATE_INFO (type)
              && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
-             && ((count_specializations
-                  && CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
-                 || uses_template_parms (CLASSTYPE_TI_ARGS (type))))
+             && uses_template_parms (CLASSTYPE_TI_ARGS (type)))
            ++depth;
        }
       else
        {
          if (DECL_TEMPLATE_INFO (type)
              && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type))
-             && ((count_specializations
-                  && DECL_TEMPLATE_SPECIALIZATION (type))
-                 || uses_template_parms (DECL_TI_ARGS (type))))
+             && uses_template_parms (DECL_TI_ARGS (type)))
            ++depth;
        }
     }
@@ -306,16 +297,6 @@ template_class_depth_real (tree type, int count_specializations)
   return depth;
 }
 
-/* Returns the template nesting level of the indicated class TYPE.
-   Like template_class_depth_real, but instantiations do not count in
-   the depth.  */
-
-int
-template_class_depth (tree type)
-{
-  return template_class_depth_real (type, /*count_specializations=*/0);
-}
-
 /* Returns 1 if processing DECL as part of do_pending_inlines
    needs us to push template parms.  */
 
@@ -695,8 +676,12 @@ check_explicit_instantiation_namespace (tree spec)
 void
 maybe_process_partial_specialization (tree type)
 {
-  /* TYPE maybe an ERROR_MARK_NODE.  */
-  tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE;
+  tree context;
+
+  if (type == error_mark_node)
+    return;
+
+  context = TYPE_CONTEXT (type);
 
   if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
     {
@@ -913,8 +898,8 @@ retrieve_specialization (tree tmpl, tree args,
 static tree
 retrieve_local_specialization (tree tmpl)
 {
-  tree spec = htab_find_with_hash (local_specializations, tmpl,
-                                  htab_hash_pointer (tmpl));
+  tree spec = (tree) htab_find_with_hash (local_specializations, tmpl,
+                                          htab_hash_pointer (tmpl));
   return spec ? TREE_PURPOSE (spec) : NULL_TREE;
 }
 
@@ -1179,6 +1164,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
            }
          else
            {
+             tree clone;
              /* This situation should occur only if the first
                 specialization is an implicit instantiation, the
                 second is an explicit specialization, and the
@@ -1204,6 +1190,23 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
                 there were no definition, and vice versa.  */
              DECL_INITIAL (fn) = NULL_TREE;
              duplicate_decls (spec, fn, is_friend);
+             /* The call to duplicate_decls will have applied
+                [temp.expl.spec]: 
+
+                  An explicit specialization of a function template
+                  is inline only if it is explicitly declared to be,
+                  and independently of whether its function template
+                  is.
+
+               to the primary function; now copy the inline bits to
+               the various clones.  */   
+             FOR_EACH_CLONE (clone, fn)
+               {
+                 DECL_DECLARED_INLINE_P (clone)
+                   = DECL_DECLARED_INLINE_P (fn);
+                 DECL_INLINE (clone)
+                   = DECL_INLINE (fn);
+               }
              check_specialization_namespace (fn);
 
              return fn;
@@ -1338,6 +1341,11 @@ determine_specialization (tree template_id,
   tree targs;
   tree explicit_targs;
   tree candidates = NULL_TREE;
+  /* A TREE_LIST of templates of which DECL may be a specialization.
+     The TREE_VALUE of each node is a TEMPLATE_DECL.  The
+     corresponding TREE_PURPOSE is the set of template arguments that,
+     when used to instantiate the template, would produce a function
+     with the signature of DECL.  */
   tree templates = NULL_TREE;
   int header_count;
   struct cp_binding_level *b;
@@ -1441,7 +1449,8 @@ determine_specialization (tree template_id,
          if (current_binding_level->kind == sk_template_parms
              && !current_binding_level->explicit_spec_p
              && (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn))
-                 != TREE_VEC_LENGTH (TREE_VALUE (current_template_parms))))
+                 != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS 
+                                     (current_template_parms))))
            continue;
 
          /* See whether this function might be a specialization of this
@@ -1542,12 +1551,12 @@ determine_specialization (tree template_id,
         the EDG front-end has that behavior, and John Spicer claims
         that the committee simply forgot to delete the wording in
         [temp.expl.spec].  */
-     tree tmpl = most_specialized (templates, decl, explicit_targs);
-     if (tmpl && tmpl != error_mark_node)
-       {
-        targs = get_bindings (tmpl, decl, explicit_targs, /*check_ret=*/true);
-        templates = tree_cons (targs, tmpl, NULL_TREE);
-       }
+      tree tmpl = most_specialized_instantiation (templates);
+      if (tmpl != error_mark_node)
+       {
+         templates = tmpl;
+         TREE_CHAIN (templates) = NULL_TREE;
+       }
     }
 
   if (templates == NULL_TREE && candidates == NULL_TREE)
@@ -1877,8 +1886,6 @@ check_explicit_specialization (tree declarator,
              ("default argument specified in explicit specialization");
            break;
          }
-      if (current_lang_name == lang_name_c)
-       error ("template specialization with C linkage");
     }
 
   if (specialization || member_specialization || explicit_instantiation)
@@ -1902,12 +1909,21 @@ check_explicit_specialization (tree declarator,
 
              /* Find the namespace binding, using the declaration
                 context.  */
-             fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
+             fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
+                                          false, true);
              if (!fns || !is_overloaded_fn (fns))
                {
                  error ("%qD is not a template function", dname);
                  fns = error_mark_node;
                }
+             else
+               {
+                 tree fn = OVL_CURRENT (fns);
+                 if (!is_associated_namespace (CP_DECL_CONTEXT (decl),
+                                               CP_DECL_CONTEXT (fn)))
+                   error ("%qD is not declared in %qD",
+                          decl, current_namespace);
+               }
            }
 
          declarator = lookup_template_function (fns, NULL_TREE);
@@ -2439,7 +2455,7 @@ end_template_decl (void)
 /* Given a template argument vector containing the template PARMS.
    The innermost PARMS are given first.  */
 
-tree
+static tree
 current_template_args (void)
 {
   tree header;
@@ -2619,10 +2635,10 @@ process_partial_specialization (tree decl)
 
      or some such would have been OK.  */
   tpd.level = TMPL_PARMS_DEPTH (current_template_parms);
-  tpd.parms = alloca (sizeof (int) * ntparms);
+  tpd.parms = (int *) alloca (sizeof (int) * ntparms);
   memset (tpd.parms, 0, sizeof (int) * ntparms);
 
-  tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs);
+  tpd.arg_uses_template_parms = (int *) alloca (sizeof (int) * nargs);
   memset (tpd.arg_uses_template_parms, 0, sizeof (int) * nargs);
   for (i = 0; i < nargs; ++i)
     {
@@ -2693,11 +2709,11 @@ process_partial_specialization (tree decl)
                {
                  /* We haven't yet initialized TPD2.  Do so now.  */
                  tpd2.arg_uses_template_parms
-                   = alloca (sizeof (int) * nargs);
+                   = (int *) alloca (sizeof (int) * nargs);
                  /* The number of parameters here is the number in the
                     main template, which, as checked in the assertion
                     above, is NARGS.  */
-                 tpd2.parms = alloca (sizeof (int) * nargs);
+                 tpd2.parms = (int *) alloca (sizeof (int) * nargs);
                  tpd2.level =
                    TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
                }
@@ -2740,7 +2756,7 @@ process_partial_specialization (tree decl)
     return decl;
 
   DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
-    = tree_cons (inner_args, inner_parms,
+    = tree_cons (specargs, inner_parms,
                 DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
   TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
   return decl;
@@ -2967,10 +2983,8 @@ push_template_decl_real (tree decl, bool is_friend)
     {
       if (DECL_CLASS_SCOPE_P (decl))
        member_template_p = true;
-      if (current_lang_name == lang_name_c)
-       error ("template with C linkage");
-      else if (TREE_CODE (decl) == TYPE_DECL
-              && ANON_AGGRNAME_P (DECL_NAME (decl)))
+      if (TREE_CODE (decl) == TYPE_DECL
+         && ANON_AGGRNAME_P (DECL_NAME (decl)))
        error ("template class without a name");
       else if (TREE_CODE (decl) == FUNCTION_DECL)
        {
@@ -2998,9 +3012,8 @@ push_template_decl_real (tree decl, bool is_friend)
              return decl;
            }
        }
-      else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
-               && CLASS_TYPE_P (TREE_TYPE (decl)))
-              || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)))
+      else if (DECL_IMPLICIT_TYPEDEF_P (decl)
+              && CLASS_TYPE_P (TREE_TYPE (decl)))
        /* OK */;
       else
        {
@@ -3348,7 +3361,7 @@ fold_non_dependent_expr (tree expr)
    initializers can maintain a syntactic rather than semantic form
    (even if they are non-dependent, for access-checking purposes).  */
 
-tree
+static tree
 fold_decl_constant_value (tree expr)
 {
   tree const_expr = expr;
@@ -3931,6 +3944,13 @@ convert_template_argument (tree parm,
        }
       else
        val = arg;
+      /* We only form one instance of each template specialization.
+        Therefore, if we use a non-canonical variant (i.e., a
+        typedef), any future messages referring to the type will use 
+        the typedef, which is confusing if those future uses do not
+        themselves also use the typedef.  */
+      if (TYPE_P (val))
+       val = canonical_type_variant (val);
     }
   else
     {
@@ -4103,7 +4123,7 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
     gcc_obstack_init (&scratch_obstack);
   else
     obstack_free (&scratch_obstack, scratch_firstobj);
-  scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
+  scratch_firstobj = (char *) obstack_alloc (&scratch_obstack, 1);
 
 #define ccat(C)        obstack_1grow (&scratch_obstack, (C));
 #define cat(S) obstack_grow (&scratch_obstack, (S), strlen (S))
@@ -4332,7 +4352,7 @@ lookup_template_class (tree d1,
        {
          if (context)
            push_decl_namespace (context);
-         template = lookup_name (d1, /*prefer_type=*/0);
+         template = lookup_name (d1);
          template = maybe_get_template_decl_from_type_decl (template);
          if (context)
            pop_decl_namespace ();
@@ -5364,7 +5384,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
     }
 
   /* First, we look for a class template.  */
-  tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
+  tmpl = lookup_name (DECL_NAME (friend_tmpl));
 
   /* But, if we don't find one, it might be because we're in a
      situation like this:
@@ -5379,7 +5399,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
      for `S<int>', not the TEMPLATE_DECL.  */
   if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
     {
-      tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
+      tmpl = lookup_name_prefer_type (DECL_NAME (friend_tmpl), 1);
       tmpl = maybe_get_template_decl_from_type_decl (tmpl);
     }
 
@@ -5473,34 +5493,34 @@ instantiate_class_template (tree type)
   template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
   gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
 
-  /* Figure out which arguments are being used to do the
-     instantiation.  */
-  args = CLASSTYPE_TI_ARGS (type);
-
   /* Determine what specialization of the original template to
      instantiate.  */
-  t = most_specialized_class (template, args);
+  t = most_specialized_class (type, template);
   if (t == error_mark_node)
     {
-      const char *str = "candidates are:";
-      error ("ambiguous class template instantiation for %q#T", type);
-      for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
-          t = TREE_CHAIN (t))
-       {
-         if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args))
-           {
-             error ("%s %+#T", str, TREE_TYPE (t));
-             str = "               ";
-           }
-       }
       TYPE_BEING_DEFINED (type) = 1;
       return error_mark_node;
     }
+  else if (t)
+    {
+      /* This TYPE is actually an instantiation of a partial
+        specialization.  We replace the innermost set of ARGS with
+        the arguments appropriate for substitution.  For example,
+        given:
+       
+           template <class T> struct S {};
+          template <class T> struct S<T*> {};
 
-  if (t)
-    pattern = TREE_TYPE (t);
+        and supposing that we are instantiating S<int*>, ARGS will
+         presently be {int*} -- but we need {int}.  */
+      pattern = TREE_TYPE (t);
+      args = TREE_PURPOSE (t);
+    }
   else
-    pattern = TREE_TYPE (template);
+    {
+      pattern = TREE_TYPE (template);
+      args = CLASSTYPE_TI_ARGS (type);
+    }
 
   /* If the template we're instantiating is incomplete, then clearly
      there's nothing we can do.  */
@@ -5521,34 +5541,6 @@ instantiate_class_template (tree type)
 
   push_to_top_level ();
 
-  if (t)
-    {
-      /* This TYPE is actually an instantiation of a partial
-        specialization.  We replace the innermost set of ARGS with
-        the arguments appropriate for substitution.  For example,
-        given:
-
-          template <class T> struct S {};
-          template <class T> struct S<T*> {};
-
-        and supposing that we are instantiating S<int*>, ARGS will
-        present be {int*} but we need {int}.  */
-      tree inner_args
-       = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
-                             args);
-
-      /* If there were multiple levels in ARGS, replacing the
-        innermost level would alter CLASSTYPE_TI_ARGS, which we don't
-        want, so we make a copy first.  */
-      if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
-       {
-         args = copy_node (args);
-         SET_TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args), inner_args);
-       }
-      else
-       args = inner_args;
-    }
-
   SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
 
   /* Set the input location to the template definition. This is needed
@@ -5649,14 +5641,12 @@ instantiate_class_template (tree type)
            {
              /* Build new CLASSTYPE_NESTED_UTDS.  */
 
-             tree tag = t;
-             tree name = TYPE_IDENTIFIER (tag);
              tree newtag;
              bool class_template_p;
 
-             class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE
-                                 && TYPE_LANG_SPECIFIC (tag)
-                                 && CLASSTYPE_IS_TEMPLATE (tag));
+             class_template_p = (TREE_CODE (t) != ENUMERAL_TYPE
+                                 && TYPE_LANG_SPECIFIC (t)
+                                 && CLASSTYPE_IS_TEMPLATE (t));
              /* If the member is a class template, then -- even after
                 substitution -- there may be dependent types in the
                 template argument list for the class.  We increment
@@ -5665,7 +5655,7 @@ instantiate_class_template (tree type)
                 when outside of a template.  */
              if (class_template_p)
                ++processing_template_decl;
-             newtag = tsubst (tag, args, tf_error, NULL_TREE);
+             newtag = tsubst (t, args, tf_error, NULL_TREE);
              if (class_template_p)
                --processing_template_decl;
              if (newtag == error_mark_node)
@@ -5673,6 +5663,8 @@ instantiate_class_template (tree type)
 
              if (TREE_CODE (newtag) != ENUMERAL_TYPE)
                {
+                 tree name = TYPE_IDENTIFIER (t);
+
                  if (class_template_p)
                    /* Unfortunately, lookup_template_class sets
                       CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
@@ -5961,7 +5953,7 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 {
   int len = TREE_VEC_LENGTH (t);
   int need_new = 0, i;
-  tree *elts = alloca (len * sizeof (tree));
+  tree *elts = (tree *) alloca (len * sizeof (tree));
 
   for (i = 0; i < len; i++)
     {
@@ -6004,6 +5996,12 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
   tree r = NULL_TREE;
   tree* new_parms;
 
+  /* When substituting into a template, we must set
+     PROCESSING_TEMPLATE_DECL as the template parameters may be
+     dependent if they are based on one-another, and the dependency
+     predicates are short-circuit outside of templates.  */
+  ++processing_template_decl;
+
   for (new_parms = &r;
        TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args);
        new_parms = &(TREE_CHAIN (*new_parms)),
@@ -6036,6 +6034,8 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
                   new_vec, NULL_TREE);
     }
 
+  --processing_template_decl;
+
   return r;
 }
 
@@ -6243,8 +6243,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        tmpl_args = DECL_CLASS_TEMPLATE_P (t)
          ? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
          : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
+       /* Because this is a template, the arguments will still be
+          dependent, even after substitution.  If
+          PROCESSING_TEMPLATE_DECL is not set, the dependency
+          predicates will short-circuit.  */
+       ++processing_template_decl;
        full_args = tsubst_template_args (tmpl_args, args,
                                          complain, in_decl);
+       --processing_template_decl;
        if (full_args == error_mark_node)
          return error_mark_node;
 
@@ -6270,15 +6276,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        gcc_assert (DECL_LANG_SPECIFIC (r) != 0);
        TREE_CHAIN (r) = NULL_TREE;
 
-       DECL_CONTEXT (r)
-         = tsubst_aggr_type (DECL_CONTEXT (t), args,
-                             complain, in_decl,
-                             /*entering_scope=*/1);
        DECL_TEMPLATE_INFO (r) = build_tree_list (t, args);
 
        if (TREE_CODE (decl) == TYPE_DECL)
          {
-           tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+           tree new_type;
+           ++processing_template_decl;
+           new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+           --processing_template_decl; 
            if (new_type == error_mark_node)
              return error_mark_node;
 
@@ -6286,10 +6291,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            CLASSTYPE_TI_TEMPLATE (new_type) = r;
            DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
            DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type);
+           DECL_CONTEXT (r) = TYPE_CONTEXT (new_type);
          }
        else
          {
-           tree new_decl = tsubst (decl, args, complain, in_decl);
+           tree new_decl;
+           ++processing_template_decl;
+           new_decl = tsubst (decl, args, complain, in_decl);
+           --processing_template_decl;
            if (new_decl == error_mark_node)
              return error_mark_node;
 
@@ -6297,6 +6306,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            DECL_TI_TEMPLATE (new_decl) = r;
            TREE_TYPE (r) = TREE_TYPE (new_decl);
            DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl);
+           DECL_CONTEXT (r) = DECL_CONTEXT (new_decl); 
          }
 
        SET_DECL_IMPLICIT_INSTANTIATION (r);
@@ -6924,39 +6934,6 @@ tsubst_exception_specification (tree fntype,
   return new_specs;
 }
 
-/* Substitute into the PARMS of a call-declarator.  */
-
-static tree
-tsubst_call_declarator_parms (tree parms,
-                             tree args,
-                             tsubst_flags_t complain,
-                             tree in_decl)
-{
-  tree new_parms;
-  tree type;
-  tree defarg;
-
-  if (!parms || parms == void_list_node)
-    return parms;
-
-  new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms),
-                                           args, complain, in_decl);
-
-  /* Figure out the type of this parameter.  */
-  type = tsubst (TREE_VALUE (parms), args, complain, in_decl);
-
-  /* Figure out the default argument as well.  Note that we use
-     tsubst_expr since the default argument is really an expression.  */
-  defarg = tsubst_expr (TREE_PURPOSE (parms), args, complain, in_decl);
-
-  /* Chain this parameter on to the front of those we have already
-     processed.  We don't use hash_tree_cons because that function
-     doesn't check TREE_PARMLIST.  */
-  new_parms = tree_cons (defarg, type, new_parms);
-
-  return new_parms;
-}
-
 /* Take the tree structure T and replace template parameters used
    therein with the argument vector ARGS.  IN_DECL is an associated
    decl for diagnostics.  If an error occurs, returns ERROR_MARK_NODE.
@@ -7041,25 +7018,24 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        max = tsubst_template_arg (omax, args, complain, in_decl);
        max = fold_decl_constant_value (max);
 
-       if (integer_zerop (omax))
-         {
-           /* Still allow an explicit array of size zero.  */
-           if (pedantic)
-             pedwarn ("creating array with size zero");
-         }
-       else if (integer_zerop (max)
-                || (TREE_CODE (max) == INTEGER_CST
-                    && INT_CST_LT (max, integer_zero_node)))
-         {
-           /* [temp.deduct]
+       /* [temp.deduct]
 
-              Type deduction may fail for any of the following
-              reasons:
+          Type deduction may fail for any of the following
+          reasons:
+
+            Attempting to create an array with a size that is
+            zero or negative.  */
+       if (integer_zerop (max) && !(complain & tf_error))
+         /* We must fail if performing argument deduction (as
+            indicated by the state of complain), so that
+            another substitution can be found.  */
+         return error_mark_node;
 
-                Attempting to create an array with a size that is
-                zero or negative.  */
+       else if (TREE_CODE (max) == INTEGER_CST
+                && INT_CST_LT (max, integer_zero_node))
+         {
            if (complain & tf_error)
-             error ("creating array with size zero (%qE)", max);
+             error ("creating array with negative size (%qE)", max);
 
            return error_mark_node;
          }
@@ -7527,7 +7503,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        if (e1 == error_mark_node || e2 == error_mark_node)
          return error_mark_node;
 
-       return build_nt (TREE_CODE (t), e1, e2);
+       return build_qualified_name (/*type=*/NULL_TREE,
+                                    e1, e2, QUALIFIED_NAME_IS_TEMPLATE (t));
       }
 
     case TYPEOF_TYPE:
@@ -7658,11 +7635,18 @@ tsubst_qualified_id (tree qualified_id, tree args,
     expr = name;
 
   if (dependent_type_p (scope))
-    return build_nt (SCOPE_REF, scope, expr);
+    return build_qualified_name (/*type=*/NULL_TREE, 
+                                scope, expr, 
+                                QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
 
   if (!BASELINK_P (name) && !DECL_P (expr))
     {
-      expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+      if (TREE_CODE (expr) == BIT_NOT_EXPR)
+       /* If this were actually a destructor call, it would have been
+          parsed as such by the parser.  */
+       expr = error_mark_node;
+      else
+       expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
       if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
                     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)
        {
@@ -7703,7 +7687,10 @@ tsubst_qualified_id (tree qualified_id, tree args,
     {
       expr = (adjust_result_of_qualified_name_lookup
              (expr, scope, current_class_type));
-      expr = finish_qualified_id_expr (scope, expr, done, address_p);
+      expr = (finish_qualified_id_expr 
+             (scope, expr, done, address_p,
+              QUALIFIED_NAME_IS_TEMPLATE (qualified_id),
+              /*template_arg_p=*/false));
     }
 
   if (TREE_CODE (expr) != SCOPE_REF)
@@ -7890,7 +7877,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            name = tsubst_copy (TREE_OPERAND (name, 0), args,
                                complain, in_decl);
            name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
-           name = build_nt (SCOPE_REF, base, name);
+           name = build_qualified_name (/*type=*/NULL_TREE,
+                                        base, name, 
+                                        /*template_p=*/false);
          }
        else if (TREE_CODE (name) == BASELINK)
          name = tsubst_baselink (name,
@@ -7932,7 +7921,6 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case LT_EXPR:
     case GT_EXPR:
     case COMPOUND_EXPR:
-    case SCOPE_REF:
     case DOTSTAR_EXPR:
     case MEMBER_REF:
     case PREDECREMENT_EXPR:
@@ -7943,6 +7931,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
        (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
         tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
 
+    case SCOPE_REF:
+      return build_qualified_name (/*type=*/NULL_TREE,
+                                  tsubst_copy (TREE_OPERAND (t, 0),
+                                               args, complain, in_decl),
+                                  tsubst_copy (TREE_OPERAND (t, 1),
+                                               args, complain, in_decl),
+                                  QUALIFIED_NAME_IS_TEMPLATE (t));
+
     case ARRAY_REF:
       return build_nt
        (ARRAY_REF,
@@ -8070,11 +8066,48 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
         in response to the saved STMT_IS_FULL_EXPR_P setting.  */
       gcc_unreachable ();
 
+    case OFFSET_REF:
+      mark_used (TREE_OPERAND (t, 1));
+      return t;
+
     default:
       return t;
     }
 }
 
+/* Like tsubst_copy_and_build, but unshare TREE_LIST nodes.  */
+
+static tree
+tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
+                         tree in_decl)
+{
+#define RECUR(t) tsubst_copy_asm_operands (t, args, complain, in_decl)
+
+  tree purpose, value, chain;
+
+  if (t == NULL)
+    return t;
+
+  if (TREE_CODE (t) != TREE_LIST)
+    return tsubst_copy_and_build (t, args, complain, in_decl,
+                                 /*function_p=*/false);
+
+  if (t == void_list_node)
+    return t;
+
+  purpose = TREE_PURPOSE (t);
+  if (purpose)
+    purpose = RECUR (purpose);
+  value = TREE_VALUE (t);
+  if (value)
+    value = RECUR (value);
+  chain = TREE_CHAIN (t);
+  if (chain && chain != void_type_node)
+    chain = RECUR (chain);
+  return tree_cons (purpose, value, chain);
+#undef RECUR
+}
+
 /* Like tsubst_copy for expressions, etc. but also does semantic
    processing.  */
 
@@ -8292,9 +8325,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       tmp = finish_asm_stmt
        (ASM_VOLATILE_P (t),
         tsubst_expr (ASM_STRING (t), args, complain, in_decl),
-        tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
-        tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
-        tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl));
+        tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
+        tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
+        tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl));
       {
        tree asm_expr = tmp;
        if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
@@ -8416,7 +8449,6 @@ tsubst_copy_and_build (tree t,
       {
        tree decl;
        cp_id_kind idk;
-       tree qualifying_class;
        bool non_integral_constant_expression_p;
        const char *error_msg;
 
@@ -8427,7 +8459,7 @@ tsubst_copy_and_build (tree t,
          }
 
        /* Look up the name.  */
-       decl = lookup_name (t, 0);
+       decl = lookup_name (t);
 
        /* By convention, expressions use ERROR_MARK_NODE to indicate
           failure, not NULL_TREE.  */
@@ -8436,10 +8468,13 @@ tsubst_copy_and_build (tree t,
 
        decl = finish_id_expression (t, decl, NULL_TREE,
                                     &idk,
-                                    &qualifying_class,
                                     /*integral_constant_expression_p=*/false,
                                     /*allow_non_integral_constant_expression_p=*/false,
                                     &non_integral_constant_expression_p,
+                                    /*template_p=*/false,
+                                    /*done=*/true,
+                                    /*address_p=*/false,
+                                    /*template_arg_p=*/false,
                                     &error_msg);
        if (error_msg)
          error (error_msg);
@@ -8681,9 +8716,17 @@ tsubst_copy_and_build (tree t,
          }
        else
          {
-           qualified_p = (TREE_CODE (function) == COMPONENT_REF
-                          && (TREE_CODE (TREE_OPERAND (function, 1))
-                              == SCOPE_REF));
+           if (TREE_CODE (function) == COMPONENT_REF)
+             {
+               tree op = TREE_OPERAND (function, 1);
+
+               qualified_p = (TREE_CODE (op) == SCOPE_REF
+                              || (BASELINK_P (op)
+                                  && BASELINK_QUALIFIED_P (op)));
+             }
+           else
+             qualified_p = false;
+           
            function = tsubst_copy_and_build (function, args, complain,
                                              in_decl,
                                              !qualified_p);
@@ -8773,6 +8816,7 @@ tsubst_copy_and_build (tree t,
     case COMPONENT_REF:
       {
        tree object;
+       tree object_type;
        tree member;
 
        object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
@@ -8780,6 +8824,7 @@ tsubst_copy_and_build (tree t,
        /* Remember that there was a reference to this entity.  */
        if (DECL_P (object))
          mark_used (object);
+       object_type = TREE_TYPE (object);
 
        member = TREE_OPERAND (t, 1);
        if (BASELINK_P (member))
@@ -8788,20 +8833,20 @@ tsubst_copy_and_build (tree t,
                                    args, complain, in_decl);
        else
          member = tsubst_copy (member, args, complain, in_decl);
-
        if (member == error_mark_node)
          return error_mark_node;
-       else if (!CLASS_TYPE_P (TREE_TYPE (object)))
+
+       if (object_type && !CLASS_TYPE_P (object_type))
          {
            if (TREE_CODE (member) == BIT_NOT_EXPR)
              return finish_pseudo_destructor_expr (object,
                                                    NULL_TREE,
-                                                   TREE_TYPE (object));
+                                                   object_type);
            else if (TREE_CODE (member) == SCOPE_REF
                     && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
              return finish_pseudo_destructor_expr (object,
                                                    object,
-                                                   TREE_TYPE (object));
+                                                   object_type);
          }
        else if (TREE_CODE (member) == SCOPE_REF
                 && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
@@ -8823,12 +8868,11 @@ tsubst_copy_and_build (tree t,
                              args);
                member = (adjust_result_of_qualified_name_lookup
                          (member, BINFO_TYPE (BASELINK_BINFO (member)),
-                          TREE_TYPE (object)));
+                          object_type));
              }
            else
              {
-               qualified_name_lookup_error (TREE_TYPE (object), tmpl,
-                                            member);
+               qualified_name_lookup_error (object_type, tmpl, member);
                return error_mark_node;
              }
          }
@@ -8850,7 +8894,8 @@ tsubst_copy_and_build (tree t,
        else if (TREE_CODE (member) == FIELD_DECL)
          return finish_non_static_data_member (member, object, NULL_TREE);
 
-       return finish_class_member_access_expr (object, member);
+       return finish_class_member_access_expr (object, member,
+                                               /*template_p=*/false);
       }
 
     case THROW_EXPR:
@@ -8985,14 +9030,15 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
 
          if (nt)
            {
-             /* DR 488 makes use of a type with no linkage causes
+             /* DR 488 makes use of a type with no linkage cause
                 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);
+                   error ("template argument for %qD uses local type %qT",
+                           tmpl, t);
                }
              result = true;
            }
@@ -9092,6 +9138,8 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
   /* Substitute template parameters.  */
   fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
                   targ_ptr, complain, gen_tmpl);
+  if (fndecl == error_mark_node)
+    return error_mark_node;
 
   /* Now we know the specialization, compute access previously
      deferred.  */
@@ -9658,34 +9706,6 @@ try_one_overload (tree tparms,
   return 1;
 }
 
-/* Verify that nondeduce template argument agrees with the type
-   obtained from argument deduction.  Return nonzero if the
-   verification fails.
-
-   For example:
-
-     struct A { typedef int X; };
-     template <class T, class U> struct C {};
-     template <class T> struct C<T, typename T::X> {};
-
-   Then with the instantiation `C<A, int>', we can deduce that
-   `T' is `A' but unify () does not check whether `typename T::X'
-   is `int'.  This function ensure that they agree.
-
-   TARGS, PARMS are the same as the arguments of unify.
-   ARGS contains template arguments from all levels.  */
-
-static int
-verify_class_unification (tree targs, tree parms, tree args)
-{
-  parms = tsubst (parms, add_outermost_template_args (args, targs),
-                 tf_none, NULL_TREE);
-  if (parms == error_mark_node)
-    return 1;
-
-  return !comp_template_args (parms, INNERMOST_TEMPLATE_ARGS (args));
-}
-
 /* PARM is a template class (perhaps with unbound template
    parameters).  ARG is a fully instantiated type.  If ARG can be
    bound to PARM, return ARG, otherwise return NULL_TREE.  TPARMS and
@@ -9848,9 +9868,18 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
   return 1;
 }
 
-/* Takes parameters as for type_unification.  Returns 0 if the
-   type deduction succeeds, 1 otherwise.  The parameter STRICT is a
-   bitwise or of the following flags:
+/* Deduce the value of template parameters.  TPARMS is the (innermost)
+   set of template parameters to a template.  TARGS is the bindings
+   for those template parameters, as determined thus far; TARGS may
+   include template arguments for outer levels of template parameters
+   as well.  PARM is a parameter to a template function, or a
+   subcomponent of that parameter; ARG is the corresponding argument.
+   This function attempts to match PARM with ARG in a manner
+   consistent with the existing assignments in TARGS.  If more values
+   are deduced, then TARGS is updated.
+
+   Returns 0 if the type deduction succeeds, 1 otherwise.  The
+   parameter STRICT is a bitwise or of the following flags:
 
      UNIFY_ALLOW_NONE:
        Require an exact match between PARM and ARG.
@@ -9955,7 +9984,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
        return (TREE_CODE (arg) == TREE_CODE (parm)
                && same_type_p (parm, arg)) ? 0 : 1;
       idx = TEMPLATE_TYPE_IDX (parm);
-      targ = TREE_VEC_ELT (targs, idx);
+      targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
       tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
 
       /* Check for mixed types and values.  */
@@ -10056,7 +10085,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
            return 1;
        }
 
-      TREE_VEC_ELT (targs, idx) = arg;
+      TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return 0;
 
     case TEMPLATE_PARM_INDEX:
@@ -10070,7 +10099,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
                 && cp_tree_equal (parm, arg));
 
       idx = TEMPLATE_PARM_IDX (parm);
-      targ = TREE_VEC_ELT (targs, idx);
+      targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
 
       if (targ)
        return !cp_tree_equal (targ, arg);
@@ -10104,7 +10133,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       else
        return 1;
 
-      TREE_VEC_ELT (targs, idx) = arg;
+      TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
       return 0;
 
     case PTRMEM_CST:
@@ -10629,33 +10658,44 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   return (better1 > 0) - (better2 > 0);
 }
 
-/* Given two class template specialization list nodes PAT1 and PAT2, return:
+/* Determine which of two partial specializations is more specialized.
 
-   1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-   -1 if PAT2 is more specialized than PAT1.
-   0 if neither is more specialized.
+   PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding
+   to the first partial specialization.  The TREE_VALUE is the
+   innermost set of template parameters for the partial
+   specialization.  PAT2 is similar, but for the second template.
 
-   FULL_ARGS is the full set of template arguments that triggers this
-   partial ordering.  */
+   Return 1 if the first partial specialization is more specialized;
+   -1 if the second is more specialized; 0 if neither is more
+   specialized.
 
-int
-more_specialized_class (tree pat1, tree pat2, tree full_args)
+   See [temp.class.order] for information about determining which of
+   two templates is more specialized.  */ 
+
+static int
+more_specialized_class (tree pat1, tree pat2)
 {
   tree targs;
+  tree tmpl1, tmpl2;
   int winner = 0;
 
+  tmpl1 = TREE_TYPE (pat1);
+  tmpl2 = TREE_TYPE (pat2);
+
   /* Just like what happens for functions, if we are ordering between
      different class template specializations, we may encounter dependent
      types in the arguments, and we need our dependency check functions
      to behave correctly.  */
   ++processing_template_decl;
-  targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
-                             add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
+  targs = get_class_bindings (TREE_VALUE (pat1), 
+                             CLASSTYPE_TI_ARGS (tmpl1),
+                             CLASSTYPE_TI_ARGS (tmpl2));
   if (targs)
     --winner;
 
-  targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
-                             add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
+  targs = get_class_bindings (TREE_VALUE (pat2), 
+                             CLASSTYPE_TI_ARGS (tmpl2),
+                             CLASSTYPE_TI_ARGS (tmpl1));
   if (targs)
     ++winner;
   --processing_template_decl;
@@ -10730,49 +10770,81 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
      template <class T> struct S<T*, int> {};
 
    Then, suppose we want to get `S<double*, int>'.  The TPARMS will be
-   {T}, the PARMS will be {T*, int} and the ARGS will be {double*,
+   {T}, the SPEC_ARGS will be {T*, int} and the ARGS will be {double*,
    int}.  The resulting vector will be {double}, indicating that `T'
    is bound to `double'.  */
 
 static tree
-get_class_bindings (tree tparms, tree parms, tree args)
+get_class_bindings (tree tparms, tree spec_args, tree args)
 {
   int i, ntparms = TREE_VEC_LENGTH (tparms);
-  tree vec = make_tree_vec (ntparms);
+  tree deduced_args;
+  tree innermost_deduced_args;
+
+  innermost_deduced_args = make_tree_vec (ntparms);
+  if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+    {
+      deduced_args = copy_node (args);
+      SET_TMPL_ARGS_LEVEL (deduced_args,
+                          TMPL_ARGS_DEPTH (deduced_args),
+                          innermost_deduced_args);
+    }
+  else
+    deduced_args = innermost_deduced_args; 
 
-  if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args),
+  if (unify (tparms, deduced_args, 
+            INNERMOST_TEMPLATE_ARGS (spec_args), 
+            INNERMOST_TEMPLATE_ARGS (args), 
             UNIFY_ALLOW_NONE))
     return NULL_TREE;
 
   for (i =  0; i < ntparms; ++i)
-    if (! TREE_VEC_ELT (vec, i))
+    if (! TREE_VEC_ELT (innermost_deduced_args, i))
       return NULL_TREE;
 
-  if (verify_class_unification (vec, parms, args))
+  /* Verify that nondeduced template arguments agree with the type
+     obtained from argument deduction.
+     
+     For example:
+
+       struct A { typedef int X; };
+       template <class T, class U> struct C {};
+       template <class T> struct C<T, typename T::X> {};
+
+     Then with the instantiation `C<A, int>', we can deduce that
+     `T' is `A' but unify () does not check whether `typename T::X'
+     is `int'.  */
+  spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
+  if (spec_args == error_mark_node
+      /* We only need to check the innermost arguments; the other
+        arguments will always agree.  */
+      || !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args),
+                             INNERMOST_TEMPLATE_ARGS (args)))
     return NULL_TREE;
 
-  return vec;
+  return deduced_args;
 }
 
-/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
-   Pick the most specialized template, and return the corresponding
-   instantiation, or if there is no corresponding instantiation, the
-   template itself.  If there is no most specialized template,
-   error_mark_node is returned.  If there are no templates at all,
-   NULL_TREE is returned.  */
+/* TEMPLATES is a TREE_LIST.  Each TREE_VALUE is a TEMPLATE_DECL.
+   Return the TREE_LIST node with the most specialized template, if
+   any.  If there is no most specialized template, the error_mark_node
+   is returned.
+
+   Note that this function does not look at, or modify, the
+   TREE_PURPOSE or TREE_TYPE of any of the nodes.  Since the node
+   returned is one of the elements of INSTANTIATIONS, callers may
+   store information in the TREE_PURPOSE or TREE_TYPE of the nodes,
+   and retrieve it from the value returned.  */
 
 tree
-most_specialized_instantiation (tree instantiations)
+most_specialized_instantiation (tree templates)
 {
   tree fn, champ;
 
-  if (!instantiations)
-    return NULL_TREE;
-
   ++processing_template_decl;
 
-  champ = instantiations;
-  for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
+  champ = templates;
+  for (fn = TREE_CHAIN (templates); fn; fn = TREE_CHAIN (fn))
     {
       int fate = 0;
 
@@ -10786,20 +10858,23 @@ most_specialized_instantiation (tree instantiations)
                        NULL_TREE, /*check_ret=*/false))
        fate++;
 
-      if (fate != 1)
+      if (fate == -1)
+       champ = fn;
+      else if (!fate)
        {
-         if (!fate)
-           /* Equally specialized, move to next function.  If there
-              is no next function, nothing's most specialized.  */
-           fn = TREE_CHAIN (fn);
+         /* Equally specialized, move to next function.  If there
+            is no next function, nothing's most specialized.  */
+         fn = TREE_CHAIN (fn);
          champ = fn;
+         if (!fn)
+           break;
        }
     }
 
   if (champ)
     /* Now verify that champ is better than everything earlier in the
        instantiation list.  */
-    for (fn = instantiations; fn != champ; fn = TREE_CHAIN (fn))
+    for (fn = templates; fn != champ; fn = TREE_CHAIN (fn))
       if (get_bindings (TREE_VALUE (champ),
                        DECL_TEMPLATE_RESULT (TREE_VALUE (fn)),
                        NULL_TREE, /*check_ret=*/false)
@@ -10816,29 +10891,7 @@ most_specialized_instantiation (tree instantiations)
   if (!champ)
     return error_mark_node;
 
-  return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ);
-}
-
-/* Return the most specialized of the list of templates in FNS that can
-   produce an instantiation matching DECL, given the explicit template
-   arguments EXPLICIT_ARGS.  */
-
-static tree
-most_specialized (tree fns, tree decl, tree explicit_args)
-{
-  tree candidates = NULL_TREE;
-  tree fn, args;
-
-  for (fn = fns; fn; fn = TREE_CHAIN (fn))
-    {
-      tree candidate = TREE_VALUE (fn);
-
-      args = get_bindings (candidate, decl, explicit_args, /*check_ret=*/true);
-      if (args)
-       candidates = tree_cons (NULL_TREE, candidate, candidates);
-    }
-
-  return most_specialized_instantiation (candidates);
+  return champ;
 }
 
 /* If DECL is a specialization of some template, return the most
@@ -10899,26 +10952,42 @@ most_general_template (tree decl)
   return decl;
 }
 
-/* Return the most specialized of the class template specializations
-   of TMPL which can produce an instantiation matching ARGS, or
-   error_mark_node if the choice is ambiguous.  */
+/* Return the most specialized of the class template partial
+   specializations of TMPL which can produce TYPE, a specialization of
+   TMPL.  The value returned is actually a TREE_LIST; the TREE_TYPE is
+   a _TYPE node corresponding to the partial specialization, while the
+   TREE_PURPOSE is the set of template arguments that must be
+   substituted into the TREE_TYPE in order to generate TYPE.
+
+   If the choice of partial specialization is ambiguous, a diagnostic
+   is issued, and the error_mark_node is returned.  If there are no
+   partial specializations of TMPL matching TYPE, then NULL_TREE is
+   returned.  */
 
 static tree
-most_specialized_class (tree tmpl, tree args)
+most_specialized_class (tree type, tree tmpl)
 {
   tree list = NULL_TREE;
   tree t;
   tree champ;
   int fate;
+  bool ambiguous_p;
+  tree args;
 
   tmpl = most_general_template (tmpl);
+  args = CLASSTYPE_TI_ARGS (type);
   for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t))
     {
-      tree spec_args
-       = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args);
+      tree partial_spec_args;
+      tree spec_args;
+
+      partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
+      spec_args = get_class_bindings (TREE_VALUE (t), 
+                                     partial_spec_args, 
+                                     args);
       if (spec_args)
        {
-         list = tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list);
+         list = tree_cons (spec_args, TREE_VALUE (t), list);
          TREE_TYPE (list) = TREE_TYPE (t);
        }
     }
@@ -10926,12 +10995,13 @@ most_specialized_class (tree tmpl, tree args)
   if (! list)
     return NULL_TREE;
 
+  ambiguous_p = false;
   t = list;
   champ = t;
   t = TREE_CHAIN (t);
   for (; t; t = TREE_CHAIN (t))
     {
-      fate = more_specialized_class (champ, t, args);
+      fate = more_specialized_class (champ, t);
       if (fate == 1)
        ;
       else
@@ -10940,17 +11010,36 @@ most_specialized_class (tree tmpl, tree args)
            {
              t = TREE_CHAIN (t);
              if (! t)
-               return error_mark_node;
+               {
+                 ambiguous_p = true;
+                 break;
+               }
            }
          champ = t;
        }
     }
 
-  for (t = list; t && t != champ; t = TREE_CHAIN (t))
+  if (!ambiguous_p)
+    for (t = list; t && t != champ; t = TREE_CHAIN (t))
+      {
+       fate = more_specialized_class (champ, t);
+       if (fate != 1)
+         {
+           ambiguous_p = true;
+           break;
+         }
+      }
+
+  if (ambiguous_p)
     {
-      fate = more_specialized_class (champ, t, args);
-      if (fate != 1)
-       return error_mark_node;
+      const char *str = "candidates are:";
+      error ("ambiguous class template instantiation for %q#T", type);
+      for (t = list; t; t = TREE_CHAIN (t))
+       {
+         error ("%s %+#T", str, TREE_TYPE (t));
+         str = "               ";
+       }
+      return error_mark_node;
     }
 
   return champ;
@@ -11064,7 +11153,7 @@ do_decl_instantiation (tree decl, tree storage)
                      /*expl_inst_class_mem_p=*/false);
 }
 
-void
+static void
 mark_class_instantiated (tree t, int extern_p)
 {
   SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
@@ -11460,6 +11549,10 @@ instantiate_decl (tree d, int defer_ok,
   td = template_for_substitution (d);
   code_pattern = DECL_TEMPLATE_RESULT (td);
 
+  /* We should never be trying to instantiate a member of a class
+     template or partial specialization.  */ 
+  gcc_assert (d != code_pattern);
   if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
       || DECL_TEMPLATE_SPECIALIZATION (td))
     /* In the case of a friend template whose definition is provided
@@ -11569,10 +11662,9 @@ instantiate_decl (tree d, int defer_ok,
          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);
+         DECL_INITIAL (d) = init;
+         cp_finish_decl (d, init, /*asmspec_tree=*/NULL_TREE,
+                         LOOKUP_ONLYCONVERTING);
          pop_nested_class ();
          pop_nested_namespace (ns);
        }
@@ -11736,10 +11828,15 @@ instantiate_pending_templates (int retries)
      to avoid infinite loop.  */
   if (pending_templates && retries >= max_tinst_depth)
     {
+      tree decl = 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));
+            " instantiating %q+D, possibly from virtual table generation"
+            " (use -ftemplate-depth-NN to increase the maximum)",
+            max_tinst_depth, decl);
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+       /* Pretend that we defined it.  */
+       DECL_INITIAL (decl) = error_mark_node;
       return;
     }
 
This page took 0.076806 seconds and 5 git commands to generate.