]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
call.c (build_new_method_call): Handle getting a TEMPLATE_ID_EXPR around a TEMPLATE_DECL.
authorJason Merrill <jason@gcc.gnu.org>
Tue, 18 Nov 1997 06:54:29 +0000 (01:54 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 18 Nov 1997 06:54:29 +0000 (01:54 -0500)
* call.c (build_new_method_call): Handle getting a
  TEMPLATE_ID_EXPR around a TEMPLATE_DECL.  Don't look for a field
  if we got template parms.
* typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR,
  not just the args.
* decl2.c (build_expr_from_tree): Tweak last change.
* pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE.
(maybe_fold_nontype_arg): Split out from tsubst_copy.
* tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR.

Mon Nov 10 20:08:38 1997  Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>

* pt.c (tsubst_copy): Handle explicit template arguments in
function calls.
* typeck.c (build_x_function_call): Likewise.
* decl2.c (build_expr_from_tree): Lookup function name if it
hasn't been done.

* pt.c (tsubst): Instantiate template functions properly when
template parameter does not appear in function arguments and return
type.
(comp_template_args): Handle member templates required by tsubst.

Mon Nov 10 20:08:29 1997  Bruno Haible  <bruno@linuix.mathematik.uni-karlsruhe.de>

* pt.c (coerce_template_parms): Tweak error message.

From-SVN: r16556

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck.c

index 63a343589b95f28003d41bf9281877f6b72a7a58..403f71f6e0c2da1d71996cf02a166e9a64a245fa 100644 (file)
@@ -61,6 +61,35 @@ Tue Nov 11 02:53:44 1997  Jason Merrill  <jason@lasher.cygnus.com>
 
        * except.c (do_pop_exception): Return a value.
 
+Mon Nov 10 20:25:31 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * call.c (build_new_method_call): Handle getting a
+       TEMPLATE_ID_EXPR around a TEMPLATE_DECL.  Don't look for a field
+       if we got template parms.
+       * typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR,
+       not just the args.
+       * decl2.c (build_expr_from_tree): Tweak last change.
+       * pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE.
+       (maybe_fold_nontype_arg): Split out from tsubst_copy.
+       * tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR.
+
+Mon Nov 10 20:08:38 1997  Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+       * pt.c (tsubst_copy): Handle explicit template arguments in 
+       function calls.
+       * typeck.c (build_x_function_call): Likewise.
+       * decl2.c (build_expr_from_tree): Lookup function name if it 
+       hasn't been done.
+
+       * pt.c (tsubst): Instantiate template functions properly when 
+       template parameter does not appear in function arguments and return 
+       type.
+       (comp_template_args): Handle member templates required by tsubst.
+
+Mon Nov 10 20:08:29 1997  Bruno Haible  <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+       * pt.c (coerce_template_parms): Tweak error message.
+
 Mon Nov 10 03:04:20 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        Complete nested exception support.
index a686dc2fd1895dd51621c94bec76cb4f2985d0f3..d4ecb62cd85736cce8c4d55fd4e0972380b29d4f 100644 (file)
@@ -5613,6 +5613,8 @@ build_new_method_call (instance, name, args, basetype_path, flags)
     {
       explicit_targs = TREE_OPERAND (name, 1);
       name = TREE_OPERAND (name, 0);
+      if (TREE_CODE (name) == TEMPLATE_DECL)
+       name = DECL_NAME (name);
       template_only = 1;
     }
 
@@ -5665,10 +5667,13 @@ build_new_method_call (instance, name, args, basetype_path, flags)
     {
       instance_ptr = build_this (instance);
 
-      /* XXX this should be handled before we get here.  */
-      fns = build_field_call (basetype_path, instance_ptr, name, args);
-      if (fns)
-       return fns;
+      if (! template_only)
+       {
+         /* XXX this should be handled before we get here.  */
+         fns = build_field_call (basetype_path, instance_ptr, name, args);
+         if (fns)
+           return fns;
+       }
     }
   else
     {
index fbe5c80bf097c86f2f52e15774b2fa53fe32afe0..9c2d8074e15692cd94f38bf4b0ef25018a6481f2 100644 (file)
@@ -3414,10 +3414,9 @@ build_expr_from_tree (t)
        return do_identifier (TREE_OPERAND (t, 0), 0);
 
     case TEMPLATE_ID_EXPR:
-      return lookup_template_function (build_expr_from_tree
-                                      (TREE_OPERAND (t, 0)),
-                                      build_expr_from_tree
-                                      (TREE_OPERAND (t, 1)));
+      return (lookup_template_function
+             (build_expr_from_tree (TREE_OPERAND (t, 0)),
+              build_expr_from_tree (TREE_OPERAND (t, 1))));
 
     case INDIRECT_REF:
       return build_x_indirect_ref
@@ -3576,7 +3575,8 @@ build_expr_from_tree (t)
       else
        {
          tree name = TREE_OPERAND (t, 0);
-         if (! really_overloaded_fn (name))
+         if (TREE_CODE (name) == TEMPLATE_ID_EXPR
+             || ! really_overloaded_fn (name))
            name = build_expr_from_tree (name);
          return build_x_function_call
            (name, build_expr_from_tree (TREE_OPERAND (t, 1)),
index f5a1291b3471f333bb44eee7bf852a754ee1e011..dffe1bf2da9c002de0f7d46c2ce88d542c8e5699 100644 (file)
@@ -1085,7 +1085,7 @@ coerce_template_parms (parms, arglist, in_decl)
            }
          else if (!TREE_CONSTANT (val))
            {
-             cp_error ("non-const `%E' cannot be used as template argument",
+             cp_error ("non-constant `%E' cannot be used as template argument",
                        arg);
              val = error_mark_node;
            }
@@ -1157,7 +1157,13 @@ comp_template_args (oldargs, newargs)
        continue;
       if (TREE_CODE (nt) != TREE_CODE (ot))
        return 0;
-      if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't')
+      if (TREE_CODE (nt) == TREE_VEC)
+        {
+          /* For member templates */
+         if (comp_template_args (nt, ot))
+           continue;
+        }
+      else if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't')
        {
          if (comptypes (ot, nt, 1))
            continue;
@@ -2025,6 +2031,39 @@ lookup_nested_type_by_name (ctype, name)
   return NULL_TREE;
 }
 
+/* If arg is a non-type template parameter that does not depend on template
+   arguments, fold it like we weren't in the body of a template.  */
+
+static tree
+maybe_fold_nontype_arg (arg)
+     tree arg;
+{
+  if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't'
+      && !uses_template_parms (arg))
+    {
+      /* 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 build_expr_from_tree() into building an actual
+        tree.  */
+
+      int saved_processing_template_decl = processing_template_decl; 
+      processing_template_decl = 0;
+      arg = fold (build_expr_from_tree (arg));
+      processing_template_decl = saved_processing_template_decl; 
+    }
+  return arg;
+}
+
+/* Take the tree structure T and replace template parameters used therein
+   with the argument vector ARGS.  NARGS is the number of args; should
+   be removed.  IN_DECL is an associated decl for diagnostics.
+
+   tsubst is used for dealing with types, decls and the like; for
+   expressions, use tsubst_expr or tsubst_copy.  */
+
 tree
 tsubst (t, args, nargs, in_decl)
      tree t, args;
@@ -2246,14 +2285,6 @@ tsubst (t, args, nargs, in_decl)
            type = tsubst (type, args, nargs, in_decl);
          }
 
-       if (type == TREE_TYPE (t)
-           && (! member || ctx == DECL_CLASS_CONTEXT (t)))
-         {
-           t = copy_node (t);
-           copy_lang_decl (t);
-           return t;
-         }
-
        /* Do we already have this instantiation?  */
        if (DECL_TEMPLATE_INFO (t) != NULL_TREE)
          {
@@ -2262,7 +2293,8 @@ tsubst (t, args, nargs, in_decl)
 
            for (; decls; decls = TREE_CHAIN (decls))
              if (TREE_TYPE (TREE_VALUE (decls)) == type
-                 && DECL_CLASS_CONTEXT (TREE_VALUE (decls)) == ctx)
+                 && DECL_CLASS_CONTEXT (TREE_VALUE (decls)) == ctx
+                 && comp_template_args (TREE_PURPOSE (decls), args))
                return TREE_VALUE (decls);
          }
 
@@ -2616,24 +2648,8 @@ tsubst (t, args, nargs, in_decl)
 
        for (i = 0; i < len; i++)
          {
-           elts[i] = tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl);
-
-           if (TREE_CODE_CLASS (TREE_CODE (elts[i])) != 't'
-               && !uses_template_parms (elts[i]))
-             {
-               /* 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 build_expr_from_tree() into building an actual
-                  tree.  */
-
-               int saved_processing_template_decl = processing_template_decl; 
-               processing_template_decl = 0;
-               elts[i] = fold (build_expr_from_tree (elts[i]));
-               processing_template_decl = saved_processing_template_decl; 
-             }
+           elts[i] = maybe_fold_nontype_arg
+             (tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl));
 
            if (elts[i] != TREE_VEC_ELT (t, i))
              need_new = 1;
@@ -2847,6 +2863,10 @@ do_poplevel ()
   return t;
 }
 
+/* Like tsubst, but deals with expressions.  This function just replaces
+   template parms; to finish processing the resultant expression, use
+   tsubst_expr.  */
+
 tree
 tsubst_copy (t, args, nargs, in_decl)
      tree t, args;
@@ -2966,7 +2986,7 @@ tsubst_copy (t, args, nargs, in_decl)
       {
        tree fn = TREE_OPERAND (t, 0);
        if (really_overloaded_fn (fn))
-         fn = tsubst_copy (TREE_VALUE (fn), args, nargs, in_decl);
+         fn = tsubst_copy (get_first_fn (fn), args, nargs, in_decl);
        else
          fn = tsubst_copy (fn, args, nargs, in_decl);
        return build_nt
@@ -3028,10 +3048,14 @@ tsubst_copy (t, args, nargs, in_decl)
 
     case TEMPLATE_ID_EXPR:
       {
-       tree r = lookup_template_function
-         (tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl),
-          tsubst_copy (TREE_OPERAND (t, 1), args, nargs, in_decl));
-       return r;
+        /* Substituted template arguments */
+       tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, nargs, in_decl);
+       tree chain;
+       for (chain = targs; chain; chain = TREE_CHAIN (chain))
+         TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
+
+       return lookup_template_function
+         (tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl), targs);
       }
 
     case TREE_LIST:
@@ -3089,6 +3113,8 @@ tsubst_copy (t, args, nargs, in_decl)
     }
 }
 
+/* Like tsubst_copy, but also does semantic processing and RTL expansion.  */
+
 tree
 tsubst_expr (t, args, nargs, in_decl)
      tree t, args;
index 9d2589fec6dce7fa4f08974264c32e807162f82d..e94fd554057d63c49623014824763493d7e88559 100644 (file)
@@ -1306,7 +1306,8 @@ tree
 get_first_fn (from)
      tree from;
 {
-  if (TREE_CODE (from) == FUNCTION_DECL 
+  if (TREE_CODE (from) == FUNCTION_DECL
+      || TREE_CODE (from) == TEMPLATE_ID_EXPR
       || DECL_FUNCTION_TEMPLATE_P (from))
     return from;
 
index c6084eb16fa88a6336da4f6147eb91b543fad7f6..f1698503119b73610dd664ac493f0ef38c52132e 100644 (file)
@@ -2266,6 +2266,7 @@ build_x_function_call (function, params, decl)
      tree function, params, decl;
 {
   tree type;
+  tree template_id = NULL_TREE;
   int is_method;
 
   if (function == error_mark_node)
@@ -2274,6 +2275,13 @@ build_x_function_call (function, params, decl)
   if (processing_template_decl)
     return build_min_nt (CALL_EXPR, function, params, NULL_TREE);
 
+  /* Save explicit template arguments if found */
+  if (TREE_CODE (function) == TEMPLATE_ID_EXPR)
+    {
+      template_id = function;
+      function = TREE_OPERAND (function, 0);
+    }
+
   type = TREE_TYPE (function);
 
   if (TREE_CODE (type) == OFFSET_TYPE
@@ -2368,6 +2376,9 @@ build_x_function_call (function, params, decl)
          decl = build_indirect_ref (decl, NULL_PTR);
        }
 
+      /* Put back explicit template arguments, if any.  */
+      if (template_id)
+        function = template_id;
       return build_method_call (decl, function, params,
                                NULL_TREE, LOOKUP_NORMAL);
     }
@@ -2396,7 +2407,12 @@ build_x_function_call (function, params, decl)
          tree val = TREE_VALUE (function);
 
          if (flag_ansi_overloading)
-           return build_new_function_call (function, params);
+           {
+             /* Put back explicit template arguments, if any.  */
+             if (template_id)
+               function = template_id;
+             return build_new_function_call (function, params);
+           }
 
          if (TREE_CODE (val) == TEMPLATE_DECL)
            return build_overload_call_real