mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 02:20:27 +08:00
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
This commit is contained in:
parent
1afc355025
commit
00d3396fdb
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)),
|
||||
|
92
gcc/cp/pt.c
92
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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user