pt.c (begin_member_template_processing): Take a function as argument, not a set of...
authorMark Mitchell <mmitchell@usa.net>
Mon, 8 Sep 1997 09:28:51 +0000 (09:28 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 8 Sep 1997 09:28:51 +0000 (05:28 -0400)
Mon Sep  8 01:21:43 1997  Mark Mitchell  <mmitchell@usa.net>

* pt.c (begin_member_template_processing): Take a function as
argument, not a set of template arguments.  Use the template
parameters, rather than the arguments.  Handle non-type parameters
correctly.  Push a binding level for the parameters so that multiple
member templates using the same parameter names can be declared.
(end_member_template_processing): Pop the binding level.
(push_template_decl): Mark member templates as static when
appropriate.

* lex.c (do_pending_inlines): Pass the function, not its template
arguments, to begin_member_template_processing.
(process_next_inline): Likewise.
(do_pending_defargs): Likewise.

* error.c (dump_expr): Obtain the correct declaration for a
TEMPLATE_CONST_PARM.

* call.c (add_template_conv_candidate): New function.
(build_object_call): Handle member templates, as done in the other
build_ functions.

From-SVN: r15155

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/error.c
gcc/cp/lex.c
gcc/cp/pt.c

index f446a4f59475a9bfec382f80e10a40fc780431bc..213ac3980d34fd8694348b6f76b39642b595cd58 100644 (file)
@@ -1,3 +1,26 @@
+Mon Sep  8 01:21:43 1997  Mark Mitchell  <mmitchell@usa.net>
+
+       * pt.c (begin_member_template_processing): Take a function as
+       argument, not a set of template arguments.  Use the template
+       parameters, rather than the arguments.  Handle non-type parameters
+       correctly.  Push a binding level for the parameters so that multiple
+       member templates using the same parameter names can be declared.
+       (end_member_template_processing): Pop the binding level.
+       (push_template_decl): Mark member templates as static when
+       appropriate. 
+
+       * lex.c (do_pending_inlines): Pass the function, not its template
+       arguments, to begin_member_template_processing.
+       (process_next_inline): Likewise.
+       (do_pending_defargs): Likewise.
+
+       * error.c (dump_expr): Obtain the correct declaration for a
+       TEMPLATE_CONST_PARM. 
+
+       * call.c (add_template_conv_candidate): New function.
+       (build_object_call): Handle member templates, as done in the other
+       build_ functions.
+       
 Sat Sep  6 10:20:27 1997  Mark Mitchell  <mmitchell@usa.net>
 
        * decl.c (replace_defag): Undo previous change.
index 06316143a2ba35acb5138fc137a6de6233cdc334..5bf18c9b69cd3131aafe9e94c919429d7120bc9a 100644 (file)
@@ -78,6 +78,8 @@ static struct z_candidate * splice_viable PROTO((struct z_candidate *));
 static int any_viable PROTO((struct z_candidate *));
 static struct z_candidate * add_template_candidate
        PROTO((struct z_candidate *, tree, tree, tree, int));
+static struct z_candidate * add_template_conv_candidate 
+        PROTO((struct z_candidate *, tree, tree, tree, tree));
 static struct z_candidate * add_builtin_candidates
        PROTO((struct z_candidate *, enum tree_code, enum tree_code,
               tree, tree *, int));
@@ -4170,6 +4172,33 @@ add_template_candidate (candidates, tmpl, arglist, return_type, flags)
   return cand;
 }
 
+
+static struct z_candidate *
+add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
+     struct z_candidate *candidates;
+     tree tmpl, obj, arglist, return_type;
+{
+  int ntparms = DECL_NTPARMS (tmpl);
+  tree targs = make_tree_vec (ntparms);
+  struct z_candidate *cand;
+  int i;
+  tree fn;
+
+  i = fn_type_unification (tmpl, targs, arglist, return_type, 0);
+
+  if (i != 0)
+    return candidates;
+
+  fn = instantiate_template (tmpl, targs);
+  if (fn == error_mark_node)
+    return candidates;
+
+  cand = add_conv_candidate (candidates, fn, obj, arglist);
+  cand->template = DECL_TEMPLATE_INFO (fn);
+  return cand;
+}
+
+
 static int
 any_viable (cands)
      struct z_candidate *cands;
@@ -4508,6 +4537,7 @@ build_object_call (obj, args)
   struct z_candidate *candidates = 0, *cand;
   tree fns, convs, mem_args;
   tree type = TREE_TYPE (obj);
+  tree templates = NULL_TREE;
 
   fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
 
@@ -4523,9 +4553,19 @@ build_object_call (obj, args)
 
       for (; fn; fn = DECL_CHAIN (fn))
        {
-         candidates = add_function_candidate
-           (candidates, fn, mem_args, LOOKUP_NORMAL);
-         candidates->basetype_path = TREE_PURPOSE (fns);
+         if (TREE_CODE (fn) == TEMPLATE_DECL)
+           {
+             templates = decl_tree_cons (NULL_TREE, fn, templates);
+             candidates = add_template_candidate (candidates, fn,
+                                                  mem_args, NULL_TREE, 
+                                                  LOOKUP_NORMAL);
+           }
+         else
+           candidates = add_function_candidate
+             (candidates, fn, mem_args, LOOKUP_NORMAL);
+
+         if (candidates)
+           candidates->basetype_path = TREE_PURPOSE (fns);
        }
     }
 
@@ -4540,8 +4580,20 @@ build_object_call (obj, args)
          && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
        for (; fn; fn = DECL_CHAIN (fn))
          {
-           candidates = add_conv_candidate (candidates, fn, obj, args);
-           candidates->basetype_path = TREE_PURPOSE (convs);
+           if (TREE_CODE (fn) == TEMPLATE_DECL) 
+             {
+               templates = decl_tree_cons (NULL_TREE, fn, templates);
+               candidates = add_template_conv_candidate (candidates,
+                                                         fn,
+                                                         obj,
+                                                         args,
+                                                         totype);
+             }
+           else
+             candidates = add_conv_candidate (candidates, fn, obj, args);
+
+           if (candidates)
+             candidates->basetype_path = TREE_PURPOSE (convs);
          }
     }
 
index ce2bc3b88dc59d72395c0fb327b1d167acf2074f..847bfa22495b6095c4c72cc7c3208cadadeaa1c9 100644 (file)
@@ -1366,13 +1366,15 @@ dump_expr (t, nop)
       if (current_template_parms)
        {
          int i;
-         tree parms;
+         int l = list_length (current_template_parms);
+         tree parms = current_template_parms;
          tree r;
 
-         for (parms = current_template_parms;
-              TREE_CHAIN (parms);
-              parms = TREE_CHAIN (parms))
-           ;
+         for (i = 0; i < l - TEMPLATE_CONST_LEVEL (t); ++i)
+           {
+             parms = TREE_CHAIN (parms);
+             my_friendly_assert (parms != NULL_TREE, 0);
+           }
 
          r = TREE_VEC_ELT (TREE_VALUE (parms),
                            TEMPLATE_CONST_IDX (t));
index 471033faf9e8eb8641611d53187582c3e2fbe4c4..8bd9c57624aa3caa06dc0ec815ba355bdb6e6089 100644 (file)
@@ -1191,7 +1191,7 @@ do_pending_inlines ()
   if (context)
     push_cp_function_context (context);
   if (is_member_template (t->fndecl))
-    begin_member_template_processing (DECL_TI_ARGS (t->fndecl));
+    begin_member_template_processing (t->fndecl);
   if (t->len > 0)
     {
       feed_input (t->buf, t->len);
@@ -1254,7 +1254,7 @@ process_next_inline (t)
       if (context)
        push_cp_function_context (context);
       if (is_member_template (i->fndecl))
-       begin_member_template_processing (DECL_TI_ARGS (i->fndecl));
+       begin_member_template_processing (i->fndecl);
       feed_input (i->buf, i->len);
       lineno = i->lineno;
       input_filename = i->filename;
@@ -1874,7 +1874,7 @@ do_pending_defargs ()
          push_nested_class (TREE_PURPOSE (defarg_fns), 1);
          pushlevel (0);
          if (is_member_template (defarg_fn))
-           begin_member_template_processing (DECL_TI_ARGS (defarg_fn));
+           begin_member_template_processing (defarg_fn);
 
          if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
            {
index a0154e173eff0046ea562f91709b3ea49e4dd20b..0c24ec4eeb945a4955d5d1f0b98cde0e2d072dc5 100644 (file)
@@ -82,29 +82,40 @@ static tree add_to_template_args PROTO((tree, tree));
 /* Restore the template parameter context. */
 
 void 
-begin_member_template_processing (parms)
-     tree parms;
+begin_member_template_processing (decl)
+     tree decl;
 {
+  tree parms;
   int i;
 
+  parms = DECL_INNERMOST_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl));
+
   ++processing_template_decl;
   current_template_parms 
     = tree_cons (build_int_2 (0, processing_template_decl),
                 parms, current_template_parms);
+  pushlevel (0);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) 
     {
-      tree parm = TREE_VEC_ELT (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 TEMPLATE_TYPE_PARM:
-         pushdecl (TYPE_NAME (parm));
-         break;
-
-       case TEMPLATE_CONST_PARM:
+       case TYPE_DECL:
          pushdecl (parm);
          break;
-         
+
+       case PARM_DECL:
+         {
+           /* Make a CONST_DECL as is done in process_template_parm. */
+           tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
+                                   TREE_TYPE (parm));
+           DECL_INITIAL (decl) = DECL_INITIAL (parm);
+           pushdecl (decl);
+         }
+       break;
+
        default:
          my_friendly_abort (0);
        }
@@ -121,6 +132,7 @@ end_member_template_processing ()
 
   --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.  Works if T
@@ -449,7 +461,11 @@ push_template_decl (decl)
       DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
       DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
       if (DECL_LANG_SPECIFIC (decl))
-       DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl);
+       {
+         DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl);
+         DECL_STATIC_FUNCTION_P (tmpl) = 
+           DECL_STATIC_FUNCTION_P (decl);
+       }
     }
   else
     {