pt.c (push_template_decl_real): Generalize check for incorrect number of template...
authorJason Merrill <jason@yorick.cygnus.com>
Thu, 29 Oct 1998 02:27:55 +0000 (02:27 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 29 Oct 1998 02:27:55 +0000 (21:27 -0500)
* pt.c (push_template_decl_real): Generalize check for incorrect
number of template parms.

From-SVN: r23422

gcc/cp/ChangeLog
gcc/cp/pt.c

index 4ae7b594275c907a9746dbe17b1d7cfdbd98e41a..64fa422843560b9d5bbe5fecc3e798196066a9df 100644 (file)
@@ -1,3 +1,8 @@
+1998-10-29  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (push_template_decl_real): Generalize check for incorrect
+       number of template parms.
+
 1998-10-29  Richard Henderson  <rth@cygnus.com>
 
        * Makefile.in (cc1plus): Put CXX_OBJS, and thence @extra_cxx_objs@,
index f232c6018fb369e588e6077205431a2030cb713f..71d080bde65125248317384f2811db5c622aeab6 100644 (file)
@@ -2166,8 +2166,8 @@ push_template_decl_real (decl, is_friend)
     }
   else
     {
-      tree t;
-      tree a;
+      tree a, t, current, parms;
+      int mem, i;
 
       if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
        cp_error ("must specialize `%#T' before defining member `%#D'",
@@ -2193,75 +2193,68 @@ push_template_decl_real (decl, is_friend)
       else
        tmpl = DECL_TI_TEMPLATE (decl);
       
-      if (is_member_template (tmpl) || is_member_template_class (tmpl))
+      if (is_member_template (tmpl)
+         && DECL_FUNCTION_TEMPLATE_P (tmpl)
+         && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) 
+         && DECL_TEMPLATE_SPECIALIZATION (decl))
        {
-         if (DECL_FUNCTION_TEMPLATE_P (tmpl)
-             && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) 
-             && DECL_TEMPLATE_SPECIALIZATION (decl))
-           {
-             tree new_tmpl;
-
-             /* The declaration is a specialization of a member
-                template, declared outside the class.  Therefore, the
-                innermost template arguments will be NULL, so we
-                replace them with the arguments determined by the
-                earlier call to check_explicit_specialization.  */
-             args = DECL_TI_ARGS (decl);
-
-             new_tmpl 
-               = build_template_decl (decl, current_template_parms);
-             DECL_TEMPLATE_RESULT (new_tmpl) = decl;
-             TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
-             DECL_TI_TEMPLATE (decl) = new_tmpl;
-             SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
-             DECL_TEMPLATE_INFO (new_tmpl) = 
-               perm_tree_cons (tmpl, args, NULL_TREE);
-
-             register_specialization (new_tmpl, tmpl, args);
-             return decl;
-           }
-         
-         a = innermost_args (args);
-         t = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
-         if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
-           {
-             cp_error ("got %d template parameters for `%#D'",
-                       TREE_VEC_LENGTH (a), decl);
-             cp_error ("  but %d required", TREE_VEC_LENGTH (t));
-           }
-         if (TMPL_ARGS_DEPTH (args) > 1)
-           /* Get the template parameters for the enclosing template
-              class.  */ 
-           a = TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args) - 1);
-         else
-           a = NULL_TREE;
+         tree new_tmpl;
+
+         /* The declaration is a specialization of a member
+            template, declared outside the class.  Therefore, the
+            innermost template arguments will be NULL, so we
+            replace them with the arguments determined by the
+            earlier call to check_explicit_specialization.  */
+         args = DECL_TI_ARGS (decl);
+
+         new_tmpl 
+           = build_template_decl (decl, current_template_parms);
+         DECL_TEMPLATE_RESULT (new_tmpl) = decl;
+         TREE_TYPE (new_tmpl) = TREE_TYPE (decl);
+         DECL_TI_TEMPLATE (decl) = new_tmpl;
+         SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl);
+         DECL_TEMPLATE_INFO (new_tmpl) = 
+           perm_tree_cons (tmpl, args, NULL_TREE);
+
+         register_specialization (new_tmpl, tmpl, args);
+         return decl;
        }
-      else 
-       a = innermost_args (args);
 
-      t = NULL_TREE;
+      /* Make sure the template headers we got make sense.  */
 
-      if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
+      mem = (is_member_template (tmpl) || is_member_template_class (tmpl));
+      parms = DECL_TEMPLATE_PARMS (tmpl);
+      i = TMPL_PARMS_DEPTH (parms);
+      if (TMPL_ARGS_DEPTH (args) != i)
        {
-         /* When processing an inline member template of a
-            specialized class, there is no CLASSTYPE_TI_SPEC_INFO.  */
-         if (CLASSTYPE_TI_SPEC_INFO (ctx))
-           t = TREE_VALUE (CLASSTYPE_TI_SPEC_INFO (ctx));
+         cp_error ("expected %d levels of template parms for `%#D', got %d",
+                   i, decl, TMPL_ARGS_DEPTH (args));
        }
-      else if (CLASSTYPE_TEMPLATE_INFO (ctx))
-       t = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (ctx));
+      else
+       for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
+         {
+           a = TMPL_ARGS_LEVEL (args, i);
+           t = INNERMOST_TEMPLATE_PARMS (parms);
+
+           if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
+             {
+               if (current == decl)
+                 cp_error ("got %d template parameters for `%#D'",
+                           TREE_VEC_LENGTH (a), decl);
+               else
+                 cp_error ("got %d template parameters for `%#T'",
+                           TREE_VEC_LENGTH (a), current);
+               cp_error ("  but %d required", TREE_VEC_LENGTH (t));
+             }
 
-      /* There should be template arguments if and only if there is a
-        template class.  */
-      my_friendly_assert((a != NULL_TREE) == (t != NULL_TREE), 0);
+           /* Perhaps we should also check that the parms are used in the
+               appropriate qualifying scopes in the declarator?  */
 
-      if (t != NULL_TREE 
-         && TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
-       {
-         cp_error ("got %d template parameters for `%#D'",
-                   TREE_VEC_LENGTH (a), decl);
-         cp_error ("  but `%#T' has %d", ctx, TREE_VEC_LENGTH (t));
-       }
+           if (current == decl)
+             current = ctx;
+           else
+             current = TYPE_CONTEXT (current);
+         }
     }
 
   DECL_TEMPLATE_RESULT (tmpl) = decl;