Commit 00d3396f by Jason Merrill

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
parent 1afc3550
...@@ -4,6 +4,31 @@ Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com) ...@@ -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 * init.c (build_vec_delete_1): Delete build_block and
add_block_current_level calls. 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> Mon Nov 10 20:08:38 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Tweak conditions for pedwarn in * decl.c (grokdeclarator): Tweak conditions for pedwarn in
......
...@@ -5474,6 +5474,8 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -5474,6 +5474,8 @@ build_new_method_call (instance, name, args, basetype_path, flags)
{ {
explicit_targs = TREE_OPERAND (name, 1); explicit_targs = TREE_OPERAND (name, 1);
name = TREE_OPERAND (name, 0); name = TREE_OPERAND (name, 0);
if (TREE_CODE (name) == TEMPLATE_DECL)
name = DECL_NAME (name);
template_only = 1; template_only = 1;
} }
...@@ -5526,11 +5528,14 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -5526,11 +5528,14 @@ build_new_method_call (instance, name, args, basetype_path, flags)
{ {
instance_ptr = build_this (instance); instance_ptr = build_this (instance);
if (! template_only)
{
/* XXX this should be handled before we get here. */ /* XXX this should be handled before we get here. */
fns = build_field_call (basetype_path, instance_ptr, name, args); fns = build_field_call (basetype_path, instance_ptr, name, args);
if (fns) if (fns)
return fns; return fns;
} }
}
else else
{ {
instance_ptr = build_int_2 (0, 0); instance_ptr = build_int_2 (0, 0);
......
...@@ -3406,10 +3406,9 @@ build_expr_from_tree (t) ...@@ -3406,10 +3406,9 @@ build_expr_from_tree (t)
return do_identifier (TREE_OPERAND (t, 0), 0); return do_identifier (TREE_OPERAND (t, 0), 0);
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
return lookup_template_function (build_expr_from_tree return (lookup_template_function
(TREE_OPERAND (t, 0)), (build_expr_from_tree (TREE_OPERAND (t, 0)),
build_expr_from_tree build_expr_from_tree (TREE_OPERAND (t, 1))));
(TREE_OPERAND (t, 1)));
case INDIRECT_REF: case INDIRECT_REF:
return build_x_indirect_ref return build_x_indirect_ref
...@@ -3568,7 +3567,8 @@ build_expr_from_tree (t) ...@@ -3568,7 +3567,8 @@ build_expr_from_tree (t)
else else
{ {
tree name = TREE_OPERAND (t, 0); 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); name = build_expr_from_tree (name);
return build_x_function_call return build_x_function_call
(name, build_expr_from_tree (TREE_OPERAND (t, 1)), (name, build_expr_from_tree (TREE_OPERAND (t, 1)),
......
...@@ -1157,7 +1157,13 @@ comp_template_args (oldargs, newargs) ...@@ -1157,7 +1157,13 @@ comp_template_args (oldargs, newargs)
continue; continue;
if (TREE_CODE (nt) != TREE_CODE (ot)) if (TREE_CODE (nt) != TREE_CODE (ot))
return 0; 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)) if (comptypes (ot, nt, 1))
continue; continue;
...@@ -2025,6 +2031,39 @@ lookup_nested_type_by_name (ctype, name) ...@@ -2025,6 +2031,39 @@ lookup_nested_type_by_name (ctype, name)
return NULL_TREE; 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 tree
tsubst (t, args, nargs, in_decl) tsubst (t, args, nargs, in_decl)
tree t, args; tree t, args;
...@@ -2246,14 +2285,6 @@ tsubst (t, args, nargs, in_decl) ...@@ -2246,14 +2285,6 @@ tsubst (t, args, nargs, in_decl)
type = tsubst (type, 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? */ /* Do we already have this instantiation? */
if (DECL_TEMPLATE_INFO (t) != NULL_TREE) if (DECL_TEMPLATE_INFO (t) != NULL_TREE)
{ {
...@@ -2262,7 +2293,8 @@ tsubst (t, args, nargs, in_decl) ...@@ -2262,7 +2293,8 @@ tsubst (t, args, nargs, in_decl)
for (; decls; decls = TREE_CHAIN (decls)) for (; decls; decls = TREE_CHAIN (decls))
if (TREE_TYPE (TREE_VALUE (decls)) == type 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); return TREE_VALUE (decls);
} }
...@@ -2616,24 +2648,8 @@ tsubst (t, args, nargs, in_decl) ...@@ -2616,24 +2648,8 @@ tsubst (t, args, nargs, in_decl)
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
{ {
elts[i] = tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl); elts[i] = maybe_fold_nontype_arg
(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;
}
if (elts[i] != TREE_VEC_ELT (t, i)) if (elts[i] != TREE_VEC_ELT (t, i))
need_new = 1; need_new = 1;
...@@ -2847,6 +2863,10 @@ do_poplevel () ...@@ -2847,6 +2863,10 @@ do_poplevel ()
return t; return t;
} }
/* Like tsubst, but deals with expressions. This function just replaces
template parms; to finish processing the resultant expression, use
tsubst_expr. */
tree tree
tsubst_copy (t, args, nargs, in_decl) tsubst_copy (t, args, nargs, in_decl)
tree t, args; tree t, args;
...@@ -2966,7 +2986,7 @@ tsubst_copy (t, args, nargs, in_decl) ...@@ -2966,7 +2986,7 @@ tsubst_copy (t, args, nargs, in_decl)
{ {
tree fn = TREE_OPERAND (t, 0); tree fn = TREE_OPERAND (t, 0);
if (really_overloaded_fn (fn)) 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 else
fn = tsubst_copy (fn, args, nargs, in_decl); fn = tsubst_copy (fn, args, nargs, in_decl);
return build_nt return build_nt
...@@ -3028,10 +3048,14 @@ tsubst_copy (t, args, nargs, in_decl) ...@@ -3028,10 +3048,14 @@ tsubst_copy (t, args, nargs, in_decl)
case TEMPLATE_ID_EXPR: case TEMPLATE_ID_EXPR:
{ {
tree r = lookup_template_function /* Substituted template arguments */
(tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl), tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, nargs, in_decl);
tsubst_copy (TREE_OPERAND (t, 1), args, nargs, in_decl)); tree chain;
return r; 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: case TREE_LIST:
...@@ -3089,6 +3113,8 @@ tsubst_copy (t, args, nargs, in_decl) ...@@ -3089,6 +3113,8 @@ tsubst_copy (t, args, nargs, in_decl)
} }
} }
/* Like tsubst_copy, but also does semantic processing and RTL expansion. */
tree tree
tsubst_expr (t, args, nargs, in_decl) tsubst_expr (t, args, nargs, in_decl)
tree t, args; tree t, args;
......
...@@ -1307,6 +1307,7 @@ get_first_fn (from) ...@@ -1307,6 +1307,7 @@ get_first_fn (from)
tree 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)) || DECL_FUNCTION_TEMPLATE_P (from))
return from; return from;
......
...@@ -2281,6 +2281,7 @@ build_x_function_call (function, params, decl) ...@@ -2281,6 +2281,7 @@ build_x_function_call (function, params, decl)
tree function, params, decl; tree function, params, decl;
{ {
tree type; tree type;
tree template_id = NULL_TREE;
int is_method; int is_method;
if (function == error_mark_node) if (function == error_mark_node)
...@@ -2289,6 +2290,13 @@ build_x_function_call (function, params, decl) ...@@ -2289,6 +2290,13 @@ build_x_function_call (function, params, decl)
if (processing_template_decl) if (processing_template_decl)
return build_min_nt (CALL_EXPR, function, params, NULL_TREE); 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); type = TREE_TYPE (function);
if (TREE_CODE (type) == OFFSET_TYPE if (TREE_CODE (type) == OFFSET_TYPE
...@@ -2383,6 +2391,9 @@ build_x_function_call (function, params, decl) ...@@ -2383,6 +2391,9 @@ build_x_function_call (function, params, decl)
decl = build_indirect_ref (decl, NULL_PTR); 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, return build_method_call (decl, function, params,
NULL_TREE, LOOKUP_NORMAL); NULL_TREE, LOOKUP_NORMAL);
} }
...@@ -2411,7 +2422,12 @@ build_x_function_call (function, params, decl) ...@@ -2411,7 +2422,12 @@ build_x_function_call (function, params, decl)
tree val = TREE_VALUE (function); tree val = TREE_VALUE (function);
if (flag_ansi_overloading) if (flag_ansi_overloading)
{
/* Put back explicit template arguments, if any. */
if (template_id)
function = template_id;
return build_new_function_call (function, params, NULL_TREE); return build_new_function_call (function, params, NULL_TREE);
}
if (TREE_CODE (val) == TEMPLATE_DECL) if (TREE_CODE (val) == TEMPLATE_DECL)
return build_overload_call_real return build_overload_call_real
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment