cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.
authorJason Merrill <jason@gcc.gnu.org>
Sun, 15 Mar 1998 19:53:08 +0000 (14:53 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 15 Mar 1998 19:53:08 +0000 (14:53 -0500)
* cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.
* pt.c (inline_needs_template_parms): New fn.
(original_template): New fn.
(push_inline_template_parms_recursive): New fn.
(maybe_begin_member_template_processing): Use them.
(maybe_end_member_template_processing): Likewise.
(is_member_or_friend_template): Rename to is_member_template.
Member functions of local classes are never member templates.
* lex.c (do_identifier): Handle TEMPLATE_DECL that was
added in the class scope to catch redefinition error.
* pt.c (reduce_template_parm_level): Also copy
the DECL_TEMPLATE_PARMS field.

From-SVN: r18595

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/lex.c
gcc/cp/pt.c

index 84ea33f0a630802a23f231c87e0d15cd54d911de..9b47256da9c276faf21e17a57313a1368e324bd6 100644 (file)
@@ -1,3 +1,22 @@
+Sun Mar 15 02:07:26 1998  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro.
+       * pt.c (inline_needs_template_parms): New fn.
+       (original_template): New fn.
+       (push_inline_template_parms_recursive): New fn.
+       (maybe_begin_member_template_processing): Use them.
+       (maybe_end_member_template_processing): Likewise.
+       (is_member_or_friend_template): Rename to is_member_template.
+       Member functions of local classes are never member templates.
+
+Sun Mar 15 01:14:22 1998  Kriang Lerdsuwanakij  <lerdsuwa@scf.usc.edu>
+
+       * lex.c (do_identifier): Handle TEMPLATE_DECL that was
+       added in the class scope to catch redefinition error.
+
+       * pt.c (reduce_template_parm_level): Also copy 
+       the DECL_TEMPLATE_PARMS field.
+
 Sun Mar 15 10:54:08 1998  Mark Mitchell  <mmitchell@usa.net>
 
        * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a
@@ -15,7 +34,8 @@ Sun Mar 15 12:26:02 1998  Manfred Hollstein  <manfred@s-direktnet.de>
        
 Thu Mar 12 09:39:40 1998  Manfred Hollstein  <manfred@s-direktnet.de>
 
-       * lang-specs.h: Properly put brackets around array elements in initializer.
+       * lang-specs.h: Properly put brackets around array elements in 
+       initializer.
 
        * typeck.c (build_binary_op_nodefault): Correctly place parens around
        && and || in expression.
@@ -32,7 +52,8 @@ Thu Mar 12 09:26:04 1998  Manfred Hollstein  <manfred@s-direktnet.de>
        * except.c (do_unwind): #if 0 definition of unused variables fcall
        and next_pc.
 
-       * expr.c (extract_scalar_init): #if 0 prototype and function definition.
+       * expr.c (extract_scalar_init): #if 0 prototype and function 
+       definition.
 
        * init.c (expand_aggr_init_1): Remove unused variable init_type.
        (build_new_1): Remove unused variable t.
index 1cee86b813ff73586208295fbe0369dfd2fa83bb..0e9f9d844ef130f60140dc02d3a4b02c586cdd9d 100644 (file)
@@ -1157,6 +1157,8 @@ struct lang_decl
 #define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE))
 #define INNERMOST_TEMPLATE_PARMS(NODE)  TREE_VALUE(NODE)
 
+#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
+
 #define DECL_SAVED_TREE(NODE)          DECL_MEMFUNC_POINTER_TO (NODE)
 #define COMPOUND_STMT_NO_SCOPE(NODE)   TREE_LANG_FLAG_0 (NODE)
 #define NEW_EXPR_USE_GLOBAL(NODE)      TREE_LANG_FLAG_0 (NODE)
index b953f951d986ef4bb68672315fcc70b41800b2b8..26c9221c327959970b6f87783c1a0fdf7109efe9 100644 (file)
@@ -2811,7 +2811,8 @@ do_identifier (token, parsing)
           But we still want to return this value.  */
        id = lookup_field (current_class_type, token, 0, 0);
       else if (TREE_CODE (field) == VAR_DECL
-              || TREE_CODE (field) == CONST_DECL)
+              || TREE_CODE (field) == CONST_DECL
+              || TREE_CODE (field) == TEMPLATE_DECL)
        id = field;
       else if (TREE_CODE (field) != FIELD_DECL)
        my_friendly_abort (61);
index 9b67811680edc5dfe4790da8505ee39c56807e08..52a4254576355f14ac1b1ac7e4eaa77cc305f758 100644 (file)
@@ -86,7 +86,6 @@ static int  type_unification_real PROTO((tree, tree *, tree, tree,
 static void note_template_header PROTO((int));
 static tree maybe_fold_nontype_arg PROTO((tree));
 static tree convert_nontype_argument PROTO((tree, tree));
-static int is_member_or_friend_template PROTO((tree, int));
 
 /* Do any processing required when DECL (a member template declaration
    using TEMPLATE_PARAMETERS as its innermost parameter list) is
@@ -164,31 +163,60 @@ template_class_depth (type)
   return depth;
 }
 
-/* Restore the template parameter context for a member template or
-   a friend template defined in a class definition.  */
+/* Return the original template for this decl, disregarding any
+   specializations.  */
 
-void 
-maybe_begin_member_template_processing (decl)
+static tree
+original_template (decl)
      tree decl;
 {
-  tree parms;
-  int i;
+  while (DECL_TEMPLATE_INFO (decl))
+    decl = DECL_TI_TEMPLATE (decl);
+  return decl;
+}
 
-  if (!is_member_or_friend_template (decl, 1))
-    return;
+/* Returns 1 if processing DECL as part of do_pending_inlines
+   needs us to push template parms.  */
+
+static int
+inline_needs_template_parms (decl)
+     tree decl;
+{
+  if (! DECL_TEMPLATE_INFO (decl))
+    return 0;
+
+  return (list_length (DECL_TEMPLATE_PARMS (original_template (decl)))
+         > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl)));
+}
 
-  parms = DECL_INNERMOST_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl));
+/* Subroutine of maybe_begin_member_template_processing.
+   Push the template parms in PARMS, starting from LEVELS steps into the
+   chain, and ending at the beginning, since template parms are listed
+   innermost first.  */
+
+static void
+push_inline_template_parms_recursive (parmlist, levels)
+     tree parmlist;
+     int levels;
+{
+  tree parms = TREE_VALUE (parmlist);
+  int i;
+
+  if (levels > 1)
+    push_inline_template_parms_recursive (TREE_CHAIN (parmlist), levels - 1);
 
   ++processing_template_decl;
-  current_template_parms 
+  current_template_parms
     = tree_cons (build_int_2 (0, processing_template_decl),
                 parms, current_template_parms);
+  TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
+
   pushlevel (0);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) 
     {
       tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0);
-      
+
       switch (TREE_CODE (parm))
        {
        case TYPE_DECL:
@@ -204,7 +232,7 @@ maybe_begin_member_template_processing (decl)
            DECL_INITIAL (decl) = DECL_INITIAL (parm);
            pushdecl (decl);
          }
-       break;
+         break;
 
        default:
          my_friendly_abort (0);
@@ -212,25 +240,51 @@ maybe_begin_member_template_processing (decl)
     }
 }
 
+/* Restore the template parameter context for a member template or
+   a friend template defined in a class definition.  */
+
+void
+maybe_begin_member_template_processing (decl)
+     tree decl;
+{
+  tree parms;
+  int levels;
+
+  if (! inline_needs_template_parms (decl))
+    return;
+
+  parms = DECL_TEMPLATE_PARMS (original_template (decl));
+
+  levels = list_length (parms) - processing_template_decl;
+
+  if (DECL_TEMPLATE_SPECIALIZATION (decl))
+    {
+      --levels;
+      parms = TREE_CHAIN (parms);
+    }
+
+  push_inline_template_parms_recursive (parms, levels);
+}
+
 /* Undo the effects of begin_member_template_processing. */
 
 void 
 maybe_end_member_template_processing (decl)
      tree decl;
 {
-  if (!is_member_or_friend_template (decl, 1))
-    return;
-
   if (! processing_template_decl)
     return;
 
-  --processing_template_decl;
-  current_template_parms = TREE_CHAIN (current_template_parms);
-  poplevel (0, 0, 0);
+  while (current_template_parms
+        && TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
+    {
+      --processing_template_decl;
+      current_template_parms = TREE_CHAIN (current_template_parms);
+      poplevel (0, 0, 0);
+    }
 }
 
-/* Returns non-zero iff T is a member template function, or, if
-   ALLOW_FRIEND is non-zero, a friend template function.  We must be
+/* Returns non-zero iff T is a member template function.  We must be
    careful as in
 
      template <class T> class C { void f(); }
@@ -244,10 +298,9 @@ maybe_end_member_template_processing (decl)
    then neither C<int>::f<char> nor C<T>::f<double> is considered
    to be a member template.  */
 
-static int
-is_member_or_friend_template (t, allow_friend)
+int
+is_member_template (t)
      tree t;
-     int allow_friend;
 {
   if (TREE_CODE (t) != FUNCTION_DECL
       && !DECL_FUNCTION_TEMPLATE_P (t))
@@ -255,15 +308,14 @@ is_member_or_friend_template (t, allow_friend)
        certainly not a member template.  */
     return 0;
 
-  if (((DECL_FUNCTION_MEMBER_P (t) 
-       || (allow_friend && DECL_FRIEND_P (t)))
+  /* A local class can't have member templates.  */
+  if (hack_decl_function_context (t))
+    return 0;
+
+  if ((DECL_FUNCTION_MEMBER_P (t) 
        && !DECL_TEMPLATE_SPECIALIZATION (t))
       || (TREE_CODE (t) == TEMPLATE_DECL 
-         && (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))
-             || (allow_friend
-                 && DECL_FUNCTION_TEMPLATE_P (t) 
-                 && DECL_FRIEND_P (DECL_TEMPLATE_RESULT (t))
-                 && DECL_CLASS_CONTEXT (t)))))
+         && DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t))))
     {
       tree tmpl;
 
@@ -275,27 +327,18 @@ is_member_or_friend_template (t, allow_friend)
       else
        tmpl = NULL_TREE;
 
-      if (tmpl && 
+      if (tmpl
          /* If there are more levels of template parameters than
             there are template classes surrounding the declaration,
             then we have a member template.  */
-         list_length (DECL_TEMPLATE_PARMS (tmpl)) > 
-         template_class_depth (DECL_CLASS_CONTEXT (t)))
+         && (list_length (DECL_TEMPLATE_PARMS (tmpl)) > 
+             template_class_depth (DECL_CLASS_CONTEXT (t))))
        return 1;
     }
 
   return 0;
 }
 
-/* Returns non-zero iff T is a member template.  */
-
-int
-is_member_template (t)
-     tree t;
-{
-  return is_member_or_friend_template (t, 0);
-}
-
 /* Return a new template argument vector which contains all of ARGS,
    but has as its innermost set of arguments the EXTRA_ARGS.  */
 
@@ -1092,6 +1135,10 @@ reduce_template_parm_level (index, type, levels)
                                     TEMPLATE_PARM_ORIG_LEVEL (index),
                                     decl, type);
       TEMPLATE_PARM_DESCENDANTS (index) = t;
+
+      /* Template template parameters need this.  */
+      DECL_TEMPLATE_PARMS (decl)
+       = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
     }
 
   return TEMPLATE_PARM_DESCENDANTS (index);