aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>1997-11-11 02:09:58 -0500
committerJason Merrill <jason@gcc.gnu.org>1997-11-11 02:09:58 -0500
commit00d3396fdbabe68ad2b7c64ac28c5608628c75ad (patch)
treebdf1e6e2cf3489fb92d44c2f7e6d2004a4513b78
parent1afc355025f984fb0b26d68a7337f987890e6042 (diff)
downloadgcc-00d3396fdbabe68ad2b7c64ac28c5608628c75ad.zip
gcc-00d3396fdbabe68ad2b7c64ac28c5608628c75ad.tar.gz
gcc-00d3396fdbabe68ad2b7c64ac28c5608628c75ad.tar.bz2
call.c (build_new_method_call): Handle getting a TEMPLATE_ID_EXPR around a TEMPLATE_DECL.
* 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. From-SVN: r16427
-rw-r--r--gcc/cp/ChangeLog25
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/cp/decl2.c10
-rw-r--r--gcc/cp/pt.c92
-rw-r--r--gcc/cp/tree.c3
-rw-r--r--gcc/cp/typeck.c18
6 files changed, 117 insertions, 44 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bd15ca1..b267d28 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -4,6 +4,31 @@ Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com)
* init.c (build_vec_delete_1): Delete build_block and
add_block_current_level calls.
+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:38 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Tweak conditions for pedwarn in
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index eaa39c6..da1d50c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5474,6 +5474,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;
}
@@ -5526,10 +5528,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
{
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index b51e660..5d94797 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3406,10 +3406,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
@@ -3568,7 +3567,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)),
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dff871d..8e05af3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9d2589f..e94fd55 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4b774d2..54f8c83 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2281,6 +2281,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)
@@ -2289,6 +2290,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
@@ -2383,6 +2391,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);
}
@@ -2411,7 +2422,12 @@ build_x_function_call (function, params, decl)
tree val = TREE_VALUE (function);
if (flag_ansi_overloading)
- return build_new_function_call (function, params, NULL_TREE);
+ {
+ /* Put back explicit template arguments, if any. */
+ if (template_id)
+ function = template_id;
+ return build_new_function_call (function, params, NULL_TREE);
+ }
if (TREE_CODE (val) == TEMPLATE_DECL)
return build_overload_call_real